ソースを参照

制作完成产品中心页面

kindring 2 年 前
コミット
dfb6e42388

+ 1 - 0
assets/icons/svg/next.svg

@@ -0,0 +1 @@
+<svg t="1681641647302" class="icon" viewBox="0 0 1257 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2608" width="200" height="200"><path d="M745.47264 1024c11.264 0 23.552-4.096 31.744-13.312L1244.16064 543.744a45.12 45.12 0 0 0 0-63.488L777.21664 13.312a45.12 45.12 0 0 0-63.488 0c-18.432 17.408-18.432 46.08 0 64.512L1147.90464 512 713.72864 946.176c-18.432 18.432-18.432 47.104 0 64.512 8.192 9.216 20.48 13.312 31.744 13.312zM45.05664 557.056h1102.848A45.44 45.44 0 0 0 1192.96064 512a44.8 44.8 0 0 0-45.056-45.056H45.05664A44.8 44.8 0 0 0 0.00064 512c0 24.576 20.48 45.056 45.056 45.056z" p-id="2609"></path></svg>

+ 1 - 0
assets/icons/svg/prev.svg

@@ -0,0 +1 @@
+<svg t="1681641683494" class="icon" viewBox="0 0 1257 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3591" width="200" height="200"><path d="M512 1024c-11.264 0-23.552-4.096-31.744-13.312L13.312 543.744a45.12 45.12 0 0 1 0-63.488L480.256 13.312a45.12 45.12 0 0 1 63.488 0c18.432 17.408 18.432 46.08 0 64.512L109.568 512l434.176 434.176c18.432 18.432 18.432 47.104 0 64.512-8.192 9.216-20.48 13.312-31.744 13.312z m700.416-466.944H109.568A45.44 45.44 0 0 1 64.512 512c0-25.6 20.48-45.056 45.056-45.056h1102.848A44.8 44.8 0 0 1 1257.472 512a45.44 45.44 0 0 1-45.056 45.056z" p-id="3592"></path></svg>

+ 75 - 0
assets/productList.css

@@ -0,0 +1,75 @@
+.productCenter{
+  display: grid;
+  grid-template-columns: repeat(4,310px);
+  grid-gap: 25px;
+  box-sizing: border-box;
+}
+.product{
+  display: block;
+  height: 380px;
+  background-color: #fff;
+  box-shadow: 1px 1px 3px black;
+  border-radius: 3px;
+  overflow: hidden;
+  cursor: pointer;
+  position: relative;
+}
+.product:hover{
+  box-shadow: 1px 1px 5px #3a3838;
+}
+.product .more{
+  background-color: #912b02;
+  padding: 0 30px;
+  border-radius: 4px;
+  display: block;
+  position: absolute;
+  left: 50%;
+  transform: translate(-50%,0);
+  top: 250px;
+  opacity: 0;
+  transition:all 0.5s;
+  color: white;
+}
+.product:hover .more{
+  opacity: 1;
+  background-color: orangered;
+}
+.product .more:hover{
+  box-shadow: 1px 1px 5px white;
+  padding: 0 25px;
+}
+.product .product-info{
+  display: block;
+  padding: 5px;
+  height: calc(100% - 270px);
+  box-sizing: border-box;
+}
+.product .imgBox{
+  display: block;
+  width: 310px;
+  height: 270px;
+}
+.product:hover .imgBox img{
+  left: -10px;
+  top: -10px;
+  max-width: calc(100% + 20px);
+  width: calc(100% + 20px);
+  height: calc(100% + 20px);
+}
+
+.product .title{
+  height: 40px;
+  display: flex;
+  align-items: center;
+  font-size: 1.6em;
+}
+.product-info .description{
+  display: block;
+  height: calc(100% - 40px);
+  border-top: 1px solid beige;
+  font-size: 0.9em;
+  color: #444343;
+}
+.product-info .description > span{
+  display: block;
+}

+ 4 - 1
assets/public.css

@@ -137,9 +137,10 @@
 .footer-list{
   display: flex;
   padding: 15px 0;
+  justify-content: space-between;
 }
 .footer-list .footerItem{
-  width: calc(1320px / 5);
+  /*width: calc(1320px / 5);*/
 }
 .footer-list .footerItem .title{
   font-size: 1.4em;
@@ -193,3 +194,5 @@
   transition: all .5s;
 }
 
+
+

+ 108 - 0
assets/publicBanner.css

@@ -0,0 +1,108 @@
+
+.banner {
+  width: 100%;
+  position: relative;
+  display: flex;
+  overflow: hidden;
+  height: 450px;
+  justify-content: center;
+  align-items: center;
+}
+.banner *{
+  transition: all .4s;
+}
+.banner .imgBox{
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+.banner:hover .imgBox > img{
+  left: -20px;
+  top: -20px;
+  max-width: calc(100% + 40px);
+  width: calc(100% + 40px);
+  height: calc(100% + 40px);
+}
+.banner-con{
+  position: relative;
+  padding: 15px 30px;
+  display: flex;
+  justify-content: center;
+  flex-direction: column;
+  margin-top: 100px;
+}
+.bg-absolute{
+  position: absolute;
+  filter: blur(5px);
+  background-image: linear-gradient(rgba(0,0,0,0) 0,rgba(0,0,0,0.5) 60% );
+  color: #b9b7b7;
+}
+.banner-con > span{
+  width: 420px;
+  font-size: 2.5em;
+  color: white;
+  font-weight: bold;
+  cursor: default;
+  display: flex;
+  justify-content: center;
+}
+.banner:hover .banner-con > span{
+  font-size: 2.6em;
+}
+.banner-con > .subTitle{
+  font-size: 2em;
+}
+.banner:hover .banner-con > .subTitle{
+  font-size: 1.9em;
+}
+
+
+.banner-con .search-box{
+  width: 100%;
+  display: flex;
+  justify-content: center;
+}
+.banner-con .search{
+  width: 340px;
+  height: 40px;
+  margin-top: 10px;
+  /*background-color: #fff;*/
+  box-shadow: 1px 1px 6px 4px #22b3e5;
+  border-radius: 40px;
+  cursor: pointer;
+  overflow: hidden;
+  position: relative;
+
+}
+.banner:hover .banner-con .search{
+  width: 400px;
+  border: 1px solid #ffffff;
+}
+.banner-con .search > *{
+  display: block;
+}
+.banner-con .search-box .search input{
+  width: 100%;
+  height: 100%;
+  border-radius: 40px;
+  outline: #22b3e5;
+  BACKGROUND-COLOR: transparent;
+  padding-left: 15px;
+  color: #b4b4b4;
+}
+.banner-con .search-box .search button{
+  display: block;
+  width: 40px;
+  height: 40px;
+  position: absolute;
+  right: 0;
+  top: 0;
+  color: white;
+  font-size: 1.4em;
+}
+.banner-con .search-box .search button:hover{
+  font-size: 1.6em;
+  color: orangered;
+}

+ 56 - 0
components/banner/itemBanner.vue

@@ -0,0 +1,56 @@
+<template>
+  <div class="banner">
+    <div class="imgBox">
+      <img src="/image/banner/banner_product.png" alt="">
+    </div>
+    <div class="banner-con bg-absolute">
+      <span>{{lang===langType.cn?"产品中心":getAbbrText("产品中心")}}</span>
+      <span class="subTitle">{{lang===langType.cn?"持续创新的软硬件产品":getLangText("持续创新的软硬件产品")}}</span>
+      <span>1</span>
+    </div>
+    <div class="banner-con">
+      <span>{{lang===langType.cn?title:getAbbrText(title)}}</span>
+      <span class="subTitle">{{lang===langType.cn?subTitle:getLangText(subTitle)}}</span>
+    </div>
+
+
+  </div>
+</template>
+
+<script>
+import langMap from "~/map/langMap";
+
+export default {
+  name: "itemBanner",
+  props:{
+    lang:{
+      default: langMap.lang.cn
+    },
+    title: {default:"产品中心"},
+    subTitle: {default:"持续创新的软硬件产品"},
+  },
+  data(){
+    return {
+      langType: langMap.lang,
+    }
+  },
+  methods:{
+    getLangText(str){
+      return langMap.getText(this.lang,str);
+    },
+    getAbbrText(str){
+      return langMap.getAbbrText(this.lang,str);
+    },
+  }
+}
+</script>
+
+<style scoped>
+@import "~/assets/publicBanner.css";
+.banner {
+  height: 300px;
+}
+.banner-con > span{
+  width: 720px;
+}
+</style>

+ 2 - 108
components/banner/productBanner.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="banner">
     <div class="imgBox">
-      <img src="image/banner/banner_product.png" alt="">
+      <img src="/image/banner/banner_product.png" alt="">
     </div>
     <div class="banner-con bg-absolute">
       <span>{{lang===langType.cn?"产品中心":getAbbrText("产品中心")}}</span>
@@ -57,111 +57,5 @@ export default {
 </script>
 
 <style scoped>
-.banner {
-  width: 100%;
-  position: relative;
-  display: flex;
-  overflow: hidden;
-  height: 450px;
-  justify-content: center;
-  align-items: center;
-}
-.banner *{
-  transition: all .4s;
-}
-.banner .imgBox{
-  width: 100%;
-  height: 100%;
-  position: absolute;
-  left: 0;
-  top: 0;
-}
-.banner:hover .imgBox > img{
-  left: -20px;
-  top: -20px;
-  max-width: calc(100% + 40px);
-  width: calc(100% + 40px);
-  height: calc(100% + 40px);
-}
-.banner-con{
-  position: relative;
-  padding: 15px 30px;
-  display: flex;
-  justify-content: center;
-  flex-direction: column;
-  margin-top: 100px;
-}
-.bg-absolute{
-  position: absolute;
-  filter: blur(5px);
-  background-image: linear-gradient(rgba(0,0,0,0) 0,rgba(0,0,0,0.5) 60% );
-  color: #b9b7b7;
-}
-.banner-con > span{
-  width: 420px;
-  font-size: 2.5em;
-  color: white;
-  font-weight: bold;
-  cursor: default;
-  display: flex;
-  justify-content: center;
-}
-.banner:hover .banner-con > span{
-  font-size: 2.6em;
-}
-.banner-con > .subTitle{
-  font-size: 2em;
-}
-.banner:hover .banner-con > .subTitle{
-  font-size: 1.9em;
-}
-
-
-.banner-con .search-box{
-  width: 100%;
-  display: flex;
-  justify-content: center;
-}
-.banner-con .search{
-  width: 340px;
-  height: 40px;
-  margin-top: 10px;
-  /*background-color: #fff;*/
-  box-shadow: 1px 1px 6px 4px #22b3e5;
-  border-radius: 40px;
-  cursor: pointer;
-  overflow: hidden;
-  position: relative;
-
-}
-.banner:hover .banner-con .search{
-  width: 400px;
-  border: 1px solid #ffffff;
-}
-.banner-con .search > *{
-  display: block;
-}
-.banner-con .search-box .search input{
-  width: 100%;
-  height: 100%;
-  border-radius: 40px;
-  outline: #22b3e5;
-  BACKGROUND-COLOR: transparent;
-  padding-left: 15px;
-  color: #b4b4b4;
-}
-.banner-con .search-box .search button{
-  display: block;
-  width: 40px;
-  height: 40px;
-  position: absolute;
-  right: 0;
-  top: 0;
-  color: white;
-  font-size: 1.4em;
-}
-.banner-con .search-box .search button:hover{
-  font-size: 1.6em;
-  color: orangered;
-}
+@import "~/assets/publicBanner.css";
 </style>

+ 17 - 13
components/header/menuDrops/menuDrop.vue

@@ -20,7 +20,7 @@
       >
         <div class="con">
           <div class="img-box">
-            <img :src="'public/'+item.image" :alt="item.name"  class="img"/>
+            <img :src="'/public/'+item.image" :alt="item.name"  class="img"/>
           </div>
           <div class="text-box">
             <div class="name">{{item.name}}</div>
@@ -37,13 +37,13 @@ import langMap from "~/map/langMap";
 import handle from "~/until/handle";
 const productMenus = [
   {
-  text: "M2M产品",
-  typeKey: "m2m",
-  href: '/m2m'
-},
+    text: "M2M产品",
+    typeKey: "m2m",
+    href: '/m2m'
+  },
   {
     text: "AI摄像头",
-    typeKey: "eCam",
+    typeKey: "aiCam",
     href: '/aiCam'
   },
   {
@@ -53,12 +53,12 @@ const productMenus = [
   },
   {
     text: "4G低功耗摄像头",
-    typeKey: "4gCam",
+    typeKey: "low",
     href: '/low'
   },
   {
     text: "自动变焦双目协同摄像头",
-    typeKey: "nCam",
+    typeKey: "cam",
     href: '/cam'
   }
 ];
@@ -68,12 +68,16 @@ const productMenus = [
  */
 const solutionMenus = [
   {
-    text: "M2M产品",
-    typeKey: "m2m"
+    text: "解决方案",
+    typeKey: "sol"
   },
   {
-    text: "智能终端",
-    typeKey: "sm"
+    text: "行业应用",
+    typeKey: "acs"
+  },
+  {
+    text: "电力案例",
+    typeKey: "epower"
   },
 ];
 export default {
@@ -158,7 +162,7 @@ export default {
         // 尝试加载特定静态页面
         window.location.href = item.source
       }else{
-        window.location.href = `${this.nowMenuKey}.html?id=${item.id}`
+        window.location.href = `${this.pHref}/item/${this.nowMenuKey}?id=${item.id}`
       }
     }
   }

+ 75 - 0
components/pageSelect.vue

@@ -0,0 +1,75 @@
+<template>
+  <div class="content">
+    <div class="conBox page-select">
+<!--      当前页数-->
+<!--      总页数-->
+      <div :class="`p-btn prev ${page===1?'disable-btn':''}`"
+           @click="prevPageHandle">
+        <svg-icon icon-class="prev"/>
+      </div>
+      <div class="p-show">
+        {{page}}/{{total}}
+        页 {{count}}条
+      </div>
+      <div :class="`p-btn next ${page===total?'disable-btn':''}`"
+           @click="nextPageHandle">
+        <svg-icon icon-class="next"/>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "pageSelect",
+  props:{
+    page: {default:1},
+    count: {default:1},
+    total: {default:1}
+  },
+  methods:{
+    prevPageHandle(){
+      if(this.page <= 1){
+        return
+      }
+      this.$root.$emit('changePage',this.page-1);
+    },
+    nextPageHandle(){
+      if(this.page >= this.total){
+        return
+      }
+      this.$root.$emit('changePage',this.page+1);
+    }
+  }
+}
+</script>
+
+<style scoped>
+.page-select{
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-top: 10px;
+  margin-bottom: 15px;
+}
+.p-btn{
+  width: 120px;
+  height: 35px;
+  display: flex;
+  justify-content: center;
+  font-size: 1.4rem;
+  align-items: center;
+  border-radius: 3px;
+  box-shadow: 1px 1px 3px blanchedalmond;
+  background: #4397bd;
+  cursor: pointer;
+}
+.disable-btn{
+  cursor: not-allowed;
+  background: #595959;
+  color: white;
+}
+.p-show{
+  margin: 0 10px;
+}
+</style>

+ 1 - 75
components/productCenter.vue

@@ -115,79 +115,5 @@ export default {
 </script>
 
 <style scoped>
-.productCenter{
-  display: grid;
-  grid-template-columns: repeat(4,310px);
-  grid-gap: 25px;
-  box-sizing: border-box;
-}
-.product{
-  display: block;
-  height: 380px;
-  background-color: #fff;
-  box-shadow: 1px 1px 3px black;
-  border-radius: 3px;
-  overflow: hidden;
-  cursor: pointer;
-  position: relative;
-}
-.product:hover{
-  box-shadow: 1px 1px 5px #3a3838;
-}
-.product .more{
-  background-color: #912b02;
-  padding: 0 30px;
-  border-radius: 4px;
-  display: block;
-  position: absolute;
-  left: 50%;
-  transform: translate(-50%,0);
-  top: 250px;
-  opacity: 0;
-  transition:all 0.5s;
-  color: white;
-}
-.product:hover .more{
-  opacity: 1;
-  background-color: orangered;
-}
-.product .more:hover{
-  box-shadow: 1px 1px 5px white;
-  padding: 0 25px;
-}
-.product .product-info{
-  display: block;
-  padding: 5px;
-  height: calc(100% - 270px);
-  box-sizing: border-box;
-}
-.product .imgBox{
-  display: block;
-  width: 310px;
-  height: 270px;
-}
-.product:hover .imgBox img{
-  left: -10px;
-  top: -10px;
-  max-width: calc(100% + 20px);
-  width: calc(100% + 20px);
-  height: calc(100% + 20px);
-}
-
-.product .title{
-  height: 40px;
-  display: flex;
-  align-items: center;
-  font-size: 1.6em;
-}
-.product-info .description{
-  display: block;
-  height: calc(100% - 40px);
-  border-top: 1px solid beige;
-  font-size: 0.9em;
-  color: #444343;
-}
-.product-info .description > span{
-  display: block;
-}
+@import "~/assets/productList.css";
 </style>

+ 71 - 0
components/productList.vue

@@ -0,0 +1,71 @@
+<template>
+<div class="content productList">
+  <div class="conBox productCenter">
+    <a class="product"
+       v-for="(product,i) in productList"
+       :key="'pro-'+i"
+       @click="clickProductHandle(product)"
+    >
+          <span class="imgBox">
+             <img :src="'/public/'+product.image" :alt="product.name" class="img">
+          </span>
+      <span class="more">
+            {{lang===langType.cn?"了解更多":getAbbrText("了解更多")}}
+          </span>
+      <p class="product-info">
+            <span class="title">
+              {{lang===langType.cn?product.name:getAbbrText(product.name)}}
+            </span>
+        <span class="description" v-if="product.remark">
+          {{product.remark}}
+        </span>
+      </p>
+    </a>
+  </div>
+</div>
+</template>
+
+<script>
+import langMap from "~/map/langMap";
+
+export default {
+  name: "productList",
+  props: {
+    lang:{
+      default: langMap.lang.cn
+    },
+    productList: {
+      default(){
+        return []
+      }
+    }
+  },
+  data(){
+    return {
+      langType: langMap.lang,
+    }
+  },
+  methods: {
+    getLangText(str) {
+      return langMap.getText(this.lang, str);
+    },
+    getAbbrText(str) {
+      return langMap.getAbbrText(this.lang, str);
+    },
+    clickProductHandle(product){
+      console.log(product);
+      let url = ""
+      if(product.sourceType === "1"){
+        url = product.source;
+      }else{
+        url = `/product/item/${product.type_key}?id=${product.id}`
+      }
+      window.location.href = url;
+    }
+  }
+}
+</script>
+
+<style scoped>
+@import "~/assets/productList.css";
+</style>

+ 2 - 32
components/productTypes.vue

@@ -24,6 +24,7 @@
 
 <script>
 import langMap from "@/map/langMap";
+import {pTypes} from "~/map/productMap";
 
 export default {
   name: "productTypes",
@@ -38,38 +39,7 @@ export default {
   data(){
     return {
       langType: langMap.lang,
-      types:[
-        {
-          key: 'all',
-          icon: 'all',
-          text: '所有产品'
-        },
-        {
-          key: 'cam',
-          icon: 'camera2',
-          text: '多目协同摄像头'
-        },
-        {
-          key: 'aiCam',
-          icon: 'camera',
-          text: 'AI摄像头'
-        },
-        {
-          key: 'low',
-          icon: 'lowPower',
-          text: '低功耗产品'
-        },
-        {
-          key: 'm2m',
-          icon: 'm2m',
-          text: 'm2m产品'
-        },
-        {
-          key: 'sm',
-          icon: 'smartDev',
-          text: '智能终端'
-        },
-      ]
+      types: pTypes
     }
   },
   methods:{

+ 58 - 0
map/productMap.js

@@ -0,0 +1,58 @@
+export const pTypes = [
+  {
+    key: 'all',
+    icon: 'all',
+    text: '所有产品'
+  },
+  {
+    key: 'cam',
+    icon: 'camera2',
+    text: '多目协同摄像头',
+    subText: '和方圆专业技术,多摄像头,画中画联合工作'
+  },
+  {
+    key: 'aiCam',
+    icon: 'camera',
+    text: 'AI摄像头',
+    subText: '前端识别,节省服务器带宽,深度学习,多种应用场景'
+  },
+  {
+    key: 'low',
+    icon: 'lowPower',
+    text: '低功耗产品',
+    subText: '超低功耗,超长工作时长,成套低功耗解决方案'
+  },
+  {
+    key: 'm2m',
+    icon: 'm2m',
+    text: 'm2m产品',
+    subText: '定制化模块,稳定,可靠,灵活'
+  },
+  {
+    key: 'sm',
+    icon: 'smartDev',
+    text: '智能终端',
+    subText: '面向专业领域定制化专业产品'
+  },
+]
+
+export function getTypeText (key){
+  let item = pTypes.find(val=>val.key === key);
+  if(item&&item.text){
+    return item.text;
+  }else{
+    return "loading...";
+  }
+
+}
+
+
+export function getTypeSubText (key){
+  let item = pTypes.find(val=>val.key === key);
+  if(item&&item.subText){
+    return item.subText;
+  }else{
+    return "loading...";
+  }
+
+}

+ 11 - 0
nuxt.config.js

@@ -78,5 +78,16 @@ export default {
     server: {
       port: 8000, // default: 3000
       host: '0.0.0.0', // default: localhost
+    },
+    generate: {
+      routes:
+        [
+          '/product/m2m', '/product/aiCam', '/product/sm', '/product/low', '/product/cam',
+          '/product/item/m2m',
+          '/product/item/aiCam',
+          '/product/item/sm',
+          '/product/item/low',
+          '/product/item/cam'
+        ]
     }
 }

+ 35 - 6
pages/product/_type.vue

@@ -1,23 +1,52 @@
 <template>
-  <div class="content">
-    <product-index :p-type="type"/>
-  </div>
+  <product-index :p-type="type" :p-product="products"/>
 </template>
 
 <script>
 import productIndex from '@/pages/product/index.vue'
+import handle from "~/until/handle";
+import axios from "axios";
+import qs from "qs";
 export default {
   name: "typeProductPage",
   props:[],
+  async asyncData(ctx){
+    // ctx.searchProduct();
+    const queryData = {};
+    // console.log(ctx)
+    queryData['key']=ctx.key;
+
+    queryData['type']=ctx.params.type?ctx.params.type:'all';
+    queryData['page']=1;
+    // 获取数据
+    let url = 'http://szhfy.com.cn/api/searchProduct.php';
+    let [err,res] = await handle(axios.post(
+      url,
+      qs.stringify(queryData)
+    ));
+    if(err){
+      console.log(err);
+      return {};
+    }
+    let result = res.data;
+    if(result.rcode === 1){
+      return {products:result.data}
+    }else{
+      console.error(result.msg);
+      console.log(result);
+      return {products:[]}
+    }
+  },
   data(){
     return {
-      type:  'all'
+      type:  'all',
+      products: []
     }
-
   },
   beforeMount() {
+    // console.log('动态页面执行');
     this.type = this.$route.params.type?this.$route.params.type:'all';
-    console.log(this.type);
+    // console.log(this.type);
   },
   components:{
     productIndex

+ 114 - 8
pages/product/index.vue

@@ -5,32 +5,70 @@
     <product-banner :lang="lang" />
 <!--    产品类别 -->
     <product-types :lang="lang" :type="type"></product-types>
+<!--    产品列表 -->
+    <product-list :lang="lang" :product-list="products"></product-list>
+    <page-select :page="page" :count="nowCount" :total="nowTotal"></page-select>
+    <default-footer :lang="lang"/>
   </div>
 </template>
 
 <script>
 import langMap from "@/map/langMap";
 import productBanner from "@/components/banner/productBanner";
-
+import qs from "qs"
+import axios from "axios"
+import handle from "~/until/handle";
 export default {
   name: "index",
-  props:['uLang','pType','pKey'],
+  props:['uLang','pType','pKey','pProduct'],
   components:{
     productBanner
   },
+  async asyncData(ctx){
+    // ctx.searchProduct();
+    const queryData = {};
+    // console.log(ctx)
+    queryData['key']=ctx.key;
+    queryData['type']=ctx.type;
+    queryData['page']=1;
+    // 获取数据
+    let url = 'http://szhfy.com.cn/api/searchProduct.php';
+    let [err,res] = await handle(axios.post(
+      url,
+      qs.stringify(queryData)
+    ));
+    if(err){
+      console.log(err);
+      return {};
+    }
+    let result = res.data;
+    if(result.rcode === 1){
+      return {products:result.data}
+    }else{
+      console.error(result.msg);
+      console.log(result);
+      return {products:[]}
+    }
+  },
   data(){
     return {
       lang: this.uLang?this.uLang:langMap.lang.cn,
       type: this.pType?this.pType:'all',
       key: this.pKey?this.pKey:'',
       page: 1,
-      productTypes: [],
+      nowCount: 199,
+      nowTotal: 2,
+      products: this.pProduct?this.pProduct:[],
+      pageSave: {
+
+      }
     }
   },
   mounted() {
     this.$root.$on('changeLang',this.switchLang);
     this.$root.$on('searchProductKey',this.changeProductKeyHandle);
     this.$root.$on('changeProductType',this.selectType);
+    this.$root.$on('changePage',this.changePageHandle);
     // this.loadData();
   },
   methods:{
@@ -48,6 +86,7 @@ export default {
     selectType(nextType){
       console.log(nextType)
       this.type = nextType;
+      this.page = 1;
       this.searchProduct();
     },
     changeProductKeyHandle(key){
@@ -55,15 +94,82 @@ export default {
         return 0;
       }
       this.key = key;
+      this.page = 1;
+      this.searchProduct();
+    },
+    changePageHandle(nextPage){
+      this.page = nextPage;
       this.searchProduct();
     },
     async searchProduct(){
-      const formData = new FormData();
-      formData.append('key',this.key);
-      formData.append('type',this.type);
-      formData.append('page',this.page);
+      // const formData = new FormData();
+      // formData.append('key',this.key);
+      // formData.append('type',this.type);
+      // formData.append('page',this.page);
+      const queryData = {};
+      // console.log(ctx)
+      queryData['key']=this.key;
+      queryData['type']=this.type;
+      queryData['page']=this.page;
       // 获取数据
-      let [err,res] = await handle(this.$axios.get())
+      let url = '/api/searchProduct.php';
+      let data = qs.stringify(queryData);
+      let [err,res] = await handle(this.$axios.post(
+        url,
+        data
+      ));
+      if(err){
+        console.log(err);
+        return null;
+      }
+      let result = res.data;
+      if(result.rcode === 1){
+        this.products = result.data;
+        this.loadPageData(data);
+      }else{
+        console.error(result.msg);
+        console.log(result);
+      }
+    },
+    async loadPageData(queryData){
+      let url = '/api/getProductPage.php';
+      // let
+      let err,res;
+      let pageData = null;
+      if(this.pageSave[this.type] && this.pageSave[this.type][this.key]){
+        pageData = this.pageSave[this.type][this.key]
+      }else{
+        [err,res] = await handle(this.$axios.post(
+          url,
+          queryData
+        ));
+        if(err){
+          console.error(err);
+        }else{
+          let result = res.data;
+          if(result.rcode === 1){
+            pageData = result.data;
+          }else{
+            console.error(result.msg);
+            console.log(result);
+          }
+        }
+      }
+      if (pageData){
+        this.nowTotal = Math.ceil(pageData.count / pageData.limit);
+        this.nowCount = pageData.count;
+        if(!this.pageSave[this.type]){
+          this.pageSave[this.type] = {}
+        }
+        if(!this.pageSave[this.type][this.key]){
+          this.pageSave[this.type][this.key] = pageData;
+        }
+      }else{
+        this.nowTotal = 1;
+        this.nowCount = 1;
+      }
+
+
     }
   }
 }

+ 29 - 0
pages/product/item/_type.vue

@@ -0,0 +1,29 @@
+<template>
+  <item-index :p-type="type" />
+</template>
+
+<script>
+import ItemIndex from "~/pages/product/item/index";
+export default {
+  name: "itemType",
+  components: {ItemIndex},
+  data(){
+    return {
+      type:  '',
+      products: []
+    }
+  },
+  beforeMount() {
+    // console.log('动态页面执行');
+    this.type = this.$route.params.type;
+    if(!this.type){
+      return window.location.href = '/product'
+    }
+    // console.log(this.type);
+  },
+}
+</script>
+
+<style scoped>
+
+</style>

+ 84 - 0
pages/product/item/index.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="content">
+    <lucency-header :lang="lang" page-key="product" />
+    <item-banner :title="productTypeText" :sub-title="productTypeSubText"></item-banner>
+    <div class="conBox big-title">
+      <span >
+        {{}}
+      </span>
+      <div class="hr"></div>
+    </div>
+<!--    产品展示页面 -->
+<!--    页脚 -->
+    <default-footer :lang="lang"/>
+  </div>
+</template>
+
+<script>
+import langMap from "~/map/langMap";
+import { getTypeText,getTypeSubText, pTypes} from "~/map/productMap";
+
+export default {
+  name: "itemIndex",
+  props:['uLang','pType'],
+  data(){
+    return {
+      langType: langMap.lang,
+      lang: this.uLang?this.uLang:langMap.lang.cn,
+      productId: null,
+      types: pTypes,
+      type: '',
+      productTypeText: getTypeText(this.pType),
+      productTypeSubText: getTypeSubText(this.pType),
+      productDetail: {},
+    }
+  },
+  beforeMount() {
+    const queryString = window.location.search;
+    const params = new URLSearchParams(queryString);
+
+    if(params&&params.get('id')){
+      this.productId = params.get('id');
+    }else{
+      window.location.href = '/product'
+    }
+  },
+  mounted() {
+    console.log(this.pType);
+    console.log(this.type);
+    this.type = this.pType;
+  },
+  methods:{
+    getLangText(str) {
+      return langMap.getText(this.lang, str);
+    },
+    getAbbrText(str) {
+      return langMap.getAbbrText(this.lang, str);
+    },
+    async loadProductDetail(){
+      let err,res;
+      let url = `/api/getProduct?id=${this.productId}`
+      [err,res] = await handle(this.$axios.$get(url));
+      if(err){
+        console.error(err);
+        return alert(err.message);
+      }
+      let result = res.data;
+      if(result.rcode === 1){
+
+      }else{
+        console.log('not match result');
+        console.log(result);
+        return alert('加载产品失败!!!');
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.big-title {
+  margin: 5px auto;
+  justify-content: left;
+}
+</style>

+ 84 - 0
phpAPi/getProductPage.php

@@ -0,0 +1,84 @@
+<?php
+include('../conn_mysqli.php');
+include('../phpMode/rcodeMap.php');
+$key = $_POST['key'];
+$type = $_POST['type'] ? $_POST['type'] : 'all';
+// 设置 $page 的默认值为1,并限定取值范围在1-10之间
+$page = isset($_POST['page']) ? max(1, min(10, intval($_POST['page']))) : 1;
+// 设置 $limit 的默认值为20,并限定取值范围在1-100之间
+$limit = isset($_POST['limit']) ? max(1, min(100, intval($_POST['limit']))) : 20;
+$offset = ($page - 1) * $limit;
+
+header('Content-Type:text/json;charset=utf-8;');
+//echo "param:" . $key . "-" . $type . "-" . $limit . "-" . $offset . "   ";
+
+try {
+  $resObj = array(
+    'rcode' => Rcode_OK,
+    'data' => "",
+    'msg' => 'ok'
+  );
+  set_time_limit(50);
+  $conn = createConn();
+  $sql = "";
+  $stmt = null;
+//echo "fuck php not conn ?";
+  if ($type == "all") {
+    // 无条件全选
+    if (!empty($key)) {
+//      echo " \n php is low \n";
+      $sql = "SELECT count(*) as total  FROM mysql85931094_db.hfy_product as p  where p.name like '".$key."'";
+      $stmt = mysqli_prepare($conn, $sql);
+      mysqli_stmt_bind_param($stmt, "s", $key);
+    } else {
+//      echo " \n fuck php  \n";
+      $sql = 'SELECT count(*) as total
+FROM mysql85931094_db.hfy_product as p  ';
+      $stmt = mysqli_prepare($conn, $sql);
+//      mysqli_stmt_bind_param($stmt, "");
+    }
+  } else {
+    if (!empty($key)) {
+//      echo " \n fuck php ?  \n";
+      $sql = 'SELECT
+     count(*) as total
+FROM mysql85931094_db.hfy_product as p ,
+                mysql85931094_db.hfy_product_type as p_type
+           where p.type_id = p_type.type_id and p_type.type_key = ? and p.name like \''.$key.'\' ;';
+      $stmt = mysqli_prepare($conn, $sql);
+      mysqli_stmt_bind_param($stmt, "s", $type);
+    } else {
+//      echo " \n fuck fuck fuck  \n";
+      $sql = 'SELECT
+     count(*) as total
+FROM mysql85931094_db.hfy_product as p , mysql85931094_db.hfy_product_type as p_type
+           where p.type_id = p_type.type_id and p_type.type_key = ? ;';
+      $stmt = mysqli_prepare($conn, $sql);
+      mysqli_stmt_bind_param($stmt, "s", $type);
+    }
+  }
+
+  mysqli_stmt_execute($stmt);
+//  echo " fuck_2";
+  $res = mysqli_stmt_get_result($stmt);
+//  mysqli_stmt_get_result
+//  $rs = mysqli_fetch_assoc($res);
+  // 获取行数据
+//  $result = mysqli_stmt_get_result($stmt);
+//  $row = mysqli_fetch_array($result, MYSQLI_NUM);
+
+// 获取行数
+//  $count = $row[0];
+  $row = mysqli_fetch_array($res, MYSQLI_NUM);
+  mysqli_close($conn);
+  $resObj['data'] = array(
+    'count' => $row[0],
+    'limit' => $limit
+  );
+
+//  echo "fuck ".$res;
+  echo json_encode($resObj);
+}catch(Exception $e)
+{
+  echo 'server Error Message: notFound';
+}

+ 42 - 0
phpAPi/loadProduct.php

@@ -0,0 +1,42 @@
+<?php
+include('../conn_mysqli.php');
+include('../phpMode/rcodeMap.php');
+
+$key = $_GET['key'];
+// 设置 $page 的默认值为1,并限定取值范围在1-10之间
+$page = isset($_GET['p']) ? max(1, min(10, intval($_GET['p']))) : 1;
+// 设置 $limit 的默认值为10,并限定取值范围在1-100之间
+$limit = isset($_GET['l']) ? max(1, min(100, intval($_GET['l']))) : 10;
+$offset = ($page - 1) * $limit;
+// 返回值设定
+header('Content-Type:text/json;charset=utf-8;');
+$resObj = array(
+    'rcode'=>Rcode_OK,
+    'data'=>"",
+    'msg'=>'ok'
+);
+if(!isset($_GET['key'])){
+    $resObj['rcode'] = Rcode_NotParam;
+    $resObj['data'] = "";
+    $resObj['msg'] = "key is must set";
+    echo json_encode($resObj);
+    exit;
+}
+
+$conn = createConn();
+$sql = "SELECT p.proid as id,p.remark,p.name,p.image,p.source,p.sourceType FROM mysql85931094_db.hfy_product as p ,mysql85931094_db.hfy_product_type as p_type WHERE p.type_id = p_type.type_id and p_type.type_key = ? limit ?,?";
+// 创建stmt
+$stmt = mysqli_prepare($conn, $sql);
+// 绑定
+mysqli_stmt_bind_param($stmt, "sdd",$key, $offset,$limit);
+mysqli_stmt_execute($stmt);
+$res = mysqli_stmt_get_result($stmt);
+
+
+while($row = mysqli_fetch_assoc($res)) { $rs[] = $row; }
+
+mysqli_close($conn);
+$resObj['data'] = $rs ;
+echo json_encode($resObj);
+
+?>

+ 45 - 0
phpAPi/loadSolution.php

@@ -0,0 +1,45 @@
+<?php
+include('../conn_mysqli.php');
+include('../phpMode/rcodeMap.php');
+
+$key = $_GET['key'];
+// 设置 $page 的默认值为1,并限定取值范围在1-10之间
+$page = isset($_GET['p']) ? max(1, min(10, intval($_GET['p']))) : 1;
+// 设置 $limit 的默认值为10,并限定取值范围在1-100之间
+$limit = isset($_GET['l']) ? max(1, min(100, intval($_GET['l']))) : 10;
+$offset = ($page - 1) * $limit;
+$parentSolutionType = 1;
+// 返回值设定
+header('Content-Type:text/json;charset=utf-8;');
+$resObj = array(
+    'rcode'=>Rcode_OK,
+    'data'=>"",
+    'msg'=>'ok'
+);
+if(!isset($_GET['key'])){
+    $resObj['rcode'] = Rcode_NotParam;
+    $resObj['data'] = "";
+    $resObj['msg'] = "key is must set";
+    echo json_encode($resObj);
+    exit;
+}
+
+$conn = createConn();
+$sql = "SELECT news.id,news.remark,news.title as name,news.image,news.source_val as source,news.sourceType
+FROM mysql85931094_db.hfy_news as news ,mysql85931094_db.hfy_news_type as n_type
+WHERE news.type_id = n_type.type_id and n_type.parent_type = ? and n_type.type_key = ? limit ?,?";
+// 创建stmt
+$stmt = mysqli_prepare($conn, $sql);
+// 绑定
+mysqli_stmt_bind_param($stmt, "dsdd",$parentSolutionType,$key, $offset,$limit);
+mysqli_stmt_execute($stmt);
+$res = mysqli_stmt_get_result($stmt);
+
+
+while($row = mysqli_fetch_assoc($res)) { $rs[] = $row; }
+
+mysqli_close($conn);
+$resObj['data'] = $rs ;
+echo json_encode($resObj);
+
+?>

+ 86 - 0
phpAPi/searchProduct.php

@@ -0,0 +1,86 @@
+<?php
+include('../conn_mysqli.php');
+include('../phpMode/rcodeMap.php');
+$key = $_POST['key'];
+$type = $_POST['type'] ? $_POST['type'] : 'all';
+// 设置 $page 的默认值为1,并限定取值范围在1-10之间
+$page = isset($_POST['page']) ? max(1, min(10, intval($_POST['page']))) : 1;
+// 设置 $limit 的默认值为20,并限定取值范围在1-100之间
+$limit = isset($_POST['limit']) ? max(1, min(100, intval($_POST['limit']))) : 20;
+$offset = ($page - 1) * $limit;
+
+header('Content-Type:text/json;charset=utf-8;');
+try {
+  $resObj = array(
+    'rcode' => Rcode_OK,
+    'data' => "",
+    'msg' => 'ok'
+  );
+  set_time_limit(50);
+//  echo "param:" . $key . "-" . $type . "-" . $limit . "-" . $offset . "   ";
+//echo !empty($key)?"T":"F";
+//  echo $type == "all" ? "T" : "F";
+//exit;
+  $conn = createConn();
+  $sql = "";
+  $stmt = null;
+//echo "fuck php not conn ?";
+  if ($type == "all") {
+    // 无条件全选
+    if (!empty($key)) {
+//      echo " \n php is low \n";
+      $sql = 'SELECT p.proid as id,p.remark,p.name,p.image,p.source,p.sourceType,p_type.type_key
+FROM mysql85931094_db.hfy_product as p  , mysql85931094_db.hfy_product_type as p_type
+where p.type_id = p_type.type_id and p.name like \''.$key.'\' order by p.proid desc limit ?,?';
+    } else {
+//      echo " \n fuck php  \n";
+      $sql = 'SELECT p.proid as id,p.remark,p.name,p.image,p.source,p.sourceType,p_type.type_key
+FROM mysql85931094_db.hfy_product as p , mysql85931094_db.hfy_product_type as p_type
+where p.type_id = p_type.type_id order by p.proid desc  limit ?,?';
+
+    }
+    $stmt = mysqli_prepare($conn, $sql);
+    mysqli_stmt_bind_param($stmt, "dd", $offset, $limit);
+  } else {
+    if (!empty($key)) {
+//      echo " \n fuck php ?  \n";
+      $sql = 'SELECT
+     p.proid as id,p.remark,p.name,p.image,p.source,p.sourceType,p_type.type_key
+FROM mysql85931094_db.hfy_product as p ,
+                mysql85931094_db.hfy_product_type as p_type
+           where p.type_id = p_type.type_id and p_type.type_key = ? and p.name like \''.$key.'\' order by p.proid desc  limit ?,?';
+      $stmt = mysqli_prepare($conn, $sql);
+      mysqli_stmt_bind_param($stmt, "ssdd", $type, $key, $offset, $limit);
+    } else {
+//      echo " \n fuck fuck fuck  \n";
+      $sql = 'SELECT
+     p.proid as id,p.remark,p.name,p.image,p.source,p.sourceType,p_type.type_key
+FROM mysql85931094_db.hfy_product as p , mysql85931094_db.hfy_product_type as p_type
+           where p.type_id = p_type.type_id and p_type.type_key = ? order by p.proid desc limit ?,?';
+      $stmt = mysqli_prepare($conn, $sql);
+      mysqli_stmt_bind_param($stmt, "sdd", $type, $offset, $limit);
+    }
+  }
+//  echo "fuck_1";
+  mysqli_stmt_execute($stmt);
+//  echo " fuck_2";
+  $res = mysqli_stmt_get_result($stmt);
+//  echo " fuck_3";
+//  echo "fuck ---------------";
+//  echo $res;
+//  echo "fuck " ;
+  while ($row = mysqli_fetch_assoc($res)) {
+    $rs[] = $row;
+  }
+//  echo "???????????????? ";
+//  echo "???????????????? ".$res;
+  mysqli_close($conn);
+  $resObj['data'] = $rs;
+//  echo "fuck ".$res;
+  echo json_encode($resObj);
+}catch(Exception $e)
+{
+//  echo 'Message: ' .$e->getMessage();
+  echo 'server Error Message: notFound';
+}
+?>

ファイルの差分が大きいため隠しています
+ 307 - 307
yarn.lock


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません