panhui 5 жил өмнө
parent
commit
9a7879f785
52 өөрчлөгдсөн 4027 нэмэгдсэн , 243 устгасан
  1. 56 33
      package-lock.json
  2. 58 0
      project.config.json
  3. 17 0
      src/App.vue
  4. 1 0
      src/components/AuthPhone.vue
  5. 138 16
      src/components/Banner.vue
  6. 32 0
      src/components/FixedButton.vue
  7. 109 0
      src/components/News/Grid.vue
  8. 59 0
      src/components/News/Row.vue
  9. 5 2
      src/components/SortList.vue
  10. 108 0
      src/components/bar/CustomBar.vue
  11. 71 17
      src/components/bar/FilterSortBar.vue
  12. 12 9
      src/components/bar/SearchBar.vue
  13. 32 9
      src/components/bar/SearchBarWithValue.vue
  14. 4 1
      src/components/filter/Application.vue
  15. 62 16
      src/components/filter/Country.vue
  16. 228 0
      src/components/filter/EnterpriseType.vue
  17. 77 30
      src/components/filter/ProductCategory.vue
  18. 65 23
      src/components/filter/ProductTags.vue
  19. 128 0
      src/components/imt/Bottom.vue
  20. 102 0
      src/components/imt/Core.vue
  21. 55 0
      src/components/imt/Title.vue
  22. 86 0
      src/components/product/GridNormal.vue
  23. 6 5
      src/components/vendor/Grid.vue
  24. 12 4
      src/main.js
  25. 12 0
      src/mixins/commont.js
  26. 10 0
      src/mixins/form.js
  27. 77 26
      src/mixins/searchList.js
  28. 0 0
      src/native/vant/tabs/index.wxss
  29. 1 1
      src/pages/Authorized.vue
  30. 86 11
      src/pages/Brand.vue
  31. 43 14
      src/pages/Classify.vue
  32. 88 6
      src/pages/FilterPage.vue
  33. 4 0
      src/pages/Home.vue
  34. 13 14
      src/pages/My.vue
  35. 149 0
      src/pages/News.vue
  36. 215 0
      src/pages/Product.vue
  37. 179 0
      src/pages/ProductList.vue
  38. 84 0
      src/pages/imt/Advantage.vue
  39. 82 0
      src/pages/imt/Connect.vue
  40. 281 0
      src/pages/imt/Index.vue
  41. 55 0
      src/pages/imt/Service.vue
  42. 184 0
      src/pages/imt/ServiceDetail.vue
  43. 176 0
      src/pages/news/Detail.vue
  44. 149 0
      src/pages/news/News.vue
  45. 342 0
      src/pages/news/Submit.vue
  46. BIN
      src/static/imgs/imt_gaikuang_icon_01.png
  47. BIN
      src/static/imgs/imt_gaikuang_icon_02.png
  48. BIN
      src/static/imgs/imt_gaikuang_icon_03.png
  49. BIN
      src/static/imgs/imt_topbanner_icon_3d.png
  50. 44 5
      src/store/index.js
  51. 61 1
      src/utils/appState.js
  52. 169 0
      src/utils/imtPageInfo.js

+ 56 - 33
package-lock.json

@@ -1118,7 +1118,7 @@
       "dependencies": {
         "ajv": {
           "version": "5.5.2",
-          "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-5.5.2.tgz?cache=0&sync_timestamp=1605459239143&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-5.5.2.tgz",
+          "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-5.5.2.tgz?cache=0&sync_timestamp=1605562344312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-5.5.2.tgz",
           "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
           "dev": true,
           "optional": true,
@@ -1760,9 +1760,9 @@
       "dev": true
     },
     "@types/node": {
-      "version": "14.14.7",
-      "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.7.tgz?cache=0&sync_timestamp=1604951079891&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.14.7.tgz",
-      "integrity": "sha1-jqHo+OriQwz0QFZLmMbfzh7FlF0=",
+      "version": "14.14.8",
+      "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.8.tgz?cache=0&sync_timestamp=1605656755365&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.14.8.tgz",
+      "integrity": "sha1-ISe9gZSalci30yQPMlQ1LXJWOuw=",
       "dev": true
     },
     "@types/normalize-package-data": {
@@ -2274,13 +2274,36 @@
       "dev": true
     },
     "array.prototype.flat": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npm.taobao.org/array.prototype.flat/download/array.prototype.flat-1.2.3.tgz",
-      "integrity": "sha1-DegrQmsDGNv9uUAInjiwQ9N/bHs=",
+      "version": "1.2.4",
+      "resolved": "https://registry.npm.taobao.org/array.prototype.flat/download/array.prototype.flat-1.2.4.tgz?cache=0&sync_timestamp=1605688437987&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.4.tgz",
+      "integrity": "sha1-bvY4tDMSvUAbTGGZ/ex+LcnpoSM=",
       "dev": true,
       "requires": {
+        "call-bind": "^1.0.0",
         "define-properties": "^1.1.3",
-        "es-abstract": "^1.17.0-next.1"
+        "es-abstract": "^1.18.0-next.1"
+      },
+      "dependencies": {
+        "es-abstract": {
+          "version": "1.18.0-next.1",
+          "resolved": "https://registry.npm.taobao.org/es-abstract/download/es-abstract-1.18.0-next.1.tgz?cache=0&sync_timestamp=1601503225168&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.18.0-next.1.tgz",
+          "integrity": "sha1-bjoKS9pxflAjqzuOkL7DYQjSLGg=",
+          "dev": true,
+          "requires": {
+            "es-to-primitive": "^1.2.1",
+            "function-bind": "^1.1.1",
+            "has": "^1.0.3",
+            "has-symbols": "^1.0.1",
+            "is-callable": "^1.2.2",
+            "is-negative-zero": "^2.0.0",
+            "is-regex": "^1.1.1",
+            "object-inspect": "^1.8.0",
+            "object-keys": "^1.1.1",
+            "object.assign": "^4.1.1",
+            "string.prototype.trimend": "^1.0.1",
+            "string.prototype.trimstart": "^1.0.1"
+          }
+        }
       }
     },
     "asn1": {
@@ -3380,9 +3403,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001158",
-      "resolved": "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30001158.tgz?cache=0&sync_timestamp=1605422072364&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001158.tgz",
-      "integrity": "sha1-/OhtMhNpYDwryFXuDpAaf0n4MQs=",
+      "version": "1.0.30001159",
+      "resolved": "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30001159.tgz?cache=0&sync_timestamp=1605683111499&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcaniuse-lite%2Fdownload%2Fcaniuse-lite-1.0.30001159.tgz",
+      "integrity": "sha1-vr3ij4k/qVlNrcqn1rjiqgKZ3yA=",
       "dev": true
     },
     "case-sensitive-paths-webpack-plugin": {
@@ -4410,7 +4433,7 @@
     },
     "css-tree": {
       "version": "1.0.0-alpha.37",
-      "resolved": "https://registry.npm.taobao.org/css-tree/download/css-tree-1.0.0-alpha.37.tgz?cache=0&sync_timestamp=1605129596306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.0.0-alpha.37.tgz",
+      "resolved": "https://registry.npm.taobao.org/css-tree/download/css-tree-1.0.0-alpha.37.tgz?cache=0&sync_timestamp=1605704552504&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.0.0-alpha.37.tgz",
       "integrity": "sha1-mL69YsTB2flg7DQM+fdSLjBwmiI=",
       "dev": true,
       "requires": {
@@ -4525,19 +4548,19 @@
       },
       "dependencies": {
         "css-tree": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npm.taobao.org/css-tree/download/css-tree-1.0.1.tgz?cache=0&sync_timestamp=1605129596306&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.0.1.tgz",
-          "integrity": "sha1-dyZnjf4qV5k6AY2dzlGb8XYOO20=",
+          "version": "1.1.1",
+          "resolved": "https://registry.npm.taobao.org/css-tree/download/css-tree-1.1.1.tgz?cache=0&sync_timestamp=1605704552504&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-tree%2Fdownload%2Fcss-tree-1.1.1.tgz",
+          "integrity": "sha1-MLjAFh2ftOniFB12JYm27C+uvS4=",
           "dev": true,
           "requires": {
-            "mdn-data": "2.0.12",
+            "mdn-data": "2.0.14",
             "source-map": "^0.6.1"
           }
         },
         "mdn-data": {
-          "version": "2.0.12",
-          "resolved": "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.12.tgz",
-          "integrity": "sha1-u7ZY0Is49XS7uI97g3A979zEaEQ=",
+          "version": "2.0.14",
+          "resolved": "https://registry.npm.taobao.org/mdn-data/download/mdn-data-2.0.14.tgz",
+          "integrity": "sha1-cRP8QoGRfWPOKbQ0RvcB5owlulA=",
           "dev": true
         },
         "source-map": {
@@ -4988,9 +5011,9 @@
       "dev": true
     },
     "electron-to-chromium": {
-      "version": "1.3.596",
-      "resolved": "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.596.tgz?cache=0&sync_timestamp=1605337427930&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.596.tgz",
-      "integrity": "sha1-x+2YUSx/823cv+2eVOY1UzXDUlc=",
+      "version": "1.3.599",
+      "resolved": "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.599.tgz?cache=0&sync_timestamp=1605724428025&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.599.tgz",
+      "integrity": "sha1-P7sARzPzwNz1mTTIZE3fgAuURDo=",
       "dev": true
     },
     "elliptic": {
@@ -5426,7 +5449,7 @@
     },
     "eslint-config-standard": {
       "version": "12.0.0",
-      "resolved": "https://registry.npm.taobao.org/eslint-config-standard/download/eslint-config-standard-12.0.0.tgz",
+      "resolved": "https://registry.npm.taobao.org/eslint-config-standard/download/eslint-config-standard-12.0.0.tgz?cache=0&sync_timestamp=1605662653337&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-standard%2Fdownload%2Feslint-config-standard-12.0.0.tgz",
       "integrity": "sha1-Y4tMZdsL1aQTGflruh8V3a0hB9k=",
       "dev": true
     },
@@ -8689,9 +8712,9 @@
       }
     },
     "node-releases": {
-      "version": "1.1.66",
-      "resolved": "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.66.tgz",
-      "integrity": "sha1-YJvQ3AaTgQFc2YIwC65Rq08bGBQ=",
+      "version": "1.1.67",
+      "resolved": "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.67.tgz?cache=0&sync_timestamp=1605581302570&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-releases%2Fdownload%2Fnode-releases-1.1.67.tgz",
+      "integrity": "sha1-KOv8zNC6pqrY6NTY/ky8Sa4jnBI=",
       "dev": true
     },
     "node-sass": {
@@ -9198,7 +9221,7 @@
     },
     "pako": {
       "version": "1.0.11",
-      "resolved": "https://registry.npm.taobao.org/pako/download/pako-1.0.11.tgz",
+      "resolved": "https://registry.npm.taobao.org/pako/download/pako-1.0.11.tgz?cache=0&sync_timestamp=1605741925189&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpako%2Fdownload%2Fpako-1.0.11.tgz",
       "integrity": "sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=",
       "dev": true
     },
@@ -11877,7 +11900,7 @@
       "dependencies": {
         "ajv": {
           "version": "5.5.2",
-          "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-5.5.2.tgz?cache=0&sync_timestamp=1605459239143&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-5.5.2.tgz",
+          "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-5.5.2.tgz?cache=0&sync_timestamp=1605562344312&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-5.5.2.tgz",
           "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
           "dev": true,
           "optional": true,
@@ -11890,7 +11913,7 @@
         },
         "ajv-keywords": {
           "version": "2.1.1",
-          "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-2.1.1.tgz?cache=0&sync_timestamp=1604565064716&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-2.1.1.tgz",
+          "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-2.1.1.tgz?cache=0&sync_timestamp=1605601441848&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-2.1.1.tgz",
           "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
           "dev": true,
           "optional": true
@@ -11930,7 +11953,7 @@
     },
     "terser": {
       "version": "4.8.0",
-      "resolved": "https://registry.npm.taobao.org/terser/download/terser-4.8.0.tgz?cache=0&sync_timestamp=1603374111112&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.8.0.tgz",
+      "resolved": "https://registry.npm.taobao.org/terser/download/terser-4.8.0.tgz?cache=0&sync_timestamp=1605534759179&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.8.0.tgz",
       "integrity": "sha1-YwVjQ9fHC7KfOvZlhlpG/gOg3xc=",
       "dev": true,
       "requires": {
@@ -12261,7 +12284,7 @@
     },
     "type-fest": {
       "version": "0.6.0",
-      "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.6.0.tgz?cache=0&sync_timestamp=1605191525194&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftype-fest%2Fdownload%2Ftype-fest-0.6.0.tgz",
+      "resolved": "https://registry.npm.taobao.org/type-fest/download/type-fest-0.6.0.tgz",
       "integrity": "sha1-jSojcNPfiG61yQraHFv2GIrPg4s=",
       "dev": true
     },
@@ -12667,7 +12690,7 @@
     },
     "vue-loader": {
       "version": "15.4.0",
-      "resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.4.0.tgz",
+      "resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.4.0.tgz?cache=0&sync_timestamp=1605670738269&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.4.0.tgz",
       "integrity": "sha1-jJD5Ts5hxrRwfoe0pYYX+X+qEls=",
       "dev": true,
       "requires": {
@@ -12848,7 +12871,7 @@
     },
     "webpack": {
       "version": "4.44.2",
-      "resolved": "https://registry.npm.taobao.org/webpack/download/webpack-4.44.2.tgz?cache=0&sync_timestamp=1604553110346&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.2.tgz",
+      "resolved": "https://registry.npm.taobao.org/webpack/download/webpack-4.44.2.tgz",
       "integrity": "sha1-a/4rCvBVyLLR6Q7SzZNj+EEma3I=",
       "dev": true,
       "requires": {

+ 58 - 0
project.config.json

@@ -96,6 +96,64 @@
                     "name": "筛选",
                     "pathName": "pages/FilterPage",
                     "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "全球产品",
+                    "pathName": "pages/Product",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "imt平台",
+                    "pathName": "pages/imt/Index",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "新闻咨询",
+                    "pathName": "pages/news/News",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "新闻咨询详情",
+                    "pathName": "pages/news/Detail",
+                    "scene": null,
+                    "query": "id=104"
+                },
+                {
+                    "id": -1,
+                    "name": "活动报名",
+                    "pathName": "pages/news/Submit",
+                    "scene": null,
+                    "query": "infoId=104&activityId=6806"
+                },
+                {
+                    "id": -1,
+                    "name": "imt平台3",
+                    "pathName": "pages/imt/Service",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "imt平台4",
+                    "pathName": "pages/imt/Connect",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "imt服务详情",
+                    "pathName": "pages/imt/ServiceDetail",
+                    "query": "name=综合物流",
+                    "scene": null
+                },
+                {
+                    "id": -1,
+                    "name": "产品列表",
+                    "pathName": "pages/ProductList",
+                    "query": "categoryIds=9",
+                    "scene": null
                 }
             ]
         }

+ 17 - 0
src/App.vue

@@ -118,4 +118,21 @@ page {
     font-family: 'OSP';
     src: url(http://imt.oss-cn-hangzhou.aliyuncs.com/micro/OSP-DIN.ttf);
 }
+
+.form {
+    .van-cell {
+        --cell-vertical-padding: 23px;
+
+        .van-field__label {
+            --field-label-color: #000000;
+            font-size: 14px;
+            font-weight: bold;
+        }
+
+        .van-field__input {
+            --field-input-text-color: #000;
+            font-size: 14px;
+        }
+    }
+}
 </style>

+ 1 - 0
src/components/AuthPhone.vue

@@ -53,6 +53,7 @@ export default {
                             this.$http.setToken(res);
                         }
                         this.$store.dispatch('getUserInfo');
+                        this.navigateBack();
                     });
             }
         },

+ 138 - 16
src/components/Banner.vue

@@ -1,17 +1,24 @@
 <template>
-    <div class="banner">
-        <swiper autoplay style="height:400rpx" @change="current = $event.detail.current" :current="current">
-            <swiper-item v-for="item in banners" :key="item.id">
-                <van-image :src="item.img" fit="widthFix" />
-            </swiper-item>
-        </swiper>
-        <div class="dots" v-if="banners.length > 1">
-            <div
-                class="dot"
-                :class="{ active: index === current }"
-                v-for="(item, index) in banners"
-                :key="item.id"
-            ></div>
+    <div class="banner-content" :style="{ height: `${height * 2}rpx` }">
+        <div class="fixedIMgContent" v-if="imgInfo && fixed && scrollTop < height / 3">
+            <div class="fixedIMg" :style="{ height: `${height * 2}rpx` }">
+                <van-image :src="imgInfo" width="100%" :height="`${height * 2}rpx`" fit="cover" :radius="radius" />
+            </div>
+        </div>
+        <div class="swiperContent" :style="bannerStyle">
+            <swiper autoplay :style="scale" @change="current = $event.detail.current" :current="current">
+                <swiper-item v-for="item in banners" :key="item.id">
+                    <van-image :src="item.img" width="100%" height="100%" fit="cover" :radius="radius" />
+                </swiper-item>
+            </swiper>
+            <div class="dots" :class="{ isRight: right }" v-if="banners.length > 1">
+                <div
+                    class="dot"
+                    :class="{ active: index === current }"
+                    v-for="(item, index) in banners"
+                    :key="item.id"
+                ></div>
+            </div>
         </div>
     </div>
 </template>
@@ -23,19 +30,102 @@ export default {
             default: () => {
                 return [];
             }
+        },
+        height: {
+            type: Number,
+            default: 200
+        },
+        right: {
+            type: Boolean,
+            default: false
+        },
+        radius: {
+            type: Number,
+            default: 4
+        },
+        fixed: {
+            type: Boolean,
+            default: false
         }
     },
     data() {
         return {
-            current: 0
+            current: 0,
+            scrollTop: 0
         };
     },
-    onShow() {}
+    computed: {
+        bannerStyle() {
+            if (this.scrollTop < 0) {
+                return {
+                    position: 'fixed',
+                    top: 0,
+                    left: 0,
+                    bottom: 0,
+                    right: 0
+                };
+            } else if (this.scrollTop === 0 && this.fixed) {
+                return {
+                    position: 'fixed',
+                    top: 0,
+                    left: 0,
+                    bottom: 0,
+                    right: 0
+                };
+            } else {
+                return {
+                    position: 'relative'
+                };
+            }
+        },
+        scale() {
+            if (this.scrollTop < 0) {
+                return {
+                    height: (this.height - this.scrollTop) * 2 + 'rpx'
+                };
+            } else {
+                return {
+                    height: this.height * 2 + 'rpx'
+                };
+            }
+        },
+        imgInfo() {
+            if (this.banners.length > this.current) {
+                return [...this.banners][this.current].img;
+            } else {
+                return '';
+            }
+        }
+    },
+    onPageScroll(e) {
+        if (e.scrollTop > 0) {
+            wx.setNavigationBarColor({
+                frontColor: '#000000',
+                backgroundColor: '#ffffff',
+                animation: {
+                    duration: 400,
+                    timingFunc: 'easeIn'
+                }
+            });
+        } else {
+            wx.setNavigationBarColor({
+                frontColor: '#ffffff',
+                backgroundColor: '#000000',
+                animation: {
+                    duration: 400,
+                    timingFunc: 'easeIn'
+                }
+            });
+        }
+
+        this.scrollTop = e.scrollTop;
+    }
 };
 </script>
 <style lang="less">
-.banner {
+.banner-content {
     position: relative;
+    z-index: 1;
     .dots {
         position: absolute;
         bottom: 10px;
@@ -55,6 +145,38 @@ export default {
                 background-color: @warn;
             }
         }
+
+        &.isRight {
+            left: auto;
+            right: 10px;
+            transform: translateX(0);
+        }
+    }
+}
+
+#main {
+    position: relative;
+    z-index: 2;
+}
+
+.fixedIMg {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    z-index: 0;
+
+    &::after {
+        content: '';
+        height: 70%;
+        background-color: #fff;
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        right: 0;
     }
 }
+.swiperContent {
+    z-index: 1;
+}
 </style>

+ 32 - 0
src/components/FixedButton.vue

@@ -0,0 +1,32 @@
+<template>
+    <div class="bottomFixed">
+        <div class="btn">
+            <slot></slot>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    name: 'FixedButton'
+};
+</script>
+
+<style lang="less">
+.bottomFixed {
+    height: 60px;
+
+    .btn {
+        position: fixed;
+        background-color: #fff;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        padding: 8px 68px;
+        z-index: 99;
+        box-shadow: 0px -1px 2px 0px rgba(0, 0, 0, 0.04);
+        .van-button {
+            height: 44px;
+        }
+    }
+}
+</style>

+ 109 - 0
src/components/News/Grid.vue

@@ -0,0 +1,109 @@
+<template>
+    <div class="news-grid news" @click="navigateTo('/pages/news/Detail?id=' + info.id, false)">
+        <van-image :src="info.img" fit="cover" :height="180" custom-class="my-img" />
+        <div class="text1">{{ info.title }}</div>
+        <div class="activity" v-if="isActivity">
+            <div class="activity-info">
+                <van-icon name="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/iocn_didian.png" />
+                <div class="text">{{ info.address }}</div>
+            </div>
+            <div class="activity-info">
+                <van-icon name="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/iocn_shijian.png" />
+                <div class="text">{{ info.date }}</div>
+            </div>
+
+            <div class="btn">
+                <van-button :color="$colors.warn" :radius="4" :disabled="isEnd" :readonly="userActivity">{{
+                    isEnd ? $t('bao-ming-jie-shu') : userActivity ? '报名中' : '活动报名'
+                }}</van-button>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        },
+        userActivity: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {};
+    },
+    computed: {
+        isActivity() {
+            if (this.info.type === 'INDUSTRY_ACTIVITIES') {
+                return true;
+            } else {
+                return false;
+            }
+        },
+        session() {
+            return this.info.session || [];
+        },
+        isEnd() {
+            return this.info.isEnd || false;
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.news-grid {
+    border-radius: 4px;
+    overflow: hidden;
+    background-color: #fff;
+    .text1 {
+        padding: 12px;
+        display: -webkit-box;
+        -webkit-box-orient: vertical;
+        -webkit-line-clamp: 2;
+        overflow: hidden;
+        font-size: 16px;
+        color: #000000;
+        line-height: 24px;
+    }
+
+    &:active {
+        background-color: darken(#fff, 10);
+    }
+
+    .activity {
+        display: flex;
+        flex-direction: column;
+
+        .activity-info {
+            display: flex;
+            align-items: center;
+            .text {
+                font-size: 12px;
+                color: #878d99;
+                line-height: 24px;
+                margin-left: 4px;
+            }
+        }
+    }
+}
+</style>
+<style lang="less">
+.my-img {
+    --image-placeholder-background-color: #ccc;
+}
+
+.activity {
+    .btn {
+        align-self: flex-end;
+        .van-button {
+            min-width: 110px;
+            height: 36px;
+        }
+    }
+    padding: 0 16px 16px 12px;
+}
+</style>

+ 59 - 0
src/components/News/Row.vue

@@ -0,0 +1,59 @@
+<template>
+    <div class="news" @click="navigateTo('/pages/news/Detail?id=' + info.id, false)">
+        <van-image :src="info.img" fit="cover" :width="120" :height="120" custom-class="my-img" />
+        <div class="news-info">
+            <div class="text1">{{ info.title }}</div>
+            <p>{{ info.createdAt }}</p>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {};
+    }
+};
+</script>
+<style lang="less" scoped>
+.news {
+    display: flex;
+    background-color: #fff;
+    border-radius: 4px;
+    overflow: hidden;
+    .news-info {
+        padding: 12px 10px;
+        flex-grow: 1;
+        overflow: hidden;
+        .text1 {
+            display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 2;
+            overflow: hidden;
+            font-size: 16px;
+            color: #000000;
+            line-height: 24px;
+        }
+
+        p {
+            color: #acb3bf;
+            margin-top: 6px;
+        }
+    }
+    &:active {
+        background-color: darken(#fff, 10);
+    }
+}
+</style>
+<style lang="less">
+.my-img {
+    --image-placeholder-background-color: #ccc;
+}
+</style>

+ 5 - 2
src/components/SortList.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="list-row" style=" min-height: calc(100vh - 71px - 172rpx)">
+    <div class="list-row" :style="` min-height: calc(100vh - 172rpx - ${top || 0})`">
         <slot></slot>
         <van-empty
             image="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/img_kong.png"
@@ -26,6 +26,10 @@ export default {
         finish: {
             type: Boolean,
             default: false
+        },
+        top: {
+            type: String,
+            default: ''
         }
     },
     data() {
@@ -39,7 +43,6 @@ export default {
 .list-row {
     background: #f5f7fa;
     padding: 6px 0;
-
     box-sizing: border-box;
 
     .van-empty__image {

+ 108 - 0
src/components/bar/CustomBar.vue

@@ -0,0 +1,108 @@
+<template>
+    <div :style="{ height: fixed ? 0 : '71px' }">
+        <div class="navBar" :style="narStyle" id="searchBar">
+            <van-icon name="arrow-left" @click="navigateBack" :size="24" :color="fontColor" />
+
+            <div class="text" v-if="ratio" :style="{ fontColor: fontColor }">{{ title }}</div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        fixed: {
+            type: Boolean,
+            default: true
+        },
+        pre: {
+            type: Number,
+            default: 0.3
+        },
+        sticky: {
+            type: Boolean,
+            default: true
+        },
+        bg: {
+            type: String,
+            default: ''
+        },
+        title: {
+            type: String,
+            default: ''
+        }
+    },
+    data() {
+        return {
+            menuButtonInfo: {},
+            isHome: false,
+            ratio: 0
+        };
+    },
+    computed: {
+        narStyle() {
+            let style = {};
+            if (this.sticky) {
+                style.background = 'rgba(255, 255, 255,' + (this.pre + (1 - this.pre) * this.ratio) + ')';
+            }
+            if (this.menuButtonInfo.top) {
+                style.padding = this.menuButtonInfo.top + 'px ' + (15 + this.menuButtonInfo.width) + 'px 15px 15px';
+                style.height = this.menuButtonInfo.height + 'px';
+            }
+            if (this.bg) {
+                style.background = this.bg;
+            }
+            return style;
+        },
+        fontColor() {
+            return this.ratio ? '#000' : '#fff';
+        }
+    },
+    mounted() {
+        this.menuButtonInfo = wx.getMenuButtonBoundingClientRect();
+    },
+    onPageScroll(e) {
+        if (e.scrollTop <= this.barTop && e.scrollTop > 0) {
+            this.ratio = Math.ceil((e.scrollTop * 100) / this.barTop) / 100;
+        } else if (e.scrollTop <= 0) {
+            this.ratio = 0;
+        } else {
+            this.ratio = 1;
+        }
+    }
+};
+</script>
+<style lang="less">
+.fixed {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    z-index: 200;
+}
+.navBar {
+    background-color: @prim;
+    display: flex;
+    align-items: center;
+    position: relative;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    z-index: 99;
+    .logo {
+        width: 48px;
+        height: 100%;
+        transform: translateY(-3px);
+    }
+
+    .text {
+        position: absolute;
+        left: 50%;
+        transform: translateX(-50%);
+        font-size: 17px;
+        font-weight: bold;
+        color: #000000;
+        line-height: 20px;
+    }
+}
+</style>

+ 71 - 17
src/components/bar/FilterSortBar.vue

@@ -3,42 +3,41 @@
         <div class="sort-top">
             <div class="sort-left">
                 <block v-for="item in sortList" :key="item.key">
-                    <div class="sort-item" :class="{ active: sort === item.key }">{{ $t(item.name) }}</div>
+                    <div class="sort-item" @click="changeSort(item.key)" :class="{ active: sort === item.key }">
+                        {{ $t(item.name) }}
+                    </div>
                 </block>
             </div>
 
-            <div class="showType">
+            <div class="showType" @click="changeShowType">
                 <van-icon :size="16" :color="showType === 'grid' ? $colors.warn : '#000'" name="apps-o" />
             </div>
-            <div class="shaixuan">
+            <div class="shaixuan" @click="showFilter">
                 <span>筛选</span>
                 <van-icon :size="16" name="filter-o" />
             </div>
         </div>
         <div class="filter-list">
             <div class="col2">
-                <div class="filter-item">
+                <div class="filter-box">
                     <slot name="filter1"></slot>
-                    <van-icon name="arrow-down" :size="12" color="#878d99" />
                 </div>
             </div>
             <div class="col4">
-                <div class="filter-item">
+                <div class="filter-box">
                     <slot name="filter2"></slot>
-                    <van-icon name="arrow-down" :size="12" color="#878d99" />
                 </div>
             </div>
             <div class="col4">
-                <div class="filter-item">
+                <div class="filter-box">
                     <slot name="filter3"></slot>
-                    <van-icon name="arrow-down" :size="12" color="#878d99" />
                 </div>
             </div>
         </div>
     </div>
 </template>
 <script>
-import { BrandSortType } from '../../utils/appState';
+import { BrandSortType, ProductSortType } from '../../utils/appState';
 export default {
     props: {
         sort: {
@@ -48,6 +47,22 @@ export default {
         showType: {
             type: String,
             default: 'grid'
+        },
+        filter1: {
+            type: Boolean,
+            default: false
+        },
+        filter2: {
+            type: Boolean,
+            default: false
+        },
+        filter3: {
+            type: Boolean,
+            default: false
+        },
+        pageType: {
+            type: String,
+            default: ''
         }
     },
     data() {
@@ -55,16 +70,36 @@ export default {
     },
     computed: {
         sortList() {
-            return [...BrandSortType].map(item => {
-                return {
-                    key: item[0],
-                    name: item[1]
-                };
-            });
+            if (this.pageType === 'vendor') {
+                return [...BrandSortType].map(item => {
+                    return {
+                        key: item[0],
+                        name: item[1]
+                    };
+                });
+            } else {
+                return [...ProductSortType].map(item => {
+                    return {
+                        key: item[0],
+                        name: item[1]
+                    };
+                });
+            }
         }
     },
     onShow() {
         console.log(this.sortList);
+    },
+    methods: {
+        showFilter() {
+            this.$emit('showFilter');
+        },
+        changeSort(value) {
+            this.$emit('changeSort', value);
+        },
+        changeShowType() {
+            this.$emit('changeShowType');
+        }
     }
 };
 </script>
@@ -88,11 +123,17 @@ export default {
         span {
             margin-right: 4px;
         }
+        &:active {
+            background-color: overlay(#f5f7fa, #000);
+        }
     }
     .showType {
         padding: 0 16px;
         align-self: center;
         line-height: 16px;
+        &:active {
+            background-color: overlay(#f5f7fa, #000);
+        }
     }
 
     .sort-left {
@@ -116,12 +157,16 @@ export default {
                     transform: translateX(-50%);
                 }
             }
+
+            &:active {
+                color: @warn;
+            }
         }
     }
 }
 
 .filter-list {
-    padding: 4px 16px 10px;
+    padding: 4px 11.5px 10px;
     display: flex;
     .col2 {
         width: 50%;
@@ -130,6 +175,10 @@ export default {
     .col4 {
         width: 25%;
     }
+
+    .filter-box {
+        margin: 0 4.5px;
+    }
     .filter-item {
         margin: 0 4.5px;
 
@@ -143,6 +192,11 @@ export default {
         display: flex;
         align-items: center;
         justify-content: space-between;
+
+        &.active {
+            background-color: #fff4e5;
+            color: @warn;
+        }
     }
 }
 </style>

+ 12 - 9
src/components/bar/SearchBar.vue

@@ -1,14 +1,12 @@
 <template>
-    <div>
-        <van-sticky>
-            <div class="navBar" :style="narStyle">
-                <img class="logo" src="../../static/imgs/home_logo.png" alt="" />
-                <div class="search">
-                    <van-icon name="search" color="rgba(255,255,255,0.6)" />
-                    <span>搜索展商/产品/资讯</span>
-                </div>
+    <div style="height:71px">
+        <div class="navBar" :style="narStyle">
+            <img class="logo" src="../../static/imgs/home_logo.png" alt="" />
+            <div class="search">
+                <van-icon name="search" color="rgba(255,255,255,0.6)" />
+                <span>搜索展商/产品/资讯</span>
             </div>
-        </van-sticky>
+        </div>
     </div>
 </template>
 <script>
@@ -43,6 +41,11 @@ export default {
     background-color: @prim;
     display: flex;
     align-items: center;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    z-index: 99;
     .logo {
         width: 48px;
         height: 100%;

+ 32 - 9
src/components/bar/SearchBarWithValue.vue

@@ -1,9 +1,9 @@
 <template>
-    <div :class="{ fixed: fixed }">
+    <div :class="{ fixed: fixed, dark: dark }">
         <van-sticky :z-index="200">
             <div class="navBar" :style="narStyle" id="searchBar">
-                <img v-if="!isHome" class="logo" src="../../static/imgs/home_logo.png" alt="" />
-                <van-icon v-else name="arrow-left" color="#fff" />
+                <!-- <img v-if="!isHome" class="logo" src="../../static/imgs/home_logo.png" alt="" /> -->
+                <van-icon name="arrow-left" :size="24" @click="navigateBack" :color="dark ? '#fff' : '#000'" />
                 <van-search
                     :style="searchStyle"
                     :value="search"
@@ -32,6 +32,10 @@ export default {
         ratio: {
             type: Number,
             default: 0
+        },
+        dark: {
+            type: Boolean,
+            default: true
         }
     },
     data() {
@@ -44,11 +48,13 @@ export default {
     computed: {
         narStyle() {
             let style = {};
-            if (this.fixed) {
+            if (this.fixed && this.dark) {
                 style.background = 'rgba(15, 38, 77,' + (0.3 + 0.7 * this.ratio) + ')';
+            } else {
+                style.background = 'rgba(255, 255, 255,' + (0.3 + 0.7 * this.ratio) + ')';
             }
             if (this.menuButtonInfo.top) {
-                style.padding = this.menuButtonInfo.top + 'px ' + (30 + this.menuButtonInfo.width) + 'px 15px 15px';
+                style.padding = this.menuButtonInfo.top + 'px ' + (15 + this.menuButtonInfo.width) + 'px 15px 15px';
                 style.height = this.menuButtonInfo.height + 'px';
             }
             return style;
@@ -99,6 +105,26 @@ export default {
     right: 0;
     z-index: 200;
 }
+
+.dark {
+    .van-search {
+        .van-search__content {
+            background-color: rgba(255, 255, 255, 0.1);
+        }
+        .van-icon {
+            color: rgba(255, 255, 255, 0.5);
+        }
+        .van-search__field {
+            .van-field__input {
+                color: #fff;
+            }
+
+            .van-field__placeholder {
+                color: rgba(255, 255, 255, 0.5);
+            }
+        }
+    }
+}
 .navBar {
     background-color: @prim;
     display: flex;
@@ -113,19 +139,16 @@ export default {
     }
     .van-search {
         .van-search__content {
-            background-color: rgba(255, 255, 255, 0.1);
         }
         .van-icon {
-            color: rgba(255, 255, 255, 0.5);
+            color: #bcc1cc;
         }
         .van-search__field {
             .van-field__input {
-                color: #fff;
                 font-size: 12px;
             }
 
             .van-field__placeholder {
-                color: rgba(255, 255, 255, 0.5);
             }
         }
     }

+ 4 - 1
src/components/filter/Application.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="filterInfo">
+    <div class="filterInfo filter--big">
         <div class="title" @click="showMore = !showMore">
             <h4>应用领域</h4>
             <van-icon :custom-class="showMore ? 'showMore' : ''" name="arrow-down" color="#CBCFDB" :size="18" />
@@ -88,6 +88,9 @@ export default {
         display: flex;
         align-items: center;
         justify-content: space-between;
+        &:active {
+            background-color: overlay(#fff, #000);
+        }
 
         .van-icon {
             transition: transform ease-in-out 0.3s;

+ 62 - 16
src/components/filter/Country.vue

@@ -1,14 +1,24 @@
 <template>
-    <div class="filterInfo">
-        <h4>国家和地区</h4>
+    <div class="filterInfo" :class="`filter--${size}`">
+        <block v-if="size === 'big'">
+            <h4>国家和地区</h4>
+        </block>
         <div class="filter-btn" :class="{ noChoose: !valueInfo }" @click="show">
-            <h3 class="fontNormal">{{ valueInfo ? $t(valueInfo.label) : '请选择' }}</h3>
-            <van-icon color="#CBCFDB" :size="18" name="arrow" />
+            <h3 class="fontNormal">{{ valueInfo ? $t(valueInfo.label) : size === 'big' ? '请选择' : '地区' }}</h3>
+            <van-icon v-if="size === 'big'" color="#CBCFDB" :size="18" name="arrow" />
+            <van-icon
+                v-if="size === 'small'"
+                :color="valueInfo ? $colors.warn : '#878D99'"
+                :size="10"
+                name="arrow-down"
+            />
         </div>
 
         <van-popup :show="showPopup" round position="bottom" custom-style="height: 300px" @close="showPopup = false">
             <div class="bar">
-                <van-icon color="#5E636D" @click="back" :size="18" name="arrow-left" />
+                <div class="left-icon">
+                    <van-icon v-if="headerInfo" color="#5E636D" @click="back" :size="18" name="arrow-left" />
+                </div>
                 <h3>国家地区</h3>
                 <van-icon color="#5E636D" :size="18" name="cross" @click="showPopup = false" />
             </div>
@@ -55,6 +65,10 @@ export default {
         value: {
             type: [Number, String],
             default: 0
+        },
+        size: {
+            type: String,
+            default: 'big'
         }
     },
     data() {
@@ -129,13 +143,17 @@ export default {
             }
         },
         backChoose(value) {
-            this.$emit('input', value || this.chooseId);
+            this.$emit('input', value || this.chooseId || '');
             this.showPopup = false;
         },
         show() {
             console.log(this.valueInfo);
             this.chooseId = this.value || 0;
             this.showPopup = true;
+        },
+        clear() {
+            this.chooseId = 0;
+            this.backChoose();
         }
     }
 };
@@ -152,6 +170,9 @@ export default {
         padding: 0 16px;
         margin-bottom: 6px;
         z-index: 20;
+        .left-icon {
+            width: 18px;
+        }
         h3 {
             flex-grow: 1;
             text-align: center;
@@ -170,26 +191,51 @@ export default {
     }
 }
 .filterInfo {
-    padding: 0 16px 20px;
+    &.filter--big {
+        padding: 0 16px 20px;
+        .filter-btn {
+            height: 44px;
+            padding: 0 16px;
+            h3 {
+                padding-right: 10px;
+            }
+            &.noChoose {
+                h3 {
+                    color: #bcc1cc;
+                }
+            }
+        }
+    }
+    &.filter--small {
+        .filter-btn {
+            height: 28px;
+            padding: 0 5px 0 10px;
+            background-color: #fff4e5;
+            h3 {
+                font-size: 12px;
+                color: @warn;
+                padding-right: 2px;
+            }
+
+            &.noChoose {
+                background: #f2f3f5;
+                h3 {
+                    color: #878d99;
+                }
+            }
+        }
+    }
     h4 {
         padding: 14px 0;
     }
     .filter-btn {
-        height: 44px;
         background: #f5f7fa;
         border-radius: 4px;
         display: flex;
         align-items: center;
-        padding: 0 16px;
+
         h3 {
             flex-grow: 1;
-            padding-right: 10px;
-        }
-
-        &.noChoose {
-            h3 {
-                color: #bcc1cc;
-            }
         }
     }
 }

+ 228 - 0
src/components/filter/EnterpriseType.vue

@@ -0,0 +1,228 @@
+<template>
+    <div class="filterInfo" :class="`filter--${size}`">
+        <block v-if="size === 'big'">
+            <h4>企业类型</h4>
+        </block>
+
+        <div class="filter-btn" :class="{ noChoose: !valueInfo }" @click="show">
+            <h3 class="fontNormal">{{ valueInfo ? $t(valueInfo.name) : size === 'big' ? '请选择' : '企业类型' }}</h3>
+            <van-icon v-if="size === 'big'" color="#CBCFDB" :size="18" name="arrow" />
+            <van-icon
+                v-if="size === 'small'"
+                :color="valueInfo ? $colors.warn : '#878D99'"
+                :size="10"
+                name="arrow-down"
+            />
+        </div>
+
+        <van-popup :show="showPopup" round position="bottom" custom-style="height: 300px" @close="showPopup = false">
+            <div class="bar">
+                <div class="left-icon">
+                    <van-icon v-if="headerInfo" color="#5E636D" @click="back" :size="18" name="arrow-left" />
+                </div>
+                <h3>选择企业类型</h3>
+                <van-icon color="#5E636D" :size="18" name="cross" @click="showPopup = false" />
+            </div>
+            <van-cell-group :border="false">
+                <block v-for="item in showList" :key="item.id">
+                    <van-cell
+                        @click="chooseList(item)"
+                        :border="false"
+                        :custom-class="chooseId === item.id ? 'active' : ''"
+                    >
+                        <h3 class="fontNormal" slot="title">{{ $t(item.name) }}</h3>
+                        <van-icon
+                            slot="right-icon"
+                            :size="18"
+                            :color="$colors.warn"
+                            v-if="chooseId === item.id"
+                            name="success"
+                        />
+                    </van-cell>
+                </block>
+            </van-cell-group>
+        </van-popup>
+    </div>
+</template>
+<script>
+import { EnterpriseType } from '../../utils/appState';
+export default {
+    props: {
+        value: {
+            type: [Number, String],
+            default: 0
+        },
+        size: {
+            type: String,
+            default: 'big'
+        }
+    },
+    data() {
+        return {
+            showPopup: false,
+            list: [],
+            chooseId: 0,
+            main: null
+        };
+    },
+    computed: {
+        showList() {
+            const list = [...this.list];
+            if (this.isLeaf) {
+                return list.filter(item => {
+                    return item.parentId === this.chooseInfo.parentId;
+                });
+            } else if (this.chooseId) {
+                return list.filter(item => {
+                    return item.parentId === this.chooseId;
+                });
+            } else {
+                return list.filter(item => {
+                    return !item.parentId;
+                });
+            }
+        },
+        chooseInfo() {
+            const list = [...this.list];
+            return list.find(item => {
+                return item.id === this.chooseId;
+            });
+        },
+        isLeaf() {
+            if (this.chooseInfo && !this.chooseInfo.children) {
+                return true;
+            }
+            return false;
+        },
+        valueInfo() {
+            const list = [...this.list];
+            return list.find(item => {
+                return item.id === this.value;
+            });
+        },
+        headerInfo() {
+            if (this.isLeaf) {
+                const list = [...this.list];
+                return list.find(item => {
+                    return item.id === this.chooseInfo.parentId;
+                });
+            } else {
+                return this.chooseInfo;
+            }
+        }
+    },
+    mounted() {
+        this.list = [...EnterpriseType].map(item => {
+            return {
+                id: item[0],
+                name: item[1]
+            };
+        });
+    },
+    methods: {
+        chooseList(info) {
+            if (info.children && info.children.length > 0) {
+                this.chooseId = info.id;
+            } else {
+                this.chooseId = info.id;
+                this.backChoose();
+            }
+        },
+        back() {
+            if (this.headerInfo) {
+                this.chooseId = this.headerInfo.parent || 0;
+            }
+        },
+        backChoose(id) {
+            this.$emit('input', id || this.chooseId);
+            this.showPopup = false;
+        },
+        show() {
+            this.chooseId = this.value || 0;
+            this.showPopup = true;
+        }
+    }
+};
+</script>
+<style lang="less">
+.van-popup {
+    .bar {
+        position: sticky;
+        top: 0;
+        height: 48px;
+        background: #ffffff;
+        display: flex;
+        align-items: center;
+        padding: 0 16px;
+        margin-bottom: 6px;
+        z-index: 20;
+        h3 {
+            flex-grow: 1;
+            text-align: center;
+            padding: 0 10px;
+        }
+        .left-icon {
+            width: 18px;
+        }
+    }
+
+    .van-cell {
+        padding: 12px 40px;
+
+        &.active {
+            h3 {
+                color: @warn;
+            }
+        }
+    }
+}
+.filterInfo {
+    &.filter--big {
+        padding: 0 16px 20px;
+        .filter-btn {
+            height: 44px;
+            padding: 0 16px;
+            h3 {
+                padding-right: 10px;
+            }
+            &.noChoose {
+                h3 {
+                    color: #bcc1cc;
+                }
+            }
+        }
+    }
+    &.filter--small {
+        .filter-btn {
+            height: 28px;
+            padding: 0 5px 0 10px;
+            background-color: #fff4e5;
+            h3 {
+                font-size: 12px;
+                color: @warn;
+                padding-right: 2px;
+            }
+
+            &.noChoose {
+                background: #f2f3f5;
+                h3 {
+                    color: #878d99;
+                }
+            }
+        }
+    }
+    h4 {
+        padding: 14px 0;
+    }
+    .filter-btn {
+        background: #f5f7fa;
+        border-radius: 4px;
+        display: flex;
+        align-items: center;
+
+        h3 {
+            flex-grow: 1;
+        }
+    }
+}
+</style>

+ 77 - 30
src/components/filter/ProductCategory.vue

@@ -1,14 +1,24 @@
 <template>
-    <div class="filterInfo">
-        <h4>分类</h4>
+    <div class="filterInfo" :class="`filter--${size}`">
+        <block v-if="size === 'big'">
+            <h4>分类</h4>
+        </block>
         <div class="filter-btn" :class="{ noChoose: !valueInfo }" @click="show">
-            <h3 class="fontNormal">{{ valueInfo ? getName(valueInfo) : '请选择' }}</h3>
-            <van-icon color="#CBCFDB" :size="18" name="arrow" />
+            <h3 class="fontNormal">{{ valueInfo ? getName(valueInfo) : size === 'big' ? '请选择' : '分类' }}</h3>
+            <van-icon v-if="size === 'big'" color="#CBCFDB" :size="18" name="arrow" />
+            <van-icon
+                v-if="size === 'small'"
+                :color="valueInfo ? $colors.warn : '#878D99'"
+                :size="10"
+                name="arrow-down"
+            />
         </div>
 
         <van-popup :show="showPopup" round position="bottom" custom-style="height: 300px" @close="showPopup = false">
             <div class="bar">
-                <van-icon color="#5E636D" @click="back" :size="18" name="arrow-left" />
+                <div class="left-icon">
+                    <van-icon v-if="headerInfo" color="#5E636D" @click="back" :size="18" name="arrow-left" />
+                </div>
                 <h3>选择类别</h3>
                 <van-icon color="#5E636D" :size="18" name="cross" @click="showPopup = false" />
             </div>
@@ -49,11 +59,20 @@
     </div>
 </template>
 <script>
+import { mapState } from 'vuex';
 export default {
     props: {
         value: {
             type: [Number, String],
             default: 0
+        },
+        firstCategory: {
+            type: [Number, String],
+            default: ''
+        },
+        size: {
+            type: String,
+            default: 'big'
         }
     },
     data() {
@@ -65,6 +84,7 @@ export default {
         };
     },
     computed: {
+        ...mapState(['productCategories']),
         showList() {
             const list = [...this.list];
             if (this.isLeaf) {
@@ -75,6 +95,10 @@ export default {
                 return list.filter(item => {
                     return item.parentId === this.chooseId;
                 });
+            } else if (this.firstCategory) {
+                return list.filter(item => {
+                    return item.parentId === Number(this.firstCategory);
+                });
             } else {
                 return list.filter(item => {
                     return !item.parentId;
@@ -103,7 +127,7 @@ export default {
             if (this.isLeaf) {
                 const list = [...this.list];
                 return list.find(item => {
-                    return item.value === this.chooseInfo.parent;
+                    return item.id === this.chooseInfo.parentId;
                 });
             } else {
                 return this.chooseInfo;
@@ -111,18 +135,13 @@ export default {
         }
     },
     mounted() {
-        this.$http.get('/productCategory/tree').then(res => {
-            this.list = res
-                .map(item => {
-                    return [
-                        item,
-                        item.children.map(child => {
-                            return [child, child.children];
-                        })
-                    ];
-                })
-                .flat(Infinity);
-        });
+        if (this.productCategories.length > 0) {
+            this.list = [...this.productCategories];
+        } else {
+            this.$store.dispatch('getProductCategories').then(res => {
+                this.list = res;
+            });
+        }
     },
     methods: {
         chooseList(info) {
@@ -134,8 +153,8 @@ export default {
             }
         },
         back() {
-            if (this.chooseInfo) {
-                this.chooseId = this.chooseInfo.parentId || 0;
+            if (this.headerInfo) {
+                this.chooseId = this.headerInfo.parent || 0;
             }
         },
         backChoose(id) {
@@ -166,6 +185,9 @@ export default {
             text-align: center;
             padding: 0 10px;
         }
+        .left-icon {
+            width: 18px;
+        }
     }
 
     .van-cell {
@@ -179,26 +201,51 @@ export default {
     }
 }
 .filterInfo {
-    padding: 0 16px 20px;
+    &.filter--big {
+        padding: 0 16px 20px;
+        .filter-btn {
+            height: 44px;
+            padding: 0 16px;
+            h3 {
+                padding-right: 10px;
+            }
+            &.noChoose {
+                h3 {
+                    color: #bcc1cc;
+                }
+            }
+        }
+    }
+    &.filter--small {
+        .filter-btn {
+            height: 28px;
+            padding: 0 5px 0 10px;
+            background-color: #fff4e5;
+            h3 {
+                font-size: 12px;
+                color: @warn;
+                padding-right: 2px;
+            }
+
+            &.noChoose {
+                background: #f2f3f5;
+                h3 {
+                    color: #878d99;
+                }
+            }
+        }
+    }
     h4 {
         padding: 14px 0;
     }
     .filter-btn {
-        height: 44px;
         background: #f5f7fa;
         border-radius: 4px;
         display: flex;
         align-items: center;
-        padding: 0 16px;
+
         h3 {
             flex-grow: 1;
-            padding-right: 10px;
-        }
-
-        &.noChoose {
-            h3 {
-                color: #bcc1cc;
-            }
         }
     }
 }

+ 65 - 23
src/components/filter/ProductTags.vue

@@ -1,19 +1,29 @@
 <template>
-    <div class="filterInfo">
-        <h4>产品标签</h4>
+    <div class="filterInfo" :class="`filter--${size}`">
+        <block v-if="size === 'big'">
+            <h4>产品标签</h4>
+        </block>
         <div class="filter-btn" :class="{ noChoose: !valueInfo }" @click="show">
-            <h3 class="fontNormal">{{ valueInfo ? getName(valueInfo) : '请选择' }}</h3>
-            <van-icon color="#CBCFDB" :size="18" name="arrow" />
+            <h3 class="fontNormal">{{ valueInfo ? getName(valueInfo) : size === 'big' ? '请选择' : '标签' }}</h3>
+            <van-icon v-if="size === 'big'" color="#CBCFDB" :size="18" name="arrow" />
+            <van-icon
+                v-if="size === 'small'"
+                :color="valueInfo ? $colors.warn : '#878D99'"
+                :size="10"
+                name="arrow-down"
+            />
         </div>
 
         <van-popup :show="showPopup" round position="bottom" custom-style="height: 300px" @close="showPopup = false">
             <div class="bar">
-                <van-icon color="#5E636D" @click="back" :size="18" name="arrow-left" />
-                <h3>选择类别</h3>
+                <div class="left-icon">
+                    <van-icon v-if="headerInfo" color="#5E636D" @click="back" :size="18" name="arrow-left" />
+                </div>
+                <h3>选择标签</h3>
                 <van-icon color="#5E636D" :size="18" name="cross" @click="showPopup = false" />
             </div>
             <van-cell-group :border="false">
-                <van-cell
+                <!-- <van-cell
                     @click="backChoose(headerInfo.id)"
                     v-if="headerInfo"
                     :border="false"
@@ -27,7 +37,7 @@
                         v-if="chooseId === headerInfo.id"
                         name="success"
                     />
-                </van-cell>
+                </van-cell> -->
                 <block v-for="item in showList" :key="item.id">
                     <van-cell
                         @click="chooseList(item)"
@@ -55,6 +65,10 @@ export default {
         value: {
             type: [Number, String],
             default: 0
+        },
+        size: {
+            type: String,
+            default: 'big'
         }
     },
     data() {
@@ -89,7 +103,7 @@ export default {
             });
         },
         isLeaf() {
-            if (this.chooseInfo && this.chooseInfo.children.length == 0) {
+            if (this.chooseInfo && !this.chooseInfo.children) {
                 return true;
             }
             return false;
@@ -104,7 +118,7 @@ export default {
             if (this.isLeaf) {
                 const list = [...this.list];
                 return list.find(item => {
-                    return item.value === this.chooseInfo.parent;
+                    return item.id === this.chooseInfo.parentId;
                 });
             } else {
                 return this.chooseInfo;
@@ -118,7 +132,7 @@ export default {
     },
     methods: {
         chooseList(info) {
-            if (info.children.length > 0) {
+            if (info.children && info.children.length > 0) {
                 this.chooseId = info.id;
             } else {
                 this.chooseId = info.id;
@@ -126,8 +140,8 @@ export default {
             }
         },
         back() {
-            if (this.chooseInfo) {
-                this.chooseId = this.chooseInfo.parentId || 0;
+            if (this.headerInfo) {
+                this.chooseId = this.headerInfo.parent || 0;
             }
         },
         backChoose(id) {
@@ -158,6 +172,9 @@ export default {
             text-align: center;
             padding: 0 10px;
         }
+        .left-icon {
+            width: 18px;
+        }
     }
 
     .van-cell {
@@ -171,26 +188,51 @@ export default {
     }
 }
 .filterInfo {
-    padding: 0 16px 20px;
+    &.filter--big {
+        padding: 0 16px 20px;
+        .filter-btn {
+            height: 44px;
+            padding: 0 16px;
+            h3 {
+                padding-right: 10px;
+            }
+            &.noChoose {
+                h3 {
+                    color: #bcc1cc;
+                }
+            }
+        }
+    }
+    &.filter--small {
+        .filter-btn {
+            height: 28px;
+            padding: 0 5px 0 10px;
+            background-color: #fff4e5;
+            h3 {
+                font-size: 12px;
+                color: @warn;
+                padding-right: 2px;
+            }
+
+            &.noChoose {
+                background: #f2f3f5;
+                h3 {
+                    color: #878d99;
+                }
+            }
+        }
+    }
     h4 {
         padding: 14px 0;
     }
     .filter-btn {
-        height: 44px;
         background: #f5f7fa;
         border-radius: 4px;
         display: flex;
         align-items: center;
-        padding: 0 16px;
+
         h3 {
             flex-grow: 1;
-            padding-right: 10px;
-        }
-
-        &.noChoose {
-            h3 {
-                color: #bcc1cc;
-            }
         }
     }
 }

+ 128 - 0
src/components/imt/Bottom.vue

@@ -0,0 +1,128 @@
+<template>
+    <div class="imt-bottom">
+        <div class="bottom">
+            <van-grid clickable column-num="4" :border="false">
+                <block v-for="(item, index) in navigations" :key="index">
+                    <van-grid-item
+                        :icon="value === index ? item.img2 : item.img1"
+                        :text="item.text"
+                        :custom-class="`grid-info ${index === value ? 'active' : ''}`"
+                        @click="choose(index)"
+                    />
+                </block>
+            </van-grid>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        value: {
+            type: Number,
+            default: 0
+        }
+    },
+    data() {
+        return {
+            navigations: [
+                {
+                    img1: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_gaikuang.png',
+                    img2: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_gaikuang_pre.png',
+                    text: '概况',
+                    url: '/pages/imt/Index'
+                },
+                {
+                    img1: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_youshi.png',
+                    img2: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_youshi_pre.png',
+                    text: '优势',
+                    url: '/pages/imt/Advantage'
+                },
+                {
+                    img1: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_fuwu.png',
+                    img2: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_fuwu_pre.png',
+                    text: '服务',
+                    url: '/pages/imt/Service'
+                },
+                {
+                    img1: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_lianxi.png',
+                    img2: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_icon_lianxi_pre.png',
+                    text: '联系',
+                    url: '/pages/imt/Connect'
+                }
+            ]
+        };
+    },
+    methods: {
+        choose(index) {
+            this.$emit('input', index);
+            wx.pageScrollTo({
+                scrollTop: 0,
+                duration: 0
+            });
+            if (index === 0) {
+                wx.setNavigationBarColor({
+                    frontColor: '#ffffff',
+                    backgroundColor: '#000000',
+                    animation: {
+                        duration: 400,
+                        timingFunc: 'easeIn'
+                    }
+                });
+            } else {
+                wx.setNavigationBarColor({
+                    frontColor: '#000000',
+                    backgroundColor: '#ffffff',
+                    animation: {
+                        duration: 400,
+                        timingFunc: 'easeIn'
+                    }
+                });
+            }
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.imt-bottom {
+    height: 48px;
+    margin-top: 20px;
+
+    .bottom {
+        position: fixed;
+        bottom: 0;
+        left: 0;
+        z-index: 200;
+        width: 100%;
+        min-width: 375px;
+        height: 48px;
+    }
+}
+</style>
+<style lang="less">
+.grid-info {
+    .van-grid-item__content {
+        padding: 8px 8px;
+        .van-grid-item__text {
+            font-size: 12px;
+            color: #878d99;
+            line-height: 24px;
+            margin-top: 0;
+        }
+        .van-grid-item__icon {
+            line-height: 16px;
+            height: 16px;
+            .van-icon {
+                font-size: 16px;
+            }
+        }
+    }
+
+    &.active {
+        .van-grid-item__content {
+            .van-grid-item__text {
+                color: @warn;
+            }
+        }
+    }
+}
+</style>

+ 102 - 0
src/components/imt/Core.vue

@@ -0,0 +1,102 @@
+<template>
+    <div class="core">
+        <div class="name">
+            {{ info.title }}
+        </div>
+        <div class="sub">
+            {{ info.sub }}
+        </div>
+        <p>{{ info.content }}</p>
+        <div class="core-banner">
+            <banner :banners="banners"></banner>
+        </div>
+    </div>
+</template>
+<script>
+import Banner from '../Banner';
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    computed: {
+        banners() {
+            return [...this.info.imgs].map(item => {
+                return {
+                    img: item
+                };
+            });
+        }
+    },
+    components: {
+        Banner
+    }
+};
+</script>
+<style lang="less" scoped>
+.name {
+    font-size: 18px;
+    font-weight: bold;
+    color: #000000;
+    line-height: 26px;
+}
+
+.sub {
+    font-size: 12px;
+    color: #878d99;
+    line-height: 22px;
+    margin-top: 2px;
+    padding-bottom: 12px;
+
+    &::after {
+        content: '';
+        width: 38px;
+        height: 3px;
+        background: #ffa526;
+        display: block;
+        margin-top: 12px;
+    }
+}
+
+p {
+    font-size: 14px;
+    color: #000000;
+    line-height: 24px;
+}
+
+.core-banner {
+    margin-top: 15px;
+}
+
+.core {
+    padding-left: 16px;
+    padding-bottom: 50px;
+    position: relative;
+    &::before {
+        content: '';
+        position: absolute;
+        width: 10px;
+        height: 10px;
+        background: #0f264d;
+        left: -3px;
+        top: 8px;
+        border-radius: 100%;
+    }
+
+    &:not(:last-child) {
+        &::after {
+            content: '';
+            position: absolute;
+            width: 1px;
+            left: 2px;
+            top: 13px;
+            bottom: -13px;
+            background: #0f264d;
+        }
+    }
+}
+</style>

+ 55 - 0
src/components/imt/Title.vue

@@ -0,0 +1,55 @@
+<template>
+    <div class="imt-title">
+        <div class="text1"><slot name="name"></slot></div>
+        <div class="text2"><slot name="sub"></slot></div>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {};
+    }
+};
+</script>
+<style lang="less" scoped>
+.imt-title {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    .text1 {
+        font-size: 15px;
+        font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
+        font-weight: bold;
+        color: #292c33;
+        line-height: 20px;
+    }
+    .text2 {
+        font-size: 10px;
+        font-family: MicrosoftYaHei;
+        color: #878d99;
+        line-height: 14px;
+        margin-top: 7px;
+        position: relative;
+
+        &::before {
+            content: '';
+            width: 24px;
+            height: 1px;
+            background: #bcc1cc;
+            position: absolute;
+            left: -30px;
+            top: 50%;
+        }
+
+        &::after {
+            content: '';
+            width: 24px;
+            height: 1px;
+            background: #bcc1cc;
+            position: absolute;
+            right: -30px;
+            top: 50%;
+        }
+    }
+}
+</style>

+ 86 - 0
src/components/product/GridNormal.vue

@@ -0,0 +1,86 @@
+<template>
+    <div class="grid">
+        <van-image class="grid-img" width="100%" height="170px" :src="getList(info.img)" fit="cover" />
+        <div class="content">
+            <van-image class="grid-logo" width="56" height="24" :src="info.logo" fit="cover" />
+            <div class="text">
+                <h3 class="fontNormal">{{ name }}</h3>
+                <p>{{ info.model }}</p>
+            </div>
+            <div class="tags">
+                <van-tag v-for="(item, index) in tag" :key="index" custom-class="mini" plain color="#BCC1CC">{{
+                    item
+                }}</van-tag>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {};
+    },
+    computed: {
+        name() {
+            return this.getName(this.info);
+        },
+        tag() {
+            return (
+                this.info.tag
+                    .filter(item => {
+                        return !!item;
+                    })
+                    .slice(0, 3) || []
+            );
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.grid {
+    .content {
+        padding: 12px;
+        overflow: hidden;
+        .text {
+            margin-top: 8px;
+            overflow: hidden;
+            p {
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                height: 22px;
+            }
+        }
+    }
+    background-color: #fff;
+
+    .tags {
+        display: flex;
+        align-items: center;
+        flex-wrap: nowrap;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        min-height: 21px;
+    }
+}
+</style>
+<style lang="less">
+.grid {
+    .van-tag {
+        &.mini {
+            font-size: 10px;
+            margin-right: 4px;
+        }
+    }
+}
+</style>

+ 6 - 5
src/components/vendor/Grid.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="bg-white">
-        <van-image radius="4" width="100%" :src="info.logo" fit="cover" />
+        <van-image radius="4" width="100%" :src="logo" fit="cover" />
     </div>
 </template>
 <script>
@@ -13,9 +13,10 @@ export default {
             }
         }
     },
-    data() {
-        return {};
-    },
-    onShow() {}
+    computed: {
+        logo() {
+            return this.info.logo || '';
+        }
+    }
 };
 </script>

+ 12 - 4
src/main.js

@@ -65,7 +65,14 @@ export default {
             'pages/Authorized',
             'pages/Collect',
             'pages/Brand',
-            'pages/FilterPage'
+            'pages/Product',
+            'pages/ProductList',
+            'pages/FilterPage',
+            'pages/imt/Index',
+            'pages/imt/ServiceDetail',
+            'pages/news/News',
+            'pages/news/Detail',
+            'pages/news/Submit'
         ],
         tabBar: {
             color: '#878D99',
@@ -98,9 +105,9 @@ export default {
             ]
         },
         window: {
-            backgroundTextStyle: 'light',
+            backgroundTextStyle: 'dark',
             navigationBarBackgroundColor: '#fff',
-            navigationBarTitleText: 'megalo project',
+            navigationBarTitleText: 'imt',
             navigationBarTextStyle: 'black'
         },
         usingComponents: {
@@ -135,7 +142,8 @@ export default {
             'van-transition': '/native/vant/transition/index',
             'van-dropdown-menu': '/native/vant/dropdown-menu/index',
             'van-dropdown-item': '/native/vant/dropdown-item/index',
-            'van-nav-bar': '/native/vant/nav-bar/index'
+            'van-nav-bar': '/native/vant/nav-bar/index',
+            'van-tag': '/native/vant/tag/index'
         }
     }
 };

+ 12 - 0
src/mixins/commont.js

@@ -30,6 +30,7 @@ export default {
         },
         getList(info, index = 0) {
             let img = '';
+            console.log(info);
             if (info instanceof Array && info.length > index) {
                 img = [...info][index];
             } else if (typeof info === 'string' && info) {
@@ -59,6 +60,17 @@ export default {
         },
         navigateBack() {
             wx.navigateBack();
+        },
+        toast(message, type = 'text') {
+            if (type === 'text') {
+                this.$toast(message);
+            } else if (type === 'success') {
+                this.$toast.success(message);
+            } else if (type === 'fail') {
+                this.$toast.fail(message);
+            } else if (type !== 'loading') {
+                this.$toast({ message: message, type: type });
+            }
         }
     }
 };

+ 10 - 0
src/mixins/form.js

@@ -0,0 +1,10 @@
+export default {
+    data() {
+			rule
+		},
+    computed:{
+			canNext(){
+				return true;
+			}
+		}
+};

+ 77 - 26
src/mixins/searchList.js

@@ -1,3 +1,4 @@
+import { mapState } from 'vuex';
 export default {
     data() {
         return {
@@ -24,12 +25,14 @@ export default {
         };
     },
     computed: {
-        pageQuery() {
-            let _routeQuery = this.routeQuery || {};
-            return {
-                ..._routeQuery,
-                showType: this.showType
-            };
+        ...mapState(['filterInfo', 'productCategories']),
+        productCategoryInfo() {
+            if (this.categoryIds) {
+                return [...this.productCategories].find(item => {
+                    return item.id === Number(this.categoryIds);
+                });
+            }
+            return null;
         }
     },
     methods: {
@@ -50,6 +53,7 @@ export default {
             });
         },
         getData() {
+            this.finish = false;
             this.loading = true;
             this.empty = false;
             let data = {
@@ -106,25 +110,25 @@ export default {
                     this.empty = true;
                 });
         },
-        changeSort(prop, order) {
-            let newOrder = '';
-            if (order) {
-                if (this.sort[prop] !== order) {
-                    newOrder = order;
-                } else {
-                    newOrder = '';
-                }
-            } else {
-                if (this.sort[prop] === 'asc') {
-                    newOrder = 'desc';
-                } else if (this.sort[prop] === 'desc') {
-                    newOrder = '';
-                } else {
-                    newOrder = 'asc';
-                }
-            }
-            this.sort = { ...this.sort, [prop]: newOrder };
-        },
+        // changeSort(prop, order) {
+        //     let newOrder = '';
+        //     if (order) {
+        //         if (this.sort[prop] !== order) {
+        //             newOrder = order;
+        //         } else {
+        //             newOrder = '';
+        //         }
+        //     } else {
+        //         if (this.sort[prop] === 'asc') {
+        //             newOrder = 'desc';
+        //         } else if (this.sort[prop] === 'desc') {
+        //             newOrder = '';
+        //         } else {
+        //             newOrder = 'asc';
+        //         }
+        //     }
+        //     this.sort = { ...this.sort, [prop]: newOrder };
+        // },
         onSortChange(e) {
             this.sort = e;
             this.getData();
@@ -164,12 +168,59 @@ export default {
                 });
             });
         },
-        refreash() {}
+        refreash() {
+            console.log('刷新');
+            this.page = 1;
+            this.getData();
+            wx.pageScrollTo({
+                scrollTop: this.searchTop,
+                duration: 300
+            });
+        },
+        showFilter() {
+            const _query = { ...this.filterQuery };
+            const querys = Object.keys(_query).map(key => {
+                return key + '=' + _query[key];
+            });
+
+            this.navigateTo('/pages/FilterPage?' + querys.join('&'), false);
+        },
+        changeSort(value) {
+            this.sort = value;
+        },
+        changeShowType() {
+            this.showType = this.showType === 'grid' ? 'row' : 'grid';
+            wx.pageScrollTo({
+                scrollTop: this.searchTop,
+                duration: 300
+            });
+        }
     },
     watch: {
         sort() {
+            wx.pageScrollTo({
+                scrollTop: this.searchTop,
+                duration: 300
+            });
             this.page = 1;
             this.getData();
+        },
+        filterInfo() {
+            if (this.filterQuery.pageType === 'vendor') {
+                this.categoryIds = this.filterInfo.categoryIds;
+                this.countries = this.filterInfo.countries;
+                this.enterpriseType = this.filterInfo.enterpriseType;
+                this.page = 1;
+                this.getData();
+            } else if (this.filterQuery.pageType === 'product') {
+                this.categoryIds = this.filterInfo.categoryIds;
+                this.countries = this.filterInfo.countries;
+                this.brands = this.filterInfo.brand;
+                this.tagIds = this.filterInfo.tagIds;
+                this.applicationField = this.filterInfo.applicationField;
+                this.page = 1;
+                this.getData();
+            }
         }
     }
 };

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
src/native/vant/tabs/index.wxss


+ 1 - 1
src/pages/Authorized.vue

@@ -81,7 +81,7 @@ export default {
 .btn-content {
     width: 240px;
     .van-button {
-        height: 40px;
+        height: 44px;
     }
 }
 </style>

+ 86 - 11
src/pages/Brand.vue

@@ -36,15 +36,45 @@
         </div>
         <div class="main" id="main">
             <van-sticky :container="main" :offset-top="71">
-                <filter-sort-bar>
-                    <span slot="filter1">类别</span>
-                    <span slot="filter2">地区</span>
-                    <span slot="filter3">企业类型</span>
+                <filter-sort-bar
+                    :sort="sort"
+                    :showType="showType"
+                    @showFilter="showFilter"
+                    @changeSort="changeSort"
+                    @changeShowType="changeShowType"
+                    pageType="vendor"
+                >
+                    <span slot="filter1">
+                        <product-category-filter
+                            size="small"
+                            v-model="categoryIds"
+                            @input="refreash"
+                        ></product-category-filter>
+                    </span>
+                    <span slot="filter2">
+                        <country-filter size="small" v-model="countries" @input="refreash"></country-filter>
+                    </span>
+                    <span slot="filter3">
+                        <enterprise-type-filter
+                            size="small"
+                            v-model="enterpriseType"
+                            @input="refreash"
+                        ></enterprise-type-filter>
+                    </span>
                 </filter-sort-bar>
             </van-sticky>
-            <sort-list :empty="empty" :loading="loading" :finish="finish">
-                <div class="item" v-for="item in list" :key="item.id">
-                    <vendor-row :info="item"></vendor-row>
+            <sort-list :empty="empty" :loading="loading" :finish="finish" top="71px">
+                <div>
+                    <div class="grid-list" v-if="showType === 'grid'">
+                        <div class="col-2" v-for="item in list" :key="item.id">
+                            <vendor-grid :info="item"></vendor-grid>
+                        </div>
+                    </div>
+                    <div v-if="showType === 'row'">
+                        <div class="item" v-for="item in list" :key="item.id">
+                            <vendor-row :info="item"></vendor-row>
+                        </div>
+                    </div>
                 </div>
             </sort-list>
         </div>
@@ -59,6 +89,10 @@ import VendorRow from '../components/vendor/Row';
 import SearchBar from '../components/bar/SearchBarWithValue';
 import FilterSortBar from '../components/bar/FilterSortBar';
 import SortList from '../components/SortList';
+import { EnterpriseType } from '../utils/appState';
+import EnterpriseTypeFilter from '../components/filter/EnterpriseType';
+import ProductCategoryFilter from '../components/filter/ProductCategory';
+import CountryFilter from '../components/filter/Country';
 export default {
     data() {
         return {
@@ -68,14 +102,33 @@ export default {
             vendors: [],
             url: '/vendorInfo/show',
             barTop: 0,
-            ratio: 0
+            ratio: 0,
+            categoryIds: '',
+            countries: '',
+            enterpriseType: '',
+            showType: 'row'
         };
     },
     computed: {
         listQuery() {
             return {
-                vendorSort: this.sort
+                vendorSort: this.sort,
+                categoryIds: this.categoryIds,
+                countries: this.countries,
+                enterpriseType: this.enterpriseType
+            };
+        },
+        filterQuery() {
+            return {
+                pageType: 'vendor',
+                categoryIds: this.categoryIds,
+                countries: this.countries,
+                enterpriseType: this.enterpriseType,
+                searchTop: this.searchTop
             };
+        },
+        enterpriseName() {
+            return this.enterpriseType ? EnterpriseType.get(this.enterpriseType) : '';
         }
     },
     mixins: [searchList],
@@ -106,8 +159,10 @@ export default {
             .exec();
     },
     onPageScroll(e) {
-        if (e.scrollTop <= this.barTop) {
+        if (e.scrollTop <= this.barTop && e.scrollTop > 0) {
             this.ratio = Math.ceil((e.scrollTop * 100) / this.barTop) / 100;
+        } else if (e.scrollTop <= 0) {
+            this.ratio = 0;
         } else {
             this.ratio = 1;
         }
@@ -124,7 +179,10 @@ export default {
         VendorRow,
         SearchBar,
         FilterSortBar,
-        SortList
+        SortList,
+        EnterpriseTypeFilter,
+        ProductCategoryFilter,
+        CountryFilter
     }
 };
 </script>
@@ -157,4 +215,21 @@ h1 {
 .item {
     padding: 6px 17px;
 }
+
+.grid-list {
+    display: flex;
+    padding: 6px 10px;
+    flex-wrap: wrap;
+    .col-2 {
+        width: 50%;
+        padding: 6px;
+        box-sizing: border-box;
+        .bg-white {
+            width: 100%;
+        }
+        .van-image {
+            height: 165px;
+        }
+    }
+}
 </style>

+ 43 - 14
src/pages/Classify.vue

@@ -16,26 +16,28 @@
 </config>
 <template>
     <div class="container">
-        <van-sticky>
+        <van-sticky :offset-top="0">
             <div class="navBar" :style="narStyle">
                 <div class="title">产品分类</div>
                 <van-search :value="search" shape="round" placeholder="搜索..." />
             </div>
         </van-sticky>
         <div class="content">
-            <div class="left">
-                <van-sticky offset-top="71">
-                    <van-sidebar
-                        :activeKey="activeKey"
-                        @change="activeKey = $event.detail"
-                        v-if="categories.length > 0"
-                    >
-                        <van-sidebar-item :title="getName(item)" :key="index" v-for="(item, index) in categories" />
-                    </van-sidebar>
+            <div class="left" id="left">
+                <van-sticky offset-top="71" :container="left">
+                    <div class="left-side">
+                        <van-sidebar
+                            :activeKey="activeKey"
+                            @change="activeKey = $event.detail"
+                            v-if="categories.length > 0"
+                        >
+                            <van-sidebar-item :title="getName(item)" :key="index" v-for="(item, index) in categories" />
+                        </van-sidebar>
+                    </div>
                 </van-sticky>
             </div>
             <div class="right">
-                <div class="top">
+                <div class="top" @click="navigateTo('/pages/ProductList?categoryIds=' + firstLevelId)">
                     <van-image
                         src="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/quanqiu_img_jixie.jpg"
                         fit="widthFix"
@@ -47,9 +49,15 @@
                     </div>
                 </div>
 
-                <van-button radius="4" type="default" block v-for="item in nowCategory.children" :key="item.id">{{
-                    getName(item)
-                }}</van-button>
+                <van-button
+                    radius="4"
+                    type="default"
+                    block
+                    v-for="item in nowCategory.children"
+                    :key="item.id"
+                    @click="navigateTo('/pages/ProductList?categoryIds=' + item.id)"
+                    >{{ getName(item) }}</van-button
+                >
             </div>
         </div>
     </div>
@@ -78,6 +86,13 @@ export default {
         },
         nowCategory() {
             return { ...(this.getList([...this.categories], this.activeKey) || { children: [] }) };
+        },
+        firstLevelId() {
+            if (this.categories.length > this.activeKey) {
+                return [...this.categories][this.activeKey].id;
+            } else {
+                return '';
+            }
         }
     },
     onShow() {
@@ -93,6 +108,9 @@ export default {
             .catch(e => {
                 console.log(e);
             });
+    },
+    onReady() {
+        this.left = wx.createSelectorQuery().select('#left');
     }
 };
 </script>
@@ -117,6 +135,7 @@ export default {
     min-height: 100vh;
     display: flex;
     flex-direction: column;
+    padding-top: 71px;
     .content {
         flex-grow: 1;
 
@@ -131,6 +150,10 @@ export default {
                 width: 140px;
                 height: calc(100vh - 71px);
             }
+
+            .left-side {
+                width: 140px;
+            }
         }
     }
 }
@@ -201,4 +224,10 @@ h3 {
         width: 100%;
     }
 }
+
+#left {
+    .van-sticky-wrap {
+        width: 140px;
+    }
+}
 </style>

+ 88 - 6
src/pages/FilterPage.vue

@@ -5,10 +5,22 @@
 </config>
 <template>
     <div>
-        <product-category-filter v-model="categoryIds"></product-category-filter>
+        <product-category-filter v-model="categoryIds" :firstCategory="firstCategory"></product-category-filter>
         <country v-model="countries"></country>
-        <product-tags v-model="tagIds"></product-tags>
-        <application v-model="applicationField"></application>
+        <product-tags v-model="tagIds" v-if="pageType === 'product'"></product-tags>
+        <enterprise-type v-model="enterpriseType" v-if="pageType === 'vendor'"></enterprise-type>
+        <application v-model="applicationField" v-if="pageType === 'product'"></application>
+
+        <div class="fixed-bottom">
+            <div class="btn-list">
+                <div class="btn-block">
+                    <van-button type="default" block @click="restart">重置</van-button>
+                </div>
+                <div class="btn-block">
+                    <van-button :color="$colors.warn" @click="submit" block>确定</van-button>
+                </div>
+            </div>
+        </div>
     </div>
 </template>
 <script>
@@ -16,6 +28,7 @@ import ProductCategoryFilter from '../components/filter/ProductCategory';
 import Country from '../components/filter/Country';
 import ProductTags from '../components/filter/ProductTags';
 import Application from '../components/filter/Application';
+import EnterpriseType from '../components/filter/EnterpriseType';
 export default {
     data() {
         return {
@@ -24,15 +37,84 @@ export default {
             countries: '',
             brand: '',
             tagIds: '',
-            applicationField: ''
+            applicationField: '',
+            enterpriseType: '',
+            firstCategory: ''
         };
     },
-    onShow() {},
+    onShow() {
+        this.pageType = this.$mp.options.pageType;
+        if (this.$mp.options.pageType === 'vendor') {
+            this.categoryIds = this.$mp.options.categoryIds;
+            this.countries = this.$mp.options.countries;
+            this.enterpriseType = this.$mp.options.enterpriseType;
+        } else if (this.$mp.options.pageType === 'product') {
+            this.categoryIds = this.$mp.options.categoryIds;
+            this.countries = this.$mp.options.countries;
+            this.firstCategory = this.$mp.options.firstCategory;
+            this.tagIds = this.$mp.options.tagIds;
+            this.applicationField = this.$mp.options.applicationField;
+        }
+    },
     components: {
         ProductCategoryFilter,
         Country,
         ProductTags,
-        Application
+        Application,
+        EnterpriseType
+    },
+    methods: {
+        restart() {
+            this.categoryIds = '';
+            this.countries = '';
+            this.brand = '';
+            this.tagIds = '';
+            this.applicationField = '';
+            this.enterpriseType = '';
+        },
+        submit() {
+            this.$store.commit('setFilterInfo', {
+                categoryIds: this.categoryIds,
+                countries: this.countries,
+                brand: this.brand,
+                tagIds: this.tagIds,
+                applicationField: this.applicationField,
+                enterpriseType: this.enterpriseType
+            });
+            wx.navigateBack({
+                success: () => {
+                    wx.pageScrollTo({
+                        scrollTop: this.$mp.options.searchTop,
+                        duration: 300
+                    });
+                }
+            });
+        }
     }
 };
 </script>
+<style lang="less">
+.fixed-bottom {
+    height: 60px;
+}
+
+.btn-list {
+    display: flex;
+    height: 60px;
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    align-items: center;
+    padding: 0 8px;
+    box-shadow: 0px -1px 2px 0px rgba(0, 0, 0, 0.04);
+    background-color: #fff;
+    .btn-block {
+        flex-grow: 1;
+        margin: 0 6px;
+        .van-button {
+            height: 40px;
+        }
+    }
+}
+</style>

+ 4 - 0
src/pages/Home.vue

@@ -58,16 +58,19 @@
                     content-class="menu-info"
                     icon="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/home_icon_quanqiu.png"
                     :text="$t('quan-qiu-chan-pin')"
+                    @click="navigateTo('/pages/Product', false)"
                 />
                 <van-grid-item
                     content-class="menu-info"
                     icon="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/home_icon_imt.png"
                     :text="$t('imt-ping-tai')"
+                    @click="navigateTo('/pages/imt/Index', false)"
                 />
                 <van-grid-item
                     content-class="menu-info"
                     icon="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/home_icon_xinwen.png"
                     :text="$t('xin-wen-zi-xun')"
+                    @click="navigateTo('/pages/news/News', false)"
                 />
             </van-grid>
 
@@ -436,6 +439,7 @@ export default {
 .hot {
     .van-tabs__line {
         bottom: 5px;
+        left: 7.5px;
     }
 }
 

+ 13 - 14
src/pages/My.vue

@@ -118,8 +118,8 @@ export default {
     computed: {
         ...mapState(['userInfo']),
         icon() {
-            return this.userInfo
-                ? this.userInfo.avater
+            return this.userInfo && this.userInfo.avatar
+                ? this.userInfo.avatar
                 : 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/info_img_touxiang_01.png';
         },
         name() {
@@ -149,18 +149,17 @@ export default {
         login(e) {
             console.log(e);
             if (e.detail.iv) {
-                this.showPhone = true;
-                // this.$http
-                //     .post('/user/getMaUserInfo', {
-                //         sessionKey: this.$store.state.sessionKey,
-                //         rawData: e.detail.rawData,
-                //         signature: e.detail.signature,
-                //         encryptedData: e.detail.encryptedData,
-                //         iv: e.detail.iv
-                //     })
-                //     .then(() => {
-                //         this.showPhone = true;
-                //     });
+                this.$http
+                    .post('/user/getMaUserInfo', {
+                        sessionKey: this.$store.state.sessionKey,
+                        rawData: e.detail.rawData,
+                        signature: e.detail.signature,
+                        encryptedData: e.detail.encryptedData,
+                        iv: e.detail.iv
+                    })
+                    .then(() => {
+                        this.showPhone = true;
+                    });
             }
         }
     }

+ 149 - 0
src/pages/News.vue

@@ -0,0 +1,149 @@
+<config>
+{
+'navigationBarTitleText': '',
+'navigationStyle':'custom',
+'navigationBarTextStyle':'white',
+'backgroundColorTop': '#fff',
+'backgroundColorBottom': '#f5f7fa',
+'enablePullDownRefresh':false
+}
+</config>
+<template>
+    <div>
+        <custom-bar :ratio="ratio" :pre="0" :title="title"></custom-bar>
+        <banner :banners="banners" fixed :height="140" :radius="0" :scrollTop="scrollTop"></banner>
+        <div class="main" id="main">
+            <van-sticky :offset-top="71" :z-index="100" :container="main">
+                <div class="tab-content">
+                    <van-tabs
+                        :active="hotActive"
+                        @change="changeTab($event.detail.index)"
+                        :ellipsis="false"
+                        :line-width="24"
+                        :line-height="2"
+                    >
+                        <van-tab :title="item.name" v-for="item in informations" :key="item.key"></van-tab>
+                    </van-tabs>
+                </div>
+            </van-sticky>
+
+            <sort-list :empty="empty" :loading="loading" :finish="finish" top="115px + 172rpx">
+                <div class="list">
+                    <template v-if="pageType === 'bigImg'">
+                        <block v-for="item in list" :key="item.id">
+                            <news-grid :info="item"></news-grid>
+                        </block>
+                    </template>
+                    <template v-if="pageType === 'default'">
+                        <block v-for="item in list" :key="item.id">
+                            <news-row :info="item"></news-row>
+                        </block>
+                    </template>
+                </div>
+            </sort-list>
+        </div>
+    </div>
+</template>
+<script>
+import Banner from '../components/Banner.vue';
+import CustomBar from '../components/bar/CustomBar.vue';
+import { getBanner } from '../utils/commont';
+import { InformationType } from '../utils/appState';
+import searchList from '../mixins/searchList';
+import SortList from '../components/SortList.vue';
+import NewsGrid from '../components/News/Grid.vue';
+import NewsRow from '../components/News/Row.vue';
+export default {
+    components: { Banner, CustomBar, SortList, NewsGrid, NewsRow },
+    data() {
+        return {
+            banners: [],
+            ratio: 0,
+            hotActive: 0,
+            main: null,
+            url: '/information/typeList',
+            httpType: 'get',
+            barTop: 0,
+            noPage: true,
+            scrollTop: 0
+        };
+    },
+    mixins: [searchList],
+    computed: {
+        informations() {
+            return [...InformationType].map(item => {
+                return {
+                    key: item[0],
+                    name: this.$t(item[1].name),
+                    type: item[1].type || 'default'
+                };
+            });
+        },
+        listQuery() {
+            return {
+                type: [...this.informations][this.hotActive].key
+            };
+        },
+        pageType() {
+            return [...this.informations][this.hotActive].type;
+        },
+        title() {
+            return this.$t([...this.informations][this.hotActive].name);
+        }
+    },
+    onLoad() {
+        this.changeTab(0, true);
+    },
+    methods: {
+        changeTab(index, first = false) {
+            this.hotActive = index;
+            getBanner([...this.informations][index].key).then(res => {
+                this.banners = res;
+            });
+
+            this.$nextTick(() => {
+                if (first) {
+                    this.getData();
+                } else {
+                    this.refreash();
+                }
+            });
+        }
+    },
+    onPageScroll() {},
+    onReady() {
+        this.main = wx.createSelectorQuery().select('#main');
+        this.main
+            .boundingClientRect(rect => {
+                this.searchTop = rect.top - 61;
+                this.barTop = rect.top - 71;
+            })
+            .exec();
+    }
+};
+</script>
+<style lang="less" scoped>
+.list {
+    padding: 16px;
+    .news + .news {
+        margin-top: 16px;
+    }
+}
+</style>
+<style lang="less">
+.tab-content {
+    .van-tabs__scroll {
+        .van-tab {
+            color: #292c33;
+            &.van-tab--active {
+                color: @warn;
+            }
+        }
+
+        .van-tabs__line {
+            bottom: 8px;
+            left: 7.5px;
+        }
+    }
+}
+</style>

+ 215 - 0
src/pages/Product.vue

@@ -0,0 +1,215 @@
+<config>
+{
+'navigationBarTitleText': '全球产品',
+'backgroundColorTop': '#0F264D',
+'backgroundColorBottom': '#F5F7FA',
+'navigationBarTextStyle':'white',
+'navigationBarBackgroundColor':'#0F264D',
+}
+</config>
+<template>
+    <div>
+        <div class="top">
+            <van-sticky :offset-top="0" z-index="100">
+                <div class="tab-content" v-if="firstLevels.length > 0">
+                    <van-tabs
+                        :active="hotActive"
+                        @change="hotActive = $event.detail.index"
+                        :ellipsis="false"
+                        :line-width="24"
+                        :line-height="2"
+                    >
+                        <van-tab :title="getName(item)" v-for="item in firstLevels" :key="item.id"></van-tab>
+                    </van-tabs>
+                </div>
+            </van-sticky>
+        </div>
+
+        <div class="banner-box">
+            <banner :banners="banners" :height="180"></banner>
+        </div>
+        <div class="main" id="main">
+            <van-sticky :container="main" :offset-top="44">
+                <filter-sort-bar
+                    :sort="sort"
+                    :showType="showType"
+                    @showFilter="showFilter"
+                    @changeSort="changeSort"
+                    @changeShowType="changeShowType"
+                >
+                    <span slot="filter1">
+                        <product-category-filter
+                            size="small"
+                            v-model="categoryIds"
+                            @input="refreash"
+                            :firstCategory="defaultCategoryId"
+                        ></product-category-filter>
+                    </span>
+                    <span slot="filter2">
+                        <country-filter size="small" v-model="countries" @input="refreash"></country-filter>
+                    </span>
+                    <span slot="filter3">
+                        <product-tags-filter size="small" v-model="tagIds" @input="refreash"></product-tags-filter>
+                    </span>
+                </filter-sort-bar>
+            </van-sticky>
+
+            <sort-list :empty="empty" :loading="loading" :finish="finish" top="44px">
+                <div class="product-list" v-if="showType === 'grid'">
+                    <div class="clo-2" v-for="item in list" :key="item.id">
+                        <product-grid :info="item"></product-grid>
+                    </div>
+                </div>
+            </sort-list>
+        </div>
+    </div>
+</template>
+<script>
+import Banner from '../components/Banner';
+import { getBanner } from '../utils/commont';
+import searchList from '../mixins/searchList';
+import FilterSortBar from '../components/bar/FilterSortBar';
+import SortList from '../components/SortList';
+import ProductGrid from '../components/product/GridNormal';
+import ProductTagsFilter from '../components/filter/ProductTags';
+import ProductCategoryFilter from '../components/filter/ProductCategory';
+import CountryFilter from '../components/filter/Country';
+export default {
+    data() {
+        return {
+            hotActive: 0,
+            banners: [],
+            categoryIds: '',
+            countries: '',
+            brands: '',
+            url: '/product/show',
+            tagIds: '',
+            applicationField: '',
+            main: null
+        };
+    },
+    mixins: [searchList],
+    computed: {
+        firstLevels() {
+            const list = [...this.productCategories];
+            return list.filter(item => {
+                return !item.parentId;
+            });
+        },
+        listQuery() {
+            return {
+                productSort: this.sort,
+                categoryIds: this.categoryIds || this.defaultCategoryId,
+                countries: this.countries,
+                tagIds: this.tagIds,
+                applicationField: this.applicationField
+            };
+        },
+        filterQuery() {
+            return {
+                pageType: 'product',
+                firstCategory: this.defaultCategoryId,
+                categoryIds: this.categoryIds,
+                countries: this.countries,
+                searchTop: this.searchTop,
+                tagIds: this.tagIds,
+                applicationField: this.applicationField
+            };
+        },
+        defaultCategoryId() {
+            const firstLevel = [...this.firstLevels];
+            if (firstLevel.length > 0) {
+                return firstLevel[this.hotActive].id;
+            } else {
+                return '';
+            }
+        }
+    },
+    onLoad() {
+        if (this.productCategories.length === 0) {
+            this.$store.dispatch('getProductCategories').then(res => {
+                this.$nextTick(() => {
+                    this.getData();
+                });
+            });
+        } else {
+            this.$nextTick(() => {
+                this.getData();
+            });
+        }
+
+        getBanner('PRODUCT').then(res => {
+            this.banners = res;
+        });
+    },
+    onReady() {
+        this.main = wx.createSelectorQuery().select('#main');
+        this.main
+            .boundingClientRect(rect => {
+                this.searchTop = rect.top - 44;
+            })
+            .exec();
+    },
+    onReachBottom() {
+        if (!this.loading && !this.finish) {
+            this.page++;
+            this.getData();
+        }
+    },
+    components: {
+        Banner,
+        FilterSortBar,
+        SortList,
+        ProductGrid,
+        ProductTagsFilter,
+        ProductCategoryFilter,
+        CountryFilter
+    },
+    watch: {
+        defaultCategoryId() {
+            this.categoryIds = '';
+            this.$nextTick(() => {
+                this.refreash();
+            });
+        }
+    }
+};
+</script>
+
+<style lang="less">
+.tab-content {
+    background: @prim;
+    .van-tabs__scroll {
+        background: @prim;
+        .van-tab {
+            color: #fff;
+            &.van-tab--active {
+                color: @warn;
+            }
+        }
+
+        .van-tabs__line {
+            bottom: 8px;
+            left: 7.5px;
+        }
+    }
+}
+
+.banner-box {
+    padding: 16px 16px 4px;
+}
+.top {
+    height: 44px;
+}
+
+.product-list {
+    display: flex;
+    flex-wrap: wrap;
+    padding: 0 10px;
+    .clo-2 {
+        width: 50%;
+        padding: 6px;
+        box-sizing: border-box;
+    }
+}
+</style>

+ 179 - 0
src/pages/ProductList.vue

@@ -0,0 +1,179 @@
+<config>
+{
+'navigationBarTitleText': '',
+'navigationStyle':'custom',
+'navigationBarTextStyle':'black',
+'backgroundColorBottom': '#F5F7FA',
+'backgroundColorTop': '#fff',
+}
+</config>
+<template>
+    <div>
+        <div style="height:71px">
+            <search-bar v-model="searchKey" :dark="false" :ratio="ratio" @search="submitSearch"></search-bar>
+        </div>
+        <div class="main" id="main">
+            <van-sticky :container="main" :offset-top="71">
+                <filter-sort-bar
+                    :sort="sort"
+                    :showType="showType"
+                    @showFilter="showFilter"
+                    @changeSort="changeSort"
+                    @changeShowType="changeShowType"
+                >
+                    <span slot="filter1">
+                        <product-category-filter
+                            size="small"
+                            v-model="categoryIds"
+                            @input="refreash"
+                        ></product-category-filter>
+                    </span>
+                    <span slot="filter2">
+                        <country-filter size="small" v-model="countries" @input="refreash"></country-filter>
+                    </span>
+                    <span slot="filter3">
+                        <product-tags-filter size="small" v-model="tagIds" @input="refreash"></product-tags-filter>
+                    </span>
+                </filter-sort-bar>
+            </van-sticky>
+
+            <sort-list :empty="empty" :loading="loading" :finish="finish" top="71px">
+                <div class="product-list" v-if="showType === 'grid'">
+                    <div class="clo-2" v-for="item in list" :key="item.id">
+                        <product-grid :info="item"></product-grid>
+                    </div>
+                </div>
+            </sort-list>
+        </div>
+    </div>
+</template>
+<script>
+import SearchBar from '../components/bar/SearchBarWithValue';
+import searchList from '../mixins/searchList';
+import FilterSortBar from '../components/bar/FilterSortBar';
+import SortList from '../components/SortList';
+import ProductGrid from '../components/product/GridNormal';
+import ProductTagsFilter from '../components/filter/ProductTags';
+import ProductCategoryFilter from '../components/filter/ProductCategory';
+import CountryFilter from '../components/filter/Country';
+export default {
+    data() {
+        return {
+            banners: [],
+            categoryIds: '',
+            countries: '',
+            brands: '',
+            url: '/product/show',
+            tagIds: '',
+            applicationField: '',
+            main: null,
+            ratio: 1
+        };
+    },
+    mixins: [searchList],
+    computed: {
+        firstLevels() {
+            const list = [...this.productCategories];
+            return list.filter(item => {
+                return !item.parentId;
+            });
+        },
+        listQuery() {
+            return {
+                productSort: this.sort,
+                categoryIds: this.categoryIds || '',
+                countries: this.countries,
+                tagIds: this.tagIds,
+                applicationField: this.applicationField
+            };
+        },
+        filterQuery() {
+            return {
+                pageType: 'product',
+                firstCategory: this.defaultCategoryId,
+                categoryIds: this.categoryIds,
+                countries: this.countries,
+                searchTop: this.searchTop,
+                tagIds: this.tagIds,
+                applicationField: this.applicationField
+            };
+        }
+    },
+    onLoad(options) {
+        console.log(options);
+        if (options.categoryIds) {
+            this.categoryIds = options.categoryIds;
+            this.getData();
+        }
+    },
+    onReady() {
+        this.main = wx.createSelectorQuery().select('#main');
+        this.main
+            .boundingClientRect(rect => {
+                this.searchTop = rect.top;
+            })
+            .exec();
+    },
+    onReachBottom() {
+        if (!this.loading && !this.finish) {
+            this.page++;
+            this.getData();
+        }
+    },
+    components: {
+        FilterSortBar,
+        SortList,
+        ProductGrid,
+        ProductTagsFilter,
+        ProductCategoryFilter,
+        CountryFilter,
+        SearchBar
+    },
+    watch: {
+        defaultCategoryId() {
+            this.categoryIds = '';
+            this.$nextTick(() => {
+                this.refreash();
+            });
+        }
+    }
+};
+</script>
+
+<style lang="less">
+.tab-content {
+    background: @prim;
+    .van-tabs__scroll {
+        background: @prim;
+        .van-tab {
+            color: #fff;
+            &.van-tab--active {
+                color: @warn;
+            }
+        }
+
+        .van-tabs__line {
+            bottom: 8px;
+            left: 7.5px;
+        }
+    }
+}
+
+.banner-box {
+    padding: 16px 16px 4px;
+}
+.top {
+    height: 44px;
+}
+
+.product-list {
+    display: flex;
+    flex-wrap: wrap;
+    padding: 0 10px;
+    .clo-2 {
+        width: 50%;
+        padding: 6px;
+        box-sizing: border-box;
+    }
+}
+</style>

+ 84 - 0
src/pages/imt/Advantage.vue

@@ -0,0 +1,84 @@
+<template>
+    <div class="advantages">
+        <block v-for="(item, index) in advantages" :key="index">
+            <div class="advantage-item">
+                <van-image :src="item.img" fit="widthFix" />
+
+                <div class="advantage-box">
+                    <van-image :src="item.icon" :width="90" :height="90" />
+                    <div class="text" v-html="item.name"></div>
+                </div>
+            </div>
+        </block>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            advantages: [
+                {
+                    img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_youshi_img_01.jpg',
+                    icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_youshi_icon_02.png',
+                    name:
+                        '强大的行业集聚性贸易服务平台<br/>专业、专项、专注<br/>充分利用自贸区国际贸易便利化优势<br/>为智能制造产业客户提供更大的灵活性和实效性优势'
+                },
+                {
+                    img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_youshi_img_02.jpg',
+                    icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_youshi_icon_04.png',
+                    name: '庞大的专业客户集群'
+                },
+                {
+                    img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_youshi_img_03.jpg',
+                    icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_youshi_icon_01.png',
+                    name: '惠享自贸区贸易、财政、先试先行政策,为企业在该区域开展相关业务给予直接的政策支撑'
+                },
+                {
+                    img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_youshi_img_04.jpg',
+                    icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_youshi_icon_05.png',
+                    name: '丰富的行业交流、政企交流活动'
+                },
+
+                {
+                    img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_youshi_img_05.jpg',
+                    icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_youshi_icon_03.png',
+                    name: '与各国行业协会建立长期合作关系<br/>发展“中国智造”'
+                }
+            ]
+        };
+    },
+    onShow() {}
+};
+</script>
+<style lang="less">
+.advantage-item {
+    position: relative;
+    .advantage-box {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 0 50px;
+        .text {
+            font-size: 14px;
+            color: #ffffff;
+            line-height: 24px;
+            margin-top: 20px;
+            text-align: center;
+        }
+    }
+}
+
+.advantage-item + .advantage-item {
+    margin-top: 16px;
+}
+
+.advantages {
+    padding: 16px;
+}
+</style>

+ 82 - 0
src/pages/imt/Connect.vue

@@ -0,0 +1,82 @@
+<template>
+    <div class="connect">
+        <map
+            id="myMap"
+            style="width: 100%; height: 300px;"
+            latitude="31.298919"
+            longitude="121.629521"
+            :markers="markers"
+            scale="18"
+        >
+        </map>
+
+        <div class="connect-box">
+            <div class="connect-info">
+                <van-icon name="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/footer_icon_dianhua.png" :size="20" />
+                <h3 class="fontNormal">025-8686-8686</h3>
+            </div>
+            <div class="connect-info">
+                <van-icon name="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/footer_icon_dianhua.png" :size="20" />
+                <h3 class="fontNormal">imt86881@163.com</h3>
+            </div>
+            <div class="connect-info">
+                <van-icon name="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/footer_icon_dianhua.png" :size="20" />
+                <h3 class="fontNormal">中国(上海)自由贸易试验区富特东三路526号</h3>
+            </div>
+            <div class="btn">
+                <van-button :color="$colors.warn" block :radius="4" @click="takePhone">联系我们</van-button>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            markers: [
+                {
+                    id: 1,
+                    latitude: 31.298919,
+                    longitude: 121.629521,
+                    iconPath: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/icon_dingwei.png',
+                    width: 24,
+                    height: 30
+                }
+            ]
+        };
+    },
+    methods: {
+        takePhone() {
+            wx.makePhoneCall({
+                phoneNumber: '025-86868686' //仅为示例,并非真实的电话号码
+            });
+        }
+    }
+};
+</script>
+
+<style lang="less">
+.connect-box {
+    background: #ffffff;
+    box-shadow: 0px 4px 6px 0px rgba(0, 0, 0, 0.04);
+    margin: 0 16px;
+    transform: translateY(-53px);
+    padding: 24px 10px;
+
+    .connect-info {
+        display: flex;
+        align-items: center;
+    }
+    .connect-info + .connect-info {
+        margin-top: 18px;
+    }
+
+    .btn {
+        margin: 24px 40px 0;
+        .van-button {
+            height: 44px;
+            font-size: 15px;
+        }
+    }
+}
+</style>

+ 281 - 0
src/pages/imt/Index.vue

@@ -0,0 +1,281 @@
+<config>
+{
+'navigationBarTitleText': '',
+'navigationBarTextStyle':'white',
+'backgroundColorBottom': '#fff',
+'navigationStyle':'custom',
+}
+</config>
+<template>
+    <div class="imt">
+        <custom-bar title="IMT平台" :pre="0" :fixed="false"></custom-bar>
+
+        <template v-if="active === 0">
+            <div class="banner">
+                <banner :banners="banners" fixed :height="300" :radius="0" :scrollTop="scrollTop"></banner>
+            </div>
+
+            <div class="main" id="main">
+                <div class="thirdbtn">
+                    <img src="../../static/imgs/imt_topbanner_icon_3d.png" alt="" />
+                    <div class="text">
+                        <h4>点击观看 IMT 3D展厅</h4>
+                    </div>
+                </div>
+
+                <div class="introduce">
+                    <Title>
+                        <template slot="name">
+                            IMT·<span :style="`color:${$colors.warn}`">科技平台</span>
+                        </template>
+                        <template slot="sub"
+                            >智能制造产业链生态系统</template
+                        >
+                    </Title>
+
+                    <div class="p1">
+                        IMT科技平台,是外高桥智能制造服务产业园(IMT)推出的在线贸易服务平台,依托IMT行业高度集聚性、高度专业化的优势,引进全球制造业高精密机械设备及先进技术,打破物理空间局限性,拓宽功能服务,构建活跃的智能制造生态圈,使企业在资源整合的生态中共同发展。从设备供应商到采购商,从国外工厂到国内用户,实现智能制造产业链各企业间
+                        “纵向+横向”的信息集成,为制造商、经销商、买家和服务商之间开展国际和国内贸易拓宽渠道、消除壁垒。
+                    </div>
+
+                    <div class="introduce-img">
+                        <div class="introduce-img-item">
+                            <div class="img-box">
+                                <img src="../../static/imgs/imt_gaikuang_icon_01.png" alt="" />
+                            </div>
+                            <div class="text">高度集聚性</div>
+                        </div>
+                        <div class="introduce-img-item">
+                            <div class="img-box">
+                                <img src="../../static/imgs/imt_gaikuang_icon_02.png" alt="" />
+                            </div>
+                            <div class="text">高精密产品/技术</div>
+                        </div>
+                        <div class="introduce-img-item">
+                            <div class="img-box">
+                                <img src="../../static/imgs/imt_gaikuang_icon_03.png" alt="" />
+                            </div>
+                            <div class="text">高度专业化</div>
+                        </div>
+                    </div>
+                </div>
+                <div class="core-box">
+                    <block v-for="(item, index) in modulars" :key="index">
+                        <Core :info="item"></Core>
+                    </block>
+                </div>
+            </div>
+        </template>
+
+        <advantage v-if="active === 1"></advantage>
+
+        <service v-if="active === 2"></service>
+
+        <connect v-if="active === 3"></connect>
+
+        <bottom v-model="active" v-if="showBottom"></bottom>
+    </div>
+</template>
+<script>
+import Banner from '../../components/Banner';
+import CustomBar from '../../components/bar/CustomBar';
+import Title from '../../components/imt/Title';
+import Core from '../../components/imt/Core';
+import Bottom from '../../components/imt/Bottom';
+import Advantage from './Advantage';
+import Service from './Service';
+import Connect from './Connect';
+export default {
+    data() {
+        return {
+            barTop: 100,
+            ratio: 0,
+            showBottom: false,
+            scrollTop: 0,
+            banners: [
+                {
+                    img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_top_banner.jpg'
+                }
+            ],
+            modulars: [
+                {
+                    imgs: [
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_01_a.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_01_b.jpg'
+                    ],
+                    title: '高端的服务定位',
+                    sub: '打造功能集成的智能制造服务产业平台',
+                    content:
+                        '外高桥智能制造服务产业园(IMT),坐落于中国(上海)自由贸易试验区,是一个服务模式、服务能级全面创新升级,针对高端智能制造行业的国际贸易便利化和专业化服务平台。'
+                },
+                {
+                    imgs: [
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_02_a.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_02_b.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_02_c.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_02_d.jpg'
+                    ],
+                    title: '成熟的运营模式',
+                    sub: '集聚性、专业化、便利化',
+                    content:
+                        '产业园针对进口各种高精端加工及检验检测等设备,已形成集中的设备展示中心、仓储分拨中心、维修中心及检测中心,为客户提供保税展示与演示、展品物流、零部件分拨、贸易代理、仓储管理、物业租赁、检测认证、专业培训、技术交流等服务。'
+                },
+                {
+                    imgs: [
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_03_a.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_03_b.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_03_c.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_03_d.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_03_e.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_03_f.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_03_g.jpg'
+                    ],
+                    title: '顶级机床及设备',
+                    sub: '高精密、智能化',
+                    content: '集聚了国际领先的精密数控机床、机床工具、智能机器人、3D 打印、高精密检测设备等企业入驻。'
+                },
+                {
+                    imgs: [
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_04_a.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_04_b.jpg'
+                    ],
+                    title: '行业协会、专业机构',
+                    sub: '国际化、专业化',
+                    content:
+                        '我们与国际化的行业协会和专业的服务机构合作,包括上海瑞士中心、美国机床协会、德国机械设备制造业联合会、机械工业机床产品质量检测中心、上海浦东智能制造协会等,共同为客户提专业、权威的综合服务。'
+                },
+                {
+                    imgs: [
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_05_a.jpg',
+                        'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_hexin_img_05_b.jpg'
+                    ],
+                    title: '特色平台',
+                    sub: '权威、专业',
+                    content:
+                        '瞄准科技前沿和高端产业,上海集中推出26个面积在3至5平方公里的特色产业园区,我们被评选为智能制造板块8个特色园区之一,将在上海市经信委智能制造产业推进处的专业指导下全力打造智能制造产业发展新高地。<br/>凭借着一直坚持为客户提供的长短结合的展示推广服务经验,我们获批成为中国国际进口博览会智能及高端设备板块中唯一“6天+365天”常年展示交易平台。'
+                }
+            ],
+            active: 0
+        };
+    },
+    onLoad() {
+        setTimeout(() => {
+            this.showBottom = true;
+        }, 1000);
+    },
+    components: {
+        Banner,
+        Title,
+        Core,
+        Bottom,
+        CustomBar,
+        Service,
+        Advantage,
+        Connect
+    },
+    onPageScroll(e) {}
+};
+</script>
+
+<style lang="less" scoped>
+.imt {
+    position: relative;
+}
+.banner {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    z-index: 1;
+}
+.main {
+    z-index: 2;
+    position: relative;
+}
+.thirdbtn {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding-top: 10px;
+    img {
+        width: 80px;
+        height: 80px;
+    }
+
+    .text {
+        padding: 6px 12px;
+        position: relative;
+        h4 {
+            color: #61edff;
+            position: relative;
+            z-index: 2;
+            line-height: 17px;
+        }
+
+        &::after {
+            content: '';
+            position: absolute;
+            top: 0;
+            left: 0;
+            right: 0;
+            bottom: 0;
+            background: rgba(0, 0, 0, 0.4);
+            z-index: 1;
+            transform: skewX(-10deg);
+        }
+    }
+}
+
+.introduce {
+    background: #ffffff;
+    border-radius: 4px;
+    margin: 16px 33px 0;
+    padding: 30px 12px;
+
+    .p1 {
+        font-size: 14px;
+        color: #000000;
+        line-height: 24px;
+        padding: 20px 0;
+    }
+
+    .introduce-img {
+        display: flex;
+        justify-content: space-between;
+        margin-top: 20px;
+        .introduce-img-item {
+            // flex-grow: 1;
+            padding: 0 8px;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            .text {
+                font-size: 13px;
+                font-weight: bold;
+                color: #ffa526;
+                line-height: 18px;
+                margin-top: 9px;
+                white-space: nowrap;
+            }
+
+            .img-box {
+                width: 80px;
+                height: 80px;
+                background: rgba(255, 165, 38, 0.12);
+                border-radius: 4px;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                img {
+                    width: 44px;
+                    height: 44px;
+                }
+            }
+        }
+    }
+}
+
+.core-box {
+    padding: 30px 16px;
+}
+</style>

+ 55 - 0
src/pages/imt/Service.vue

@@ -0,0 +1,55 @@
+<template>
+    <div class="services">
+        <div
+            class="service-item"
+            v-for="(item, index) in services"
+            :key="index"
+            @click="navigateTo('/pages/imt/ServiceDetail?name=' + item.name, false)"
+        >
+            <van-icon :name="item.icon" :size="50" />
+            <div class="servce-info">
+                <h2>{{ item.name }}</h2>
+                <p>{{ item.sub }}</p>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+import { services } from '../../utils/imtPageInfo';
+export default {
+    computed: {
+        services() {
+            return [...services].map(item => {
+                return {
+                    icon: item.icon,
+                    name: item.name,
+                    sub: item.sub
+                };
+            });
+        }
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.services {
+    background: #f5f7fa;
+    padding: 12px 16px;
+}
+.service-item {
+    display: flex;
+    background-color: #fff;
+    padding: 23px 14px;
+    border-radius: 4px;
+    .servce-info {
+        margin-left: 10px;
+    }
+
+    &:active {
+        background-color: darken(#ffffff, 10);
+    }
+}
+.service-item + .service-item {
+    margin-top: 12px;
+}
+</style>

+ 184 - 0
src/pages/imt/ServiceDetail.vue

@@ -0,0 +1,184 @@
+<config>
+{
+'navigationBarTitleText': '',
+}
+</config>
+<template>
+    <div class="service">
+        <div class="info" v-if="serviceInfo">
+            <van-icon :name="serviceInfo.icon" :size="50" />
+            <h2>{{ serviceInfo.name }}</h2>
+            <p class="font14">{{ serviceInfo.content }}</p>
+        </div>
+
+        <div class="case" v-if="cases">
+            <div class="btn-list">
+                <div
+                    class="btn"
+                    @click="active = index"
+                    :class="{ active: index === active }"
+                    v-for="(item, index) in cases"
+                    :key="index"
+                >
+                    案例 {{ index + 1 }}
+                </div>
+            </div>
+
+            <banner :banners="banners" right :height="192"></banner>
+            <h2>{{ caseInfo.name }}</h2>
+
+            <p>{{ caseInfo.content }}</p>
+        </div>
+
+        <div class="case" v-if="!cases">
+            <van-empty
+                image="http://imt.oss-cn-hangzhou.aliyuncs.com/micro/kong_img_default.png"
+                description="暂无案例展示"
+            >
+            </van-empty>
+        </div>
+    </div>
+</template>
+<script>
+import { services } from '../../utils/imtPageInfo';
+import Banner from '../../components/Banner';
+export default {
+    data() {
+        return {
+            serviceName: '',
+            active: 0
+        };
+    },
+    computed: {
+        serviceInfo() {
+            return [...services].find(item => {
+                return item.name === this.serviceName;
+            });
+        },
+        cases() {
+            if (this.serviceInfo && this.serviceInfo.cases) {
+                return this.serviceInfo.cases;
+            } else {
+                return null;
+            }
+        },
+        caseInfo() {
+            if (this.cases) {
+                return [...this.cases][this.active];
+            }
+            return null;
+        },
+        banners() {
+            if (this.caseInfo) {
+                return [...this.caseInfo.imgs].map(item => {
+                    return { img: item };
+                });
+            } else {
+                return [];
+            }
+        }
+    },
+    onLoad(options) {
+        this.serviceName = options.name;
+    },
+    components: {
+        Banner
+    }
+};
+</script>
+
+<style lang="less" scoped>
+.service {
+    padding: 0 16px;
+}
+.info {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 10px 0;
+
+    h2 {
+        font-size: 18px;
+        margin-top: 12px;
+
+        line-height: 25px;
+    }
+
+    p {
+        color: #878d99;
+        margin-top: 20px;
+        text-align: center;
+        line-height: 24px;
+    }
+}
+
+.case {
+    margin-top: 38px;
+    padding-bottom: 20px;
+    border-top: 1px solid #f2f3f5;
+
+    h2 {
+        font-size: 18px;
+        margin-top: 26px;
+        line-height: 28px;
+    }
+
+    p {
+        font-size: 14px;
+        color: #292c33;
+        line-height: 24px;
+        margin-top: 10px;
+    }
+}
+
+.btn-list {
+    display: flex;
+    padding: 16px 0 18px;
+
+    .btn {
+        font-size: 14px;
+        color: #292c33;
+        line-height: 24px;
+        position: relative;
+
+        &.active {
+            color: @warn;
+            font-weight: bold;
+
+            &::after {
+                content: '';
+                width: 24px;
+                height: 2px;
+                background: #ffa526;
+                border-radius: 1px;
+                position: absolute;
+                bottom: -2px;
+                left: 50%;
+                transform: translateX(-50%);
+            }
+        }
+    }
+
+    .btn + .btn {
+        margin-left: 37px;
+    }
+}
+</style>
+
+<style lang="less">
+.case {
+    .van-empty__image {
+        width: 240px;
+        height: 240px;
+    }
+
+    .van-empty {
+        .van-empty__description {
+            font-size: 12px;
+            color: #bcc1cc;
+            line-height: 17px;
+            margin-top: 10px;
+        }
+    }
+}
+</style>

+ 176 - 0
src/pages/news/Detail.vue

@@ -0,0 +1,176 @@
+<config>
+{
+'navigationBarTitleText': '',
+'navigationStyle':'custom',
+'navigationBarTextStyle':'white',
+'backgroundColorTop': '#fff',
+'backgroundColorBottom': '#f5f7fa',
+'enablePullDownRefresh':false
+}
+</config>
+<template>
+    <div>
+        <custom-bar :pre="0" :title="isActivity ? '活动详情' : '新闻详情'"></custom-bar>
+        <banner :banners="banners" fixed :height="260" :radius="0"></banner>
+
+        <div class="main" id="main">
+            <!-- <h2>{{ info.title }}</h2> -->
+            <div class="title">{{ info.title }}</div>
+
+            <div class="activity" v-if="isActivity">
+                <div class="activity-info">
+                    <div class="name">时间:</div>
+                    <div class="text">{{ info.date }}</div>
+                </div>
+                <div class="activity-info">
+                    <div class="name">地址:</div>
+                    <div class="text">{{ info.address }}</div>
+                </div>
+                <div class="activity-info" v-if="session.length > 0">
+                    <div class="name">场次:</div>
+                    <div class="sessions">
+                        <block v-for="(item, index) in session" :key="index">
+                            <div class="session-item">
+                                {{ item }}
+                            </div>
+                        </block>
+                    </div>
+                </div>
+            </div>
+
+            <div class="detail">
+                <h2>{{ isActivity ? '活动' : '新闻' }}详情</h2>
+
+                <div class="html" v-html="info.content"></div>
+            </div>
+        </div>
+
+        <fixed-button v-if="isActivity">
+            <van-button
+                block
+                :color="$colors.warn"
+                :radius="4"
+                @click="navigateTo('/pages/news/Submit?infoId=' + info.id + '&activityId=' + activityId)"
+                >{{ isEnd ? '报名结束' : activityId ? '查看报名信息' : '立即报名' }}</van-button
+            >
+        </fixed-button>
+    </div>
+</template>
+<script>
+import Banner from '../../components/Banner.vue';
+import CustomBar from '../../components/bar/CustomBar.vue';
+import FixedButton from '../../components/FixedButton';
+export default {
+    data() {
+        return {
+            informationId: 0,
+            info: {},
+            activityId: 0
+        };
+    },
+    computed: {
+        banners() {
+            return this.info.img
+                ? this.info.img.split(',').map(item => {
+                      return {
+                          img: item
+                      };
+                  })
+                : [];
+        },
+        isActivity() {
+            if (this.info.type === 'INDUSTRY_ACTIVITIES') {
+                return true;
+            } else {
+                return false;
+            }
+        },
+        session() {
+            return this.info.session || [];
+        },
+        isEnd() {
+            return this.info.isEnd || false;
+        }
+    },
+    onLoad(options) {
+        this.informationId = options.id;
+        this.$http.get('/information/get/' + options.id).then(res => {
+            this.info = res;
+        });
+        this.getActivity();
+    },
+    onShow() {
+        if (this.informationId) {
+            this.getActivity();
+        }
+    },
+    methods: {
+        getActivity() {
+            this.$http
+                .get('/eventRegistration/myEvent', {
+                    informationId: this.informationId
+                })
+                .then(res => {
+                    if (res) {
+                        this.activityId = res.id;
+                    }
+                });
+        }
+    },
+    onPageScroll() {},
+    components: {
+        Banner,
+        CustomBar,
+        FixedButton
+    }
+};
+</script>
+<style lang="less">
+.main {
+    padding: 16px;
+    .title {
+        font-size: 18px;
+        font-weight: bold;
+        color: #000000;
+        line-height: 28px;
+        padding-bottom: 5px;
+    }
+}
+.activity-info {
+    display: flex;
+    margin-top: 15px;
+    align-items: center;
+    .name {
+        font-size: 14px;
+        color: #bcc1cc;
+        line-height: 22px;
+        margin-right: 4px;
+    }
+
+    .text {
+        font-size: 14px;
+        color: #000000;
+        line-height: 22px;
+    }
+    .sessions {
+        display: flex;
+        .session-item {
+            height: 36px;
+            font-size: 14px;
+            color: #000000;
+            line-height: 36px;
+            padding: 0 10px;
+            border-radius: 4px;
+            border: 1px solid #cfd5e1;
+            margin-right: 12px;
+        }
+    }
+}
+
+.detail {
+    padding: 50px 0;
+    .html {
+        padding-top: 14px;
+    }
+}
+</style>

+ 149 - 0
src/pages/news/News.vue

@@ -0,0 +1,149 @@
+<config>
+{
+'navigationBarTitleText': '',
+'navigationStyle':'custom',
+'navigationBarTextStyle':'white',
+'backgroundColorTop': '#fff',
+'backgroundColorBottom': '#f5f7fa',
+'enablePullDownRefresh':false
+}
+</config>
+<template>
+    <div>
+        <custom-bar :pre="0" :title="title"></custom-bar>
+        <banner :banners="banners" fixed :height="140" :radius="0"></banner>
+        <div class="main" id="main">
+            <van-sticky :offset-top="71" :z-index="100" :container="main">
+                <div class="tab-content">
+                    <van-tabs
+                        :active="hotActive"
+                        @change="changeTab($event.detail.index)"
+                        :ellipsis="false"
+                        :line-width="24"
+                        :line-height="2"
+                    >
+                        <van-tab :title="item.name" v-for="item in informations" :key="item.key"></van-tab>
+                    </van-tabs>
+                </div>
+            </van-sticky>
+
+            <sort-list :empty="empty" :loading="loading" :finish="finish" top="115px + 172rpx">
+                <div class="list">
+                    <template v-if="pageType === 'bigImg'">
+                        <block v-for="item in list" :key="item.id">
+                            <news-grid :info="item"></news-grid>
+                        </block>
+                    </template>
+                    <template v-if="pageType === 'default'">
+                        <block v-for="item in list" :key="item.id">
+                            <news-row :info="item"></news-row>
+                        </block>
+                    </template>
+                </div>
+            </sort-list>
+        </div>
+    </div>
+</template>
+<script>
+import Banner from '../../components/Banner.vue';
+import CustomBar from '../../components/bar/CustomBar.vue';
+import { getBanner } from '../../utils/commont';
+import { InformationType } from '../../utils/appState';
+import searchList from '../../mixins/searchList';
+import SortList from '../../components/SortList.vue';
+import NewsGrid from '../../components/News/Grid.vue';
+import NewsRow from '../../components/News/Row.vue';
+export default {
+    components: { Banner, CustomBar, SortList, NewsGrid, NewsRow },
+    data() {
+        return {
+            banners: [],
+            ratio: 0,
+            hotActive: 0,
+            main: null,
+            url: '/information/typeList',
+            httpType: 'get',
+            barTop: 0,
+            noPage: true,
+            scrollTop: 0
+        };
+    },
+    mixins: [searchList],
+    computed: {
+        informations() {
+            return [...InformationType].map(item => {
+                return {
+                    key: item[0],
+                    name: this.$t(item[1].name),
+                    type: item[1].type || 'default'
+                };
+            });
+        },
+        listQuery() {
+            return {
+                type: [...this.informations][this.hotActive].key
+            };
+        },
+        pageType() {
+            return [...this.informations][this.hotActive].type;
+        },
+        title() {
+            return this.$t([...this.informations][this.hotActive].name);
+        }
+    },
+    onLoad() {
+        this.changeTab(0, true);
+    },
+    methods: {
+        changeTab(index, first = false) {
+            this.hotActive = index;
+            getBanner([...this.informations][index].key).then(res => {
+                this.banners = res;
+            });
+
+            this.$nextTick(() => {
+                if (first) {
+                    this.getData();
+                } else {
+                    this.refreash();
+                }
+            });
+        }
+    },
+    onPageScroll() {},
+    onReady() {
+        this.main = wx.createSelectorQuery().select('#main');
+        this.main
+            .boundingClientRect(rect => {
+                this.searchTop = rect.top - 61;
+                this.barTop = rect.top - 71;
+            })
+            .exec();
+    }
+};
+</script>
+<style lang="less" scoped>
+.list {
+    padding: 16px;
+    .news + .news {
+        margin-top: 16px;
+    }
+}
+</style>
+<style lang="less">
+.tab-content {
+    .van-tabs__scroll {
+        .van-tab {
+            color: #292c33;
+            &.van-tab--active {
+                color: @warn;
+            }
+        }
+
+        .van-tabs__line {
+            bottom: 8px;
+            left: 7.5px;
+        }
+    }
+}
+</style>

+ 342 - 0
src/pages/news/Submit.vue

@@ -0,0 +1,342 @@
+<config>
+{
+'navigationBarTitleText': '填写报名表',
+'backgroundColor':'#fff'
+}
+</config>
+<template>
+    <div class="container">
+        <div class="activutyInfo">
+            <div class="title">{{ information.title }}</div>
+            <div class="info">
+                <div class="name">时间:</div>
+                <div class="val">{{ information.date }}</div>
+            </div>
+
+            <div class="info">
+                <div class="name">地址:</div>
+                <div class="val">{{ information.address }}</div>
+            </div>
+        </div>
+
+        <div class="form">
+            <div class="session" v-if="session.length > 0">
+                <h3>活动场次选择</h3>
+
+                <div class="session-list">
+                    <div
+                        class="session-item"
+                        :class="{ active: form.session === item }"
+                        @click="!activityId ? (form.session = item) : ''"
+                        v-for="(item, index) in session"
+                        :key="index"
+                    >
+                        <span> {{ item }}</span>
+
+                        <img src="../../static/imgs/icon_list_xuanzhong.png" alt="" />
+                    </div>
+                </div>
+            </div>
+
+            <van-cell-group :border="false">
+                <van-field
+                    label="姓名"
+                    :value="form.nickname"
+                    input-align="right"
+                    @input="form.nickname = $event.detail"
+                    :readonly="activityId"
+                />
+                <van-field label="称呼" :value="getSexName(form.sex)" input-align="right" readonly @click="chooseSex" />
+                <van-field
+                    label="公司名称"
+                    :value="form.companyName"
+                    input-align="right"
+                    @input="form.companyName = $event.detail"
+                    :readonly="activityId"
+                />
+                <van-field
+                    label="职位"
+                    :value="form.position"
+                    input-align="right"
+                    @input="form.position = $event.detail"
+                    :readonly="activityId"
+                />
+                <van-field
+                    label="电话"
+                    :value="form.phone"
+                    input-align="right"
+                    :readonly="activityId"
+                    @input="form.phone = $event.detail"
+                />
+                <van-field
+                    label="邮箱"
+                    :value="form.email"
+                    input-align="right"
+                    :readonly="activityId"
+                    @input="form.email = $event.detail"
+                />
+            </van-cell-group>
+
+            <fixed-button v-if="!activityId">
+                <van-button block :color="$colors.warn" :disabled="!canNext" :radius="4" @click="submit"
+                    >提交</van-button
+                >
+            </fixed-button>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import FixedButton from '../../components/FixedButton';
+import { sexModels } from '../../utils/appState';
+export default {
+    data() {
+        return {
+            information: {},
+            chooseSession: '',
+            form: {},
+            activityId: 0
+        };
+    },
+    computed: {
+        ...mapState(['userInfo']),
+        session() {
+            return this.information.session || [];
+        },
+        canNext() {
+            const _form = { ...this.form };
+            if (
+                _form.userId &&
+                _form.sex &&
+                _form.position &&
+                _form.nickname &&
+                _form.phone &&
+                _form.email &&
+                _form.companyName &&
+                _form.informationId &&
+                _form.session
+            ) {
+                return true;
+            }
+            return false;
+        }
+    },
+    onLoad(options) {
+        if (options.activityId && Number(options.activityId)) {
+            this.activityId = Number(options.activityId);
+            this.$http.get('/eventRegistration/get/' + options.activityId).then(res => {
+                this.information = res.information;
+                this.form = { ...res };
+            });
+            wx.setNavigationBarTitle({
+                title: '报名表信息'
+            });
+        } else {
+            this.informationId = options.infoId;
+            this.$http.get('/information/get/' + options.infoId).then(res => {
+                this.information = res;
+                this.setInfo();
+            });
+        }
+    },
+    watch: {
+        userInfo() {
+            this.setInfo();
+        }
+    },
+    methods: {
+        submit() {
+            if (!this.form.session) {
+                this.$toast('请选择活动场次');
+                return;
+            }
+            if (!this.form.nickname) {
+                this.$toast('请输入姓名', 'success');
+                return;
+            }
+            if (!this.form.sex) {
+                this.$toast('请选择称呼');
+                return;
+            }
+            if (!this.form.companyName) {
+                this.$toast('请输入公司名称');
+                return;
+            }
+            if (!this.form.position) {
+                this.$toast('请输入职务');
+                return;
+            }
+            if (!this.form.phone) {
+                this.$toast('请输入联系电话');
+                return;
+            }
+            if (!this.form.email) {
+                this.$toast('请输入邮箱');
+                return;
+            }
+
+            this.$http
+                .post(
+                    '/eventRegistration/save',
+                    {
+                        ...this.form
+                    },
+                    {
+                        header: {
+                            'Content-Type': 'application/json'
+                        }
+                    }
+                )
+                .then(res => {
+                    this.$toast('报名成功!', 'success');
+                    this.navigateBack();
+                })
+                .catch(e => {
+                    this.$toast(e.error);
+                });
+        },
+        setInfo() {
+            if (this.userInfo) {
+                this.form = {
+                    userId: this.userInfo.id,
+                    sex: this.userInfo.sex,
+                    position: this.userInfo.position,
+                    nickname: this.userInfo.nickname,
+                    phone: this.userInfo.phone,
+                    email: this.userInfo.email,
+                    companyName: this.userInfo.chCompanyName,
+                    informationId: this.informationId,
+                    session: this.getList(this.information.session)
+                };
+            }
+        },
+        getSexName(sex) {
+            if (sexModels.has(sex)) {
+                return sexModels.get(sex).label;
+            } else {
+                return '';
+            }
+        },
+        chooseSex() {
+            if (this.activityId) {
+                return;
+            }
+            const _list = [...sexModels.values()].map(item => {
+                return item.label;
+            });
+            wx.showActionSheet({
+                itemList: _list,
+                success: res => {
+                    this.form.sex = [...sexModels.keys()][res.tapIndex];
+                },
+                fail: res => {
+                    console.log(res.errMsg);
+                }
+            });
+        }
+    },
+    components: {
+        FixedButton
+    }
+};
+</script>
+<style lang="less">
+.container {
+    padding: 16px;
+}
+.activutyInfo {
+    padding: 20px 16px;
+
+    box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.06);
+    border-radius: 4px;
+    position: relative;
+    &::before {
+        content: '';
+        width: 3px;
+        height: 16px;
+        background: #ffa526;
+        border-radius: 2px;
+        position: absolute;
+        top: 27px;
+        left: 10px;
+    }
+    .title {
+        font-size: 18px;
+        font-weight: bold;
+        color: #000000;
+        line-height: 28px;
+
+        .ellipsisLn(2);
+    }
+
+    .info {
+        display: flex;
+        margin-top: 12px;
+
+        .name {
+            font-size: 14px;
+            color: #bcc1cc;
+            line-height: 22px;
+        }
+
+        .val {
+            font-size: 14px;
+            color: #000000;
+            line-height: 22px;
+        }
+    }
+}
+
+.form {
+    padding: 20px 0;
+
+    .session {
+        h3 {
+            padding: 10px 0;
+        }
+
+        .session-list {
+            display: flex;
+            padding-bottom: 10px;
+
+            .session-item {
+                font-size: 14px;
+                color: #000000;
+                line-height: 50px;
+                background: #ffffff;
+                border-radius: 4px;
+                border: 1px solid #cfd5e1;
+                margin-right: 12px;
+                padding: 0 12px;
+                position: relative;
+
+                &.active {
+                    color: @warn;
+                    border-color: @warn;
+                    img {
+                        display: block;
+                    }
+                }
+
+                img {
+                    width: 16px;
+                    height: 16px;
+                    position: absolute;
+                    right: 0;
+                    bottom: 0;
+                    display: none;
+                }
+            }
+        }
+    }
+
+    --cell-horizontal-padding: 0;
+
+    .van-cell {
+        &::after {
+            left: 0;
+            right: 0;
+        }
+    }
+}
+</style>

BIN
src/static/imgs/imt_gaikuang_icon_01.png


BIN
src/static/imgs/imt_gaikuang_icon_02.png


BIN
src/static/imgs/imt_gaikuang_icon_03.png


BIN
src/static/imgs/imt_topbanner_icon_3d.png


+ 44 - 5
src/store/index.js

@@ -7,7 +7,9 @@ export default new Vuex.Store({
         safeAreaBottom: 0,
         userInfo: null,
         loginInfo: null,
-        userIcon: ''
+        userIcon: '',
+        filterInfo: {},
+        productCategories: []
     },
     mutations: {
         setSafeAreaTop(state, val) {
@@ -27,14 +29,51 @@ export default new Vuex.Store({
         },
         setUserIcon(state, icon) {
             state.userIcon = icon;
+        },
+        setFilterInfo(state, filterInfo) {
+            state.filterInfo = filterInfo;
+        },
+        setProductCategories(state, productCategories) {
+            state.productCategories = productCategories;
         }
     },
     actions: {
         getUserInfo(context) {
-            http.http.get('/user/my').then(res => {
-                if (res.phone) {
-                    context.commit('setUserInfo', res);
-                }
+            let userInfo = {};
+            http.http
+                .get('/user/my')
+                .then(res => {
+                    if (res.phone) {
+                        userInfo = res;
+                        return http.http.post('/buyersInfo/getInfo', {
+                            userId: res.id
+                        });
+                    }
+
+                    return Promise.reject();
+                })
+                .then(res => {
+                    if (res.logo) {
+                        userInfo.avatar = res.logo;
+                    }
+                    context.commit('setUserInfo', userInfo);
+                });
+        },
+        getProductCategories(context) {
+            return http.http.get('/productCategory/tree').then(res => {
+                let list = res
+                    .map(item => {
+                        return [
+                            item,
+                            item.children.map(child => {
+                                return [child, child.children];
+                            })
+                        ];
+                    })
+                    .flat(Infinity);
+                context.commit('setProductCategories', list);
+
+                return Promise.resolve(list);
             });
         }
     }

+ 61 - 1
src/utils/appState.js

@@ -1,4 +1,64 @@
 const collectType = new Map([['PRODUCT', 'chan-pin'], ['VENDOR', 'chang-shang']]);
 const BrandSortType = new Map([['COMPOSITE', 'zong-he'], ['POPULARITY', 'ren-qi']]);
 
-export { collectType, BrandSortType };
+const ProductSortType = new Map([['COMPOSITE', 'zong-he'], ['POPULARITY', 'ren-qi'], ['TIME', 'shi-jian']]);
+
+const EnterpriseType = new Map([
+    ['MANUFACTURER', 'sheng-chan-shang'],
+    ['DEALER', 'jing-xiao-shang'],
+    ['TECHNICAL_SERVICE_PROVIDER', 'ji-shu-fu-wu-shang']
+]);
+
+const sexModels = new Map([
+    [
+        'male',
+        {
+            label: '先生',
+            zh: '男'
+        }
+    ],
+    [
+        'female',
+        {
+            label: '女士',
+            zh: '女'
+        }
+    ]
+]);
+
+const InformationType = new Map([
+    [
+        'NEW_PRODUCT_RELEASE',
+        {
+            name: 'xin-pin-fa-bu',
+            type: 'bigImg'
+        }
+    ],
+    [
+        'INDUSTRY_NEWS',
+        {
+            name: 'hang-ye-xin-wen'
+        }
+    ],
+    [
+        'TECHNICAL_INFORMATION',
+        {
+            name: 'ji-shu-zi-xun',
+            type: 'bigImg'
+        }
+    ],
+    [
+        'POLICY_INFORMATION',
+        {
+            name: 'zheng-ce-xin-xi'
+        }
+    ],
+    [
+        'INDUSTRY_ACTIVITIES',
+        {
+            name: 'hang-ye-huo-dong',
+            type: 'bigImg'
+        }
+    ]
+]);
+export { collectType, BrandSortType, ProductSortType, EnterpriseType, InformationType, sexModels };

+ 169 - 0
src/utils/imtPageInfo.js

@@ -0,0 +1,169 @@
+const services = [
+    {
+        name: '综合物流',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_01.png',
+        sub: '全面的贸易物流与进出口业务解决方案',
+        content:
+            '配备专业的贸易及物流服务团队,为客户提供全面的贸易物流解决方案,包括进出口业务服务、运输服务、保税展示物流、仓储管理与分拨、机械设备维修物流等。',
+
+        cases: [
+            {
+                imgs: [
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_wuliu_case01_a.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_wuliu_case01_b.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_wuliu_case01_c.jpg'
+                ],
+                name: '中国国际进口博览会保税参展物流服务',
+                content:
+                    '首届中国国际进口博览会(CIIE)已于2018年11月5至10期间在上海顺利召开,智能装备展区中有多家IMT客户参展,其中展机直接从自贸区出展的客户共有9家,参展高端机床设备共计21台,总货值超过1000万美元。IMT物流团队为客户提供从展前布展到展后撤展的全程展品物流服务,负责保税展机的所有海关及物流手续。'
+            },
+            {
+                imgs: [
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_wuliu_case02_a.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_wuliu_case02_b.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_wuliu_case02_c.jpg'
+                ],
+                name: 'Liebherr保税仓储与物流服务',
+                content:
+                    '我们为利勃海尔中国提供综合物流及保税仓储服务,为其配备了独立恒温恒湿仓库,并提供保税仓储管理,以及包括进口/出口业务流程操作、进境备案、保税区清关、物流运输与装卸在内的综合贸易物流服务。高效的保税仓储管理和完善的物流服务可为其节约运营成本,助力提高业务运转效率。'
+            }
+        ]
+    },
+    {
+        name: '商务租赁',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_02.png',
+        sub: '多种功能的物业空间,专业的物业管理',
+        content:
+            '拥有多种功能的物业空间,包括商务办公楼、设备展示体验馆、多功能会议厅、多媒体中心,并提供专业的物业管理服务。',
+
+        cases: [
+            {
+                imgs: [
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zulin_case01_a.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zulin_case01_b.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zulin_case01_c.jpg'
+                ],
+                name: 'GF 加工方案',
+                content:
+                    '乔治费歇尔精密机床(上海)有限公司是瑞士GF加工方案上海子公司,2014年迁址至外高桥智能制造服务产业园,并在园区设立亚洲和中国总部。总部面积达3000平方米,是亚洲和中国管理团队所在地,也是其在亚洲地区最大最新的综合技术服务中心。同时,GF加工方案在产业园内设立了亚洲自动化演示中心,以及面向公司内部及外部的亚洲技术培训学院,奠定了其在亚太地区的重要地位。同时,产业园的保税展示及演示功能,也为其最新技术和产品的首发亮相提供最优的场所与环境。'
+            },
+            {
+                imgs: [
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zulin_case02_a.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zulin_case02_b.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zulin_case02_c.jpg'
+                ],
+                name: 'Index',
+                content:
+                    'INDEX集团起源于德国,是全球一流的数控车床制造商。2017年,INDEX集团入驻外高桥智能制造服务产业园,成立了全新的技术中心和展厅,新的技术服务中心为两层,建筑面积近1500平方米,白绿相间的简约设计极具现代感。宽敞通透的展厅中展示了因代克斯集团最新系列产品,并配以自主研发的数控机床控制系统——Xpanel i4.0进行生产实时管理系统演示。该技术中心集合公司运营管理、结算、设备展示、演示、销售、技术支持和培训等功能,并与其位于太仓的生产基地协同,可为亚太区客户提供更加完善的服务。'
+            }
+        ]
+    },
+    {
+        name: '检测认证',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_03.png',
+        sub: '政策咨询、投资咨询、公司事务代理等',
+        content:
+            '行业专业检测机构,为客户提供进口机床法定检验、机床精度及性能检测等服务。实行进口机床现场法定检验及采信第三方检测报告。',
+        cases: [
+            {
+                imgs: [
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_jiance_case01_a.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_jiance_case01_b.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_jiance_case01_c.jpg'
+                ],
+                name: '机械工业机床产品质量检测中心',
+                content:
+                    '机械工业机床产品质量检测中心(上海)坐落于产业园内,是机床制造领域产品质量监督检验和性能测试的专业检测机构。可进行出入境检验检疫局系统委托的进出口机床法定检验, 以及各类机床用户﹑制造商及销售商委托的机床精度和性能检测等服务。'
+            }
+        ]
+    },
+    {
+        name: '专业培训',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_04.png',
+        sub: '进口机床现场法定检验及采信第三方检测报告',
+        content:
+            '园区设立 “上海市智能制造高技能人才培养基地外高桥分基地”,是由上海市智能制造产业协会、上海浦东智能制造协共同组建的专业化培训平台,旨在服务更多智能制造优秀企业,以产业发展、企业需求为导向,加快为企业输送智能制造高技能人才。',
+        cases: [
+            {
+                imgs: [
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_peixun_case01_a.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_peixun_case01_b.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_peixun_case01_c.jpg'
+                ],
+                name: '工业大数据助推智能工厂建设',
+                content:
+                    '2019年11月,首期专题培训研修班“工业大数据助推智能工厂建设”开班,邀请了协会部分会员企业相关负责人及行业资深专家讲解授课,旨在帮助制造业企业更好理解大数据技术如何融入智能制造过程的各个环节,实现生产精准化、智能化,适应本市“创新驱动发展、经济转型升级”的需要。'
+            }
+        ]
+    },
+    {
+        name: '商务咨询',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_05.png',
+        sub: '行业展会、政企交流活动、研讨会、技术论坛',
+        content: '配备专业政策咨询及公司事务咨询团队,为客户提供政策咨询、投资咨询、公司事务代理等服务。',
+        cases: [
+            {
+                imgs: [
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zixun_case01_a.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zixun_case01_b.jpg',
+                    'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_zixun_case01_c.jpg'
+                ],
+                name: '通快',
+                content:
+                    '我们成功助力通快科技(上海)有限公司于2019年9月认定为上海市跨国公司地区总部(亚太区),将作为德国通快集团在亚太地区的唯一高能级总部建立财务控制管理中心、外币跨境现金池、亚太区备件物流中心以及激光应用的亚太区服务中心,承载通快集团发展中国市场乃至亚太地区市场发展的期望,进一步提升在中国内地的投资和投资管理能力,拓展市场份额。'
+            }
+        ]
+    },
+    {
+        name: '参展服务',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_06.png',
+        sub: '为企业输送智能制造高技能人才',
+        color: '#64776F',
+        content: '为客户提供设备保税参展服务,从设备到港到设备进馆完成调试的全流程服务。',
+        img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_img_062x.jpg'
+    },
+    {
+        name: '行业交流',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_07.png',
+        sub: '设备保税参展全流程服务',
+        color: '#B3775B',
+        content: '组织筹办国际性的行业展会、组织政企交流活动、举办研讨会、技术论坛等专业活动。',
+        img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_img_072x.jpg'
+    },
+    {
+        name: '融资租赁',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_08.png',
+        sub: '配置优质金融服务解决方案',
+        color: '#BF782C',
+        content:
+            '与银行系统进行金融战略合作,搭建产融合作平台,为平台智能制造企业和相关重点项目配置优质金融服务解决方案。',
+        img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_img_082x.jpg'
+    },
+    {
+        name: '维修',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_09.png',
+        sub: '整合专业技术团队资源,提供高效维修服务',
+        color: '#204758',
+        content: '整合专业技术团队资源,为客户提供高效便捷的维修服务。',
+        img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_img_092x.jpg'
+    },
+    {
+        name: '产能共享',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_10.png',
+        sub: '整合生产资源,提供产能供应与需求配置服务',
+        color: '#88785B',
+        content: '整合生产资源,为客提供产能供应与需求的配置服务。',
+        img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_img_102x.jpg'
+    },
+    {
+        name: '技术系统集成',
+        icon: 'http://imt.oss-cn-hangzhou.aliyuncs.com/micro/imt_fuwu_icon_11.png',
+        sub: '整合行业资源,寻找最佳技术系统集成方案',
+        color: '#5C493B',
+        content: '整合行业众多优质资源,为客户寻找最佳的技术系统集成方案。',
+        img: 'http://imt.oss-cn-hangzhou.aliyuncs.com/case/imt_fuwu_img_112x.jpg'
+    }
+];
+
+export { services };

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно