Browse Source

购物车和弹窗添加购物车

skyblued 3 năm trước cách đây
mục cha
commit
fd562dfb17

+ 8 - 0
src/router/routes-common.ts

@@ -105,6 +105,14 @@ export const router = [
     meta: {
       title: '商品详情'
     }
+  },
+  {
+    path: '/cart',
+    name: 'cart',
+    component: () => import('@/views/cart'),
+    meta: {
+      title: '购物车'
+    }
   }
 ]
 

+ 65 - 0
src/views/cart/index.module.less

@@ -0,0 +1,65 @@
+.cartBox {
+  padding: 15px;
+  :global {
+    --van-cart: #ff4e19;
+    --van-stepper-button-round-theme-color: var(--van-primary);
+  }
+}
+.submit {
+  :global {
+    .van-submit-bar__price {
+      color: var(--van-cart);
+    }
+  }
+}
+.delete {
+  :global {
+    .van-button {
+      margin-left: auto;
+    }
+  }
+}
+.cartItem {
+  display: flex;
+  align-items: center;
+  background: #fff;
+  border-radius: 11px;
+  padding-left: 12px;
+  margin-bottom: 10px;
+  :global {
+    .van-card {
+      background: #fff;
+      flex: 1;
+      margin: 0;
+      padding: 14px 12px;
+    }
+    .van-card__title {
+      font-size: 16px;
+      color: #333;
+      font-weight: 400;
+      line-height: 22px;
+      max-height: 44px;
+    }
+    .van-card__desc {
+      font-size: 14px;
+      color: #999;
+      font-weight: 400;
+      line-height: 20px;
+      max-height: 40px;
+      white-space: break-spaces;
+    }
+    .van-card__thumb {
+      width: auto;
+      height: auto;
+    }
+    .van-image {
+      width: 100px !important;
+      height: 100px !important;
+      border-radius: 8px;
+      overflow: hidden;
+    }
+    .van-card__price {
+      color: var(--van-cart);
+    }
+  }
+}

+ 163 - 0
src/views/cart/index.tsx

@@ -0,0 +1,163 @@
+import { defineComponent } from 'vue'
+import ColHeader from '@/components/col-header'
+import styles from './index.module.less'
+import { Checkbox, SubmitBar, Card, Stepper, CheckboxGroup } from 'vant'
+import request from '@/helpers/request'
+
+export default defineComponent({
+  name: 'cart',
+  data() {
+    return {
+      isManage: false,
+      cartList: [],
+      selectItems: []
+    }
+  },
+  computed: {
+    checkAll() {
+      let selectLen = this.selectItems.length as any
+      let cartLen = this.cartList.length as any
+      return selectLen === cartLen
+    },
+    len() {
+      let n = this.selectItems.length as any
+      return n
+    },
+    totalPrice() {
+      let price = 0
+      const items = this.selectItems as any
+      this.cartList.forEach((n: any) => {
+        if (items.includes(n.id) && typeof n.price === 'number') {
+          price += n.price * n.quantity
+        }
+      })
+      return price * 100
+    }
+  },
+  mounted() {
+    this.getCartList()
+  },
+  methods: {
+    async getCartList() {
+      this.cartList = []
+      try {
+        let { code, data } = await request.get('/api-mall-portal/cart/list')
+        code === 200 && (this.cartList = data)
+      } catch (err) {}
+    },
+    setCheckAll() {
+      const selectItems = [] as any
+      if (!this.checkAll) {
+        this.cartList.forEach((n: any) => {
+          selectItems.push(n.id)
+        })
+      }
+      this.selectItems = selectItems
+    },
+
+    async setCartItem(item: any) {
+      try {
+        let { code, data } = await request.get(
+          '/api-mall-portal/cart/update/quantity',
+          {
+            params: {
+              id: item.id,
+              quantity: item.quantity
+            }
+          }
+        )
+      } catch (err) {}
+    },
+
+    async onDeleteCartItem() {
+      const ids = this.selectItems.join(',')
+      try {
+        let { code, data } = await request.post(
+          '/api-mall-portal/cart/delete?ids=' + ids
+        )
+        if (code === 200) {
+          this.getCartList()
+          this.selectItems = []
+          this.isManage = false
+        }
+      } catch (error) {}
+    }
+  },
+  render() {
+    return (
+      <>
+        <ColHeader
+          isBack
+          onClickRight={() => (this.isManage = !this.isManage)}
+          v-slots={{
+            right: () => (
+              <span style={{ color: '#333', fontSize: '14px' }}>
+                {this.isManage ? '完成' : '管理'}
+              </span>
+            )
+          }}
+        ></ColHeader>
+        <div class={styles.cartBox}>
+          <CheckboxGroup v-model={this.selectItems}>
+            {this.cartList.map((item: any) => (
+              <div class={styles.cartItem}>
+                <Checkbox name={item.id} />
+                <Card
+                  price={((item.price * item.quantity * 100) / 100).toFixed(2)}
+                  desc={item.productAttr}
+                  title={item.productName}
+                  thumb={item.productPic}
+                  v-slots={{
+                    num: () => (
+                      <Stepper
+                        v-model={item.quantity}
+                        onChange={() => this.setCartItem(item)}
+                        inputWidth="50px"
+                        buttonSize="24px"
+                        min={1}
+                      />
+                    )
+                  }}
+                ></Card>
+              </div>
+            ))}
+          </CheckboxGroup>
+
+          {this.isManage ? (
+            <div class={styles.delete}>
+              <SubmitBar
+                buttonText="删除"
+                buttonColor="var(--van-primary)"
+                disabled={this.totalPrice === 0}
+                onSubmit={() => this.onDeleteCartItem()}
+              >
+                <Checkbox
+                  modelValue={this.checkAll}
+                  onClick={value => this.setCheckAll()}
+                >
+                  全选
+                </Checkbox>
+              </SubmitBar>
+            </div>
+          ) : (
+            <div class={styles.submit}>
+              <SubmitBar
+                price={this.totalPrice}
+                buttonText={`结算(${this.len})`}
+                buttonColor="var(--van-primary)"
+                disabled={this.totalPrice === 0}
+              >
+                <Checkbox
+                  modelValue={this.checkAll}
+                  onClick={value => this.setCheckAll()}
+                >
+                  全选
+                </Checkbox>
+              </SubmitBar>
+            </div>
+          )}
+        </div>
+      </>
+    )
+  }
+})

+ 43 - 7
src/views/shop-mall/modal/add-goods-cart/index.tsx

@@ -7,11 +7,13 @@ import {
   Radio,
   RadioGroup,
   Stepper,
-  Tag
+  Tag,
+  Toast
 } from 'vant'
 import { defineComponent } from 'vue'
 import styles from './index.module.less'
 import iconSellOut from '../../images/icon-sell-out.png'
+import request from '@/helpers/request'
 
 export default defineComponent({
   name: 'add-goods-cart',
@@ -29,8 +31,10 @@ export default defineComponent({
         pic: '',
         stock: 0,
         price: 0,
-        spDataJson: ''
-      }
+        spDataJson: '',
+        skuCode: ''
+      },
+      total: 1
     }
   },
   computed: {
@@ -58,19 +62,47 @@ export default defineComponent({
         }
       })
       // 处理默认显示
-      const { id, price, pic, stock, spDataJson } = skuStockList[0]
+      const { id, price, pic, stock, spDataJson, skuCode } = skuStockList[0]
       this.radio = id
       this.selectItem = {
         id,
         price,
         pic: pic || this.item.pic,
         stock,
-        spDataJson
+        spDataJson,
+        skuCode
       }
       return skuStockList
     }
   },
   mounted() {},
+  methods: {
+    async onAddCart() {
+      // console.log(this.total, this.selectItem, this.item)
+      const selectItem = this.selectItem
+      const item = this.item
+      const body = {
+        price: selectItem.price, //添加到购物车的价格
+        productCategoryId: item.productCategoryId, //商品分类
+        productName: item.name, // 商品名称
+        productPic: selectItem.pic, // 商品主图
+        productSkuCode: selectItem.skuCode, //商品sku条码
+        productSkuId: selectItem.id,
+        productSn: item.productSn,
+        productSubTitle: item.subTitle, // 副标题
+        quantity: this.total, // 数量
+        productId: item.id,
+        productAttr: selectItem.spDataJson
+      }
+      console.log(body)
+      try {
+        let { code, data } = await request.post('/api-mall-portal/cart/add', {
+          data: body
+        })
+        code === 200 && Toast('加入购物车成功')
+      } catch (error) {}
+    }
+  },
   render() {
     const item = this.item
     return (
@@ -126,14 +158,16 @@ export default defineComponent({
                       onClick={() => {
                         this.radio = item.id
                         // 处理默认显示
-                        const { id, price, pic, stock, spDataJson } = item
+                        const { id, price, pic, stock, spDataJson, skuCode } =
+                          item
                         this.radio = id
                         this.selectItem = {
                           id,
                           price,
                           pic: pic || this.item.pic,
                           stock,
-                          spDataJson
+                          spDataJson,
+                          skuCode
                         }
                       }}
                     >
@@ -155,6 +189,7 @@ export default defineComponent({
           center
         >
           <Stepper
+            v-model={this.total}
             inputWidth="50px"
             theme="round"
             buttonSize="24px"
@@ -170,6 +205,7 @@ export default defineComponent({
             type="primary"
             text="确定"
             disabled={this.selectItem.stock <= 0}
+            onClick={() => this.onAddCart()}
           />
         </div>
       </div>