wuheng hace 1 año
padre
commit
b396423768

+ 6 - 0
package-lock.json

@@ -13,6 +13,7 @@
         "babel-plugin-import": "^1.13.6",
         "core-js": "^3.8.3",
         "crypto-js": "^4.1.1",
+        "mitt": "^3.0.1",
         "vant": "^2.12.54",
         "vue": "^2.6.14",
         "vue-router": "^3.5.1",
@@ -6758,6 +6759,11 @@
       "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
       "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": {
       "version": "0.5.6",
       "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",
     "core-js": "^3.8.3",
     "crypto-js": "^4.1.1",
+    "mitt": "^3.0.1",
     "vant": "^2.12.54",
     "vue": "^2.6.14",
     "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 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>
 <script>
 import { prodCount } from '@/api/shopcart'
+import emitter from '../utils/mitt'
 export default {
     data() {
         return {
@@ -15,6 +16,10 @@ export default {
             count: 0
         }   
     },
+    created(){
+        this.onChange()
+        emitter.on('changeItem', e => this.onChange() )
+    },
     methods: {
         async onChange(){
             this.count = await prodCount()

+ 2 - 1
src/main.js

@@ -8,9 +8,10 @@ import {
   Image as VanImage, Form, Field, Search, CheckboxGroup,
   Swipe, Grid, GridItem, NoticeBar, Checkbox, Col, Cell,
   Button, Tabbar, TabbarItem, SwipeItem, Tag, Row, CellGroup,
-  TreeSelect, Card, Empty, SubmitBar, Stepper, Divider
+  TreeSelect, Card, Empty, SubmitBar, Stepper, Divider, Icon
 } from 'vant';
 
+Vue.use(Icon)
 Vue.use(Cell);
 Vue.use(CellGroup);
 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 ShopCart from '../views/ShopCart.vue'
 import Layout from '../components/Layout.vue'
+import Prodinfo from '../views/ProdInfo.vue'
 
 Vue.use(VueRouter)
 
@@ -46,6 +47,10 @@ const routes = [
     path: '/register',
     name: '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 -->
                 <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="当前分类没有商品" />
             </template>

+ 14 - 4
src/views/Home.vue

@@ -22,25 +22,25 @@
         <!-- 通知栏 -->
         <van-notice-bar left-icon="volume-o" :scrollable="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-notice-bar>
 
         <!-- 商品列表 -->
         <div class="produc-list">
             <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">
                     <span class="title">{{ tag.title }}</span><span class="more">查看更多</span>
                 </div>
                 <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" />
                         <div class="produc-info">{{ goods.prodName }}</div>
                         <div class="produc-price"> ¥{{ goods.price }}</div>
                     </van-grid-item>
                 </van-grid>
-            </template>
+            </div>
         </div>
         <div style="height: 4rem"></div>
     </div>
@@ -59,6 +59,16 @@ export default {
         this.images = await indexImgs()
         this.noticeList = await noticeList()
         this.tagProdList = await tagProdList()
+    },
+    methods: {
+        gotoDetils(goods) {
+            this.$router.push({
+                path: "/prodinfo",
+                query: {
+                    prodId: goods.prodId
+                }
+            })
+        }
     }
 }
 </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="请输入搜索关键词" />
         <div style="height: 1rem;"></div>
         <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>
+        <van-empty v-if="shopCartInfo <= 0" />
         <div style="height: 7rem;"></div>
         <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>
                 你的收货地址不支持同城送, <span @click="onClickEditAddress">修改地址</span>
             </template>
@@ -39,26 +51,45 @@
     </div>
 </template>
 <script>
-import { shopCartInfo } from '@/api/shopcart';
+import { shopCartInfo, totalPay, changeItem } from '@/api/shopcart'
+import emitter from '../utils/mitt'
 export default {
     data() {
         return {
             checked: false,
             shopCartInfo: [],
             value: 0,
-            result: [],
+            basketIds: [],
             totalMoney: 0
-        }
+        };
     },
     async created() {
-        this.shopCartInfo = await shopCartInfo({})
+        this.shopCartInfo = await shopCartInfo({});
     },
     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() {
-
         },
         onClickEditAddress() {
-
         }
     }
 }