wuheng преди 1 година
родител
ревизия
b396423768
променени са 13 файла, в които са добавени 296 реда и са изтрити 39 реда
  1. 6 0
      package-lock.json
  2. 1 0
      package.json
  3. 8 0
      src/api/prodinfo.js
  4. 3 1
      src/api/shopcart.js
  5. 5 0
      src/components/Tabber.vue
  6. 2 1
      src/main.js
  7. 5 0
      src/router/index.js
  8. 5 0
      src/utils/mitt.js
  9. 8 0
      src/utils/util.js
  10. 1 1
      src/views/Category.vue
  11. 14 4
      src/views/Home.vue
  12. 175 0
      src/views/ProdInfo.vue
  13. 63 32
      src/views/ShopCart.vue

+ 6 - 0
package-lock.json

@@ -13,6 +13,7 @@
         "babel-plugin-import": "^1.13.6",
         "babel-plugin-import": "^1.13.6",
         "core-js": "^3.8.3",
         "core-js": "^3.8.3",
         "crypto-js": "^4.1.1",
         "crypto-js": "^4.1.1",
+        "mitt": "^3.0.1",
         "vant": "^2.12.54",
         "vant": "^2.12.54",
         "vue": "^2.6.14",
         "vue": "^2.6.14",
         "vue-router": "^3.5.1",
         "vue-router": "^3.5.1",
@@ -6758,6 +6759,11 @@
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "dev": true
       "dev": true
     },
     },
+    "node_modules/mitt": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
+      "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
+    },
     "node_modules/mkdirp": {
     "node_modules/mkdirp": {
       "version": "0.5.6",
       "version": "0.5.6",
       "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz",
       "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz",

+ 1 - 0
package.json

@@ -12,6 +12,7 @@
     "babel-plugin-import": "^1.13.6",
     "babel-plugin-import": "^1.13.6",
     "core-js": "^3.8.3",
     "core-js": "^3.8.3",
     "crypto-js": "^4.1.1",
     "crypto-js": "^4.1.1",
+    "mitt": "^3.0.1",
     "vant": "^2.12.54",
     "vant": "^2.12.54",
     "vue": "^2.6.14",
     "vue": "^2.6.14",
     "vue-router": "^3.5.1",
     "vue-router": "^3.5.1",

+ 8 - 0
src/api/prodinfo.js

@@ -0,0 +1,8 @@
+import { post, get } from '../utils/request'
+
+
+export const prodInfo = (data) => get("/prod/prodInfo", data)
+
+export const prodCommData = (data) => get("/prodComm/prodCommData", data)
+
+export const isCollection = (data) => get("/p/user/collection/isCollection", data)

+ 3 - 1
src/api/shopcart.js

@@ -4,4 +4,6 @@ export const shopCartInfo = (data) => post("/p/shopCart/info", data)
 
 
 export const prodCount = () => get("/p/shopCart/prodCount")
 export const prodCount = () => get("/p/shopCart/prodCount")
 
 
-export const totalPay = (data) => post("/p/shopCart/totalPay", data)
+export const totalPay = (data) => post("/p/shopCart/totalPay", data)
+
+export const changeItem = (data) => post("/p/shopCart/changeItem", data)

+ 5 - 0
src/components/Tabber.vue

@@ -8,6 +8,7 @@
 </template>
 </template>
 <script>
 <script>
 import { prodCount } from '@/api/shopcart'
 import { prodCount } from '@/api/shopcart'
+import emitter from '../utils/mitt'
 export default {
 export default {
     data() {
     data() {
         return {
         return {
@@ -15,6 +16,10 @@ export default {
             count: 0
             count: 0
         }   
         }   
     },
     },
+    created(){
+        this.onChange()
+        emitter.on('changeItem', e => this.onChange() )
+    },
     methods: {
     methods: {
         async onChange(){
         async onChange(){
             this.count = await prodCount()
             this.count = await prodCount()

+ 2 - 1
src/main.js

@@ -8,9 +8,10 @@ import {
   Image as VanImage, Form, Field, Search, CheckboxGroup,
   Image as VanImage, Form, Field, Search, CheckboxGroup,
   Swipe, Grid, GridItem, NoticeBar, Checkbox, Col, Cell,
   Swipe, Grid, GridItem, NoticeBar, Checkbox, Col, Cell,
   Button, Tabbar, TabbarItem, SwipeItem, Tag, Row, CellGroup,
   Button, Tabbar, TabbarItem, SwipeItem, Tag, Row, CellGroup,
-  TreeSelect, Card, Empty, SubmitBar, Stepper, Divider
+  TreeSelect, Card, Empty, SubmitBar, Stepper, Divider, Icon
 } from 'vant';
 } from 'vant';
 
 
+Vue.use(Icon)
 Vue.use(Cell);
 Vue.use(Cell);
 Vue.use(CellGroup);
 Vue.use(CellGroup);
 Vue.use(Divider);
 Vue.use(Divider);

+ 5 - 0
src/router/index.js

@@ -7,6 +7,7 @@ import Home from '../views/Home.vue'
 import Category from '../views/Category.vue'
 import Category from '../views/Category.vue'
 import ShopCart from '../views/ShopCart.vue'
 import ShopCart from '../views/ShopCart.vue'
 import Layout from '../components/Layout.vue'
 import Layout from '../components/Layout.vue'
+import Prodinfo from '../views/ProdInfo.vue'
 
 
 Vue.use(VueRouter)
 Vue.use(VueRouter)
 
 
@@ -46,6 +47,10 @@ const routes = [
     path: '/register',
     path: '/register',
     name: 'register',
     name: 'register',
     component: Register
     component: Register
+  },{
+    path: '/prodinfo',
+    name: 'prodinfo',
+    component: Prodinfo
   }
   }
 ]
 ]
 
 

+ 5 - 0
src/utils/mitt.js

@@ -0,0 +1,5 @@
+import mitt from 'mitt'
+
+const emitter = mitt()
+
+export default emitter

+ 8 - 0
src/utils/util.js

@@ -0,0 +1,8 @@
+export const formatHtml = content => {
+    content = content.replace(/\<img/gi, '<img style="width:100% !important;height:auto !important;margin:0;display:flex;" ');
+    content = content.replace(/\<td/gi, '<td  cellspacing="0" cellpadding="0" border="0" style="display:block;vertical-align:top;margin: 0px; padding: 0px; border: 0px;outline-width:0px;" ');
+    content = content.replace(/width=/gi, 'sss=');
+    content = content.replace(/height=/gi, 'sss=');
+    content = content.replace(/ \/\>/gi, ' style="max-width:100% !important;height:auto !important;margin:0;display:block;" \/\>');
+    return content;
+}

+ 1 - 1
src/views/Category.vue

@@ -7,7 +7,7 @@
                 <!-- 分类类型图片 banner -->
                 <!-- 分类类型图片 banner -->
                 <van-image v-if="categoryInfo[active]" :src="categoryInfo[active].pic" />
                 <van-image v-if="categoryInfo[active]" :src="categoryInfo[active].pic" />
                 <!-- 当前分类下的商品 -->
                 <!-- 当前分类下的商品 -->
-                <van-card v-for="item in prodList.records" :num="item.totalStocks" :price="item.price" :desc="item.brief" :title="item.prodName" :thumb="item.pic" />
+                <van-card v-for="(item, index) in prodList.records" :key="index" :num="item.totalStocks" :price="item.price" :desc="item.brief" :title="item.prodName" :thumb="item.pic" />
                 <!-- 如果没有商品 展示默认信息 -->
                 <!-- 如果没有商品 展示默认信息 -->
                 <van-empty v-if="prodList.records <= 0" description="当前分类没有商品" />
                 <van-empty v-if="prodList.records <= 0" description="当前分类没有商品" />
             </template>
             </template>

+ 14 - 4
src/views/Home.vue

@@ -22,25 +22,25 @@
         <!-- 通知栏 -->
         <!-- 通知栏 -->
         <van-notice-bar left-icon="volume-o" :scrollable="false">
         <van-notice-bar left-icon="volume-o" :scrollable="false">
             <van-swipe vertical class="notice-swipe" :autoplay="3000" :show-indicators="false">
             <van-swipe vertical class="notice-swipe" :autoplay="3000" :show-indicators="false">
-                <van-swipe-item v-for="item in noticeList.records">{{ item.title }}</van-swipe-item>
+                <van-swipe-item v-for="item in noticeList.records" :key="item.title">{{ item.title }}</van-swipe-item>
             </van-swipe>
             </van-swipe>
         </van-notice-bar>
         </van-notice-bar>
 
 
         <!-- 商品列表 -->
         <!-- 商品列表 -->
         <div class="produc-list">
         <div class="produc-list">
             <div style="width: 100%; height: 2rem;"></div>
             <div style="width: 100%; height: 2rem;"></div>
-            <template v-for="tag in tagProdList">
+            <div v-for="(tag, index) in tagProdList" :key="index">
                 <div class="list-title">
                 <div class="list-title">
                     <span class="title">{{ tag.title }}</span><span class="more">查看更多</span>
                     <span class="title">{{ tag.title }}</span><span class="more">查看更多</span>
                 </div>
                 </div>
                 <van-grid :border="false" :column-num="3">
                 <van-grid :border="false" :column-num="3">
-                    <van-grid-item v-for="goods in tag.productDtoList">
+                    <van-grid-item @click="gotoDetils(goods)" v-for="goods in tag.productDtoList" :key="goods.prodId">
                         <van-image :src="goods.pic" fit="fill" />
                         <van-image :src="goods.pic" fit="fill" />
                         <div class="produc-info">{{ goods.prodName }}</div>
                         <div class="produc-info">{{ goods.prodName }}</div>
                         <div class="produc-price"> ¥{{ goods.price }}</div>
                         <div class="produc-price"> ¥{{ goods.price }}</div>
                     </van-grid-item>
                     </van-grid-item>
                 </van-grid>
                 </van-grid>
-            </template>
+            </div>
         </div>
         </div>
         <div style="height: 4rem"></div>
         <div style="height: 4rem"></div>
     </div>
     </div>
@@ -59,6 +59,16 @@ export default {
         this.images = await indexImgs()
         this.images = await indexImgs()
         this.noticeList = await noticeList()
         this.noticeList = await noticeList()
         this.tagProdList = await tagProdList()
         this.tagProdList = await tagProdList()
+    },
+    methods: {
+        gotoDetils(goods) {
+            this.$router.push({
+                path: "/prodinfo",
+                query: {
+                    prodId: goods.prodId
+                }
+            })
+        }
     }
     }
 }
 }
 </script>
 </script>

+ 175 - 0
src/views/ProdInfo.vue

@@ -0,0 +1,175 @@
+<template>
+    <div class="prod-info">
+        <!-- 轮播 -->
+        <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
+            <van-swipe-item v-if="prodData.imgs" v-for="(img, index) in prodData.imgs " :key="index">
+                <van-image alt="" :src="img" />
+            </van-swipe-item>
+        </van-swipe>
+
+        <van-divider />
+
+        <!-- 商品信息介绍 -->
+        <div class="prod-title">
+            <van-row>
+                <van-col class="prod-title-name" span="18">
+                    {{ prodData.prodName }}
+                </van-col>
+                <van-col span="6" class="prod-title-icon">
+                    <div>
+                        <van-icon v-if="!isCollection" name="like-o" size="20" /> 
+                        <van-icon v-if="isCollection" style="color:red" name="like" size="20" /> 
+                        <span> 收藏</span>
+                    </div>
+                </van-col>
+            </van-row>
+            <van-row>
+                <van-col span="20" class="prod-title-brief">
+                    {{ prodData.brief }}
+                </van-col>
+                <van-col span="4" class="prod-title-icon">
+                </van-col>
+            </van-row>
+            <van-row>
+                <van-col class="prod-title-name prod-title-price" span="20">
+                    ¥<span class="title-price">{{ prodData.price }}</span>
+                </van-col>
+                <van-col span="4" class="prod-title-icon">
+                </van-col>
+            </van-row>
+        </div>
+
+        <!-- 分割线 -->
+        <van-divider :style="{ border: '.5rem solid #ebedf0' }" />
+
+        <!-- 类别 -->
+        <div class="prod-categray">
+            <span class="left">已选 </span> {{ skuList[0].skuName }} <span class="right">...</span>
+        </div>
+
+        <!-- 分割线 -->
+        <van-divider :style="{ border: '.5rem solid #ebedf0', marginBottom: 0 }" />
+
+        <!-- 评价信息 -->
+        <van-cell title-style="cell-title" center value="共0条" is-link>
+            <!-- 使用 title 插槽来自定义标题 -->
+            <template #title>
+                <span class="custom-title">评价: </span>
+                <span>好评{{ commData.positiveRating }}%</span>
+            </template>
+        </van-cell>
+        <van-grid :column-num="5" :border="false">
+            <van-grid-item ><van-tag type="warning">全部({{ commData.number }})</van-tag></van-grid-item>
+            <van-grid-item ><van-tag type="warning">好评({{ commData.praiseNumber }})</van-tag></van-grid-item>
+            <van-grid-item ><van-tag type="warning">中评({{ commData.secondaryNumber }})</van-tag></van-grid-item>
+            <van-grid-item ><van-tag type="warning">差评({{ commData.negativeNumber }})</van-tag></van-grid-item>
+            <van-grid-item ><van-tag type="warning">有图({{ commData.picNumber }})</van-tag></van-grid-item>
+        </van-grid>
+        <div class="content" v-html="formatHtml(prodData.content)"></div>
+        <div style="height: 5rem;"> </div>
+    </div>
+</template>
+<script>
+import { prodInfo, prodCommData, isCollection } from '../api/prodinfo'
+import { formatHtml } from '../utils/util'
+export default {
+    data() {
+        return {
+            prodId: 0,
+            prodData: {},
+            skuList: [],
+            transport: {},
+            commData: {
+                positiveRating: 0,
+                number: 0,
+                praiseNumber: 0,
+                secondaryNumber: 0,
+                negativeNumber: 0,
+                picNumber: 0
+            }
+        }
+    },
+    async created() {
+        this.prodId = this.$route.query.prodId
+        const prod = await prodInfo({ prodId: this.prodId })
+        this.skuList = prod.skuList
+        this.transport = prod.transport
+        prod.imgs = prod.imgs.split(",")
+        this.prodData = prod
+        this.commData = await prodCommData({ prodId: this.prodId })
+        this.isCollection = await isCollection({ prodId: this.prodId })
+    },
+    methods:{
+        formatHtml(t){
+            return formatHtml(t)
+        }
+    }
+}
+</script>
+<style lang="less">
+.van-tag--warning {
+    background-color: #ff976a;
+    padding: 0.3rem;
+}
+.prod-info {
+    padding: auto;
+    .van-cell {
+        .van-cell__title {
+            text-align: left;
+        }
+    }
+    .content{
+        padding: 0%;
+    }
+    .prod-categray {
+        height: 1rem;
+        line-height: 1rem;
+        text-align: left;
+        padding-left: 1rem;
+        font-weight: 700;
+
+        .left {
+            font-size: .9rem;
+            color: grey;
+            font-weight: 200;
+        }
+
+        .right {
+            text-align: right;
+            float: right;
+            margin-right: 1rem;
+            font-weight: 200;
+        }
+    }
+
+    .prod-title {
+        .prod-title-brief {
+            height: 3rem;
+            padding-left: 1rem;
+            text-align: left;
+            font-size: .6rem;
+            color: #595959;
+        }
+
+        .prod-title-price {
+            color: red;
+
+            .title-price {
+                font-size: 1.5rem;
+                font-weight: 500;
+            }
+        }
+
+        .prod-title-name {
+            height: 3rem;
+            padding-left: 1rem;
+            text-align: left;
+        }
+
+        .prod-title-icon {
+            height: 3rem;
+            line-height: 3rem;
+            padding-right: 1rem;
+        }
+    }
+}</style>

+ 63 - 32
src/views/ShopCart.vue

@@ -3,35 +3,47 @@
         <van-search placeholder="请输入搜索关键词" />
         <van-search placeholder="请输入搜索关键词" />
         <div style="height: 1rem;"></div>
         <div style="height: 1rem;"></div>
         <div class="cards-list">
         <div class="cards-list">
-            <div  v-for="shop in shopCartInfo" :key="shop.shopId">
-                <van-row v-for="items in shop.shopCartItemDiscounts[0].shopCartItems">
-                    <van-col span="2">
-                        <van-checkbox-group v-model="result" ref="checkboxGroup">
-                            <van-checkbox :name="items.basketId"></van-checkbox>
-                        </van-checkbox-group>
-                    </van-col>
-                    <van-col span="22">
-                        <span class="shop-name">{{ shop.shopName }}</span>
-                        <van-card :num="items.prodCount" :price="items.price" 
-                            :desc="items.skuName" :title="items.prodName"
-                            :thumb="items.pic">
-                            <template #tags>
-                                <!-- 暂时没有 -->
-                                <!-- <van-tag plain type="danger">标签</van-tag> -->
-                                <!-- <van-tag plain type="danger">标签</van-tag> -->
-                            </template>
-                            <template #footer>
-                                <van-stepper v-model="value" integer />
-                            </template>
-                        </van-card>
-                    </van-col>
-                </van-row>
-                <van-divider  />
-            </div>
+            <van-checkbox-group v-model="basketIds" ref="checkboxGroup">
+                <div v-for="shop in shopCartInfo" :key="shop.shopId">
+                    <van-row v-for="items in shop.shopCartItemDiscounts[0].shopCartItems" :key="items.basketId">
+                        <van-col span="2">
+                            <van-checkbox @click="basketClick" :name="items.basketId"></van-checkbox>
+                        </van-col>
+                        <van-col span="22">
+                            <span class="shop-name">{{ shop.shopName }}</span>
+                            <van-card :num="items.prodCount" :price="items.price" :desc="items.skuName"
+                                :title="items.prodName" :thumb="items.pic">
+                                <template #tags>
+                                    <!-- 暂时没有 -->
+                                    <!-- <van-tag plain type="danger">标签</van-tag> -->
+                                    <!-- <van-tag plain type="danger">标签</van-tag> -->
+                                </template>
+                                <template #footer>
+                                    <van-stepper :value="items.prodCount" async-change @change="(value)=>{
+                                        if ( items.prodCount === value ) {
+                                            return 
+                                        }
+                                        let count = 1
+                                        if ( items.prodCount > value ) {
+                                            count = -1
+                                        }
+                                        onStepperChange(items, count, ()=>{
+                                            items.prodCount = value
+                                            basketClick()
+                                        })
+                                    }" integer />
+                                </template>
+                            </van-card>
+                        </van-col>
+                    </van-row>
+                    <van-divider />
+                </div>
+            </van-checkbox-group>
         </div>
         </div>
+        <van-empty v-if="shopCartInfo <= 0" />
         <div style="height: 7rem;"></div>
         <div style="height: 7rem;"></div>
         <van-submit-bar :price="totalMoney" button-text="提交订单" @submit="onSubmit">
         <van-submit-bar :price="totalMoney" button-text="提交订单" @submit="onSubmit">
-            <van-checkbox v-model="checked">全选</van-checkbox>
+            <van-checkbox v-model="checked" @click="allProdSelected">全选</van-checkbox>
             <template #tip>
             <template #tip>
                 你的收货地址不支持同城送, <span @click="onClickEditAddress">修改地址</span>
                 你的收货地址不支持同城送, <span @click="onClickEditAddress">修改地址</span>
             </template>
             </template>
@@ -39,26 +51,45 @@
     </div>
     </div>
 </template>
 </template>
 <script>
 <script>
-import { shopCartInfo } from '@/api/shopcart';
+import { shopCartInfo, totalPay, changeItem } from '@/api/shopcart'
+import emitter from '../utils/mitt'
 export default {
 export default {
     data() {
     data() {
         return {
         return {
             checked: false,
             checked: false,
             shopCartInfo: [],
             shopCartInfo: [],
             value: 0,
             value: 0,
-            result: [],
+            basketIds: [],
             totalMoney: 0
             totalMoney: 0
-        }
+        };
     },
     },
     async created() {
     async created() {
-        this.shopCartInfo = await shopCartInfo({})
+        this.shopCartInfo = await shopCartInfo({});
     },
     },
     methods: {
     methods: {
+        onStepperChange(items, value, callback) {
+            changeItem({
+                basketId: items.basketId,
+                prodId: items.prodId,
+                skuId: items.skuId,
+                shopId: items.shopId,
+                count: value,
+                distributionCardNo: ""
+            });
+            callback();
+            emitter.emit("changeItem")
+        },
+        allProdSelected() {
+            this.$refs.checkboxGroup.toggleAll(this.checked);
+            this.basketClick();
+        },
+        async basketClick() {
+            const result = await totalPay(this.basketIds);
+            this.totalMoney = result.finalMoney * 100;
+        },
         onSubmit() {
         onSubmit() {
-
         },
         },
         onClickEditAddress() {
         onClickEditAddress() {
-
         }
         }
     }
     }
 }
 }