You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
434 lines
10 KiB
434 lines
10 KiB
<template>
|
|
<div class="bg">
|
|
<div>
|
|
<div
|
|
class="order-products"
|
|
style="
|
|
padding: 0 20px;
|
|
background: #f8f9fa;
|
|
border-top: 1px solid #eee;
|
|
border-bottom: 1px solid #eee;
|
|
margin-bottom: 20px;
|
|
"
|
|
>
|
|
<div class="product-item">
|
|
<div class="product-select">
|
|
<el-checkbox v-model="selectAll" @change="handleSelectAll"
|
|
>全选</el-checkbox
|
|
>
|
|
</div>
|
|
<div class="product-details">
|
|
<div class="product-name">商品</div>
|
|
</div>
|
|
<div class="product-box">单价(元)</div>
|
|
<div class="product-quantity">数量</div>
|
|
<div class="product-box">收货方式</div>
|
|
<div class="product-box">小计(元)</div>
|
|
<div class="product-box">操作</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 订单卡片 - 按商家合并商品 -->
|
|
<div class="order-card" v-for="shop in list" :key="shop.id">
|
|
<!-- 订单头部 - 包含商家信息 -->
|
|
<div class="order-header flex-between">
|
|
<div class="product-select">
|
|
<el-checkbox
|
|
v-model="shop.selected"
|
|
@change="handleSelectShop(shop)"
|
|
><span style="opacity: 0">全选</span></el-checkbox
|
|
>
|
|
</div>
|
|
<div class="product-details">
|
|
<div class="product-name">供应商名称:{{ shop.shop_name }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 订单商品列表 -->
|
|
<div class="order-products">
|
|
<div class="product-item" v-for="goods in shop.goods" :key="goods.id">
|
|
<div class="product-select">
|
|
<el-checkbox v-model="goods.selected" @change="handleSelect"
|
|
><span style="opacity: 0">全选</span></el-checkbox
|
|
>
|
|
</div>
|
|
<div class="product-details flex-between">
|
|
<img :src="goods.product.headimg" class="product-image" />
|
|
<div class="product-details">
|
|
<div class="product-name">{{ goods.product.title }}</div>
|
|
<div class="product-spec">{{ goods.sku.sku_name }}</div>
|
|
</div>
|
|
</div>
|
|
<div class="product-box">
|
|
¥{{ (goods.sku.price / 100).toFixed(2) }}
|
|
</div>
|
|
<div class="product-quantity">
|
|
<el-input-number
|
|
size="small"
|
|
v-model="goods.num"
|
|
@change="handleNumChange(goods)"
|
|
:min="1"
|
|
:step="1"
|
|
/>
|
|
</div>
|
|
<div class="product-box">邮寄</div>
|
|
<div class="product-box product-price">
|
|
¥{{ ((goods.num * goods.sku.price) / 100).toFixed(2) }}
|
|
</div>
|
|
<div class="product-box">
|
|
<el-button type="text" size="mini" @click="delItem(goods)"
|
|
>删除</el-button
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<el-empty description="暂无数据" v-if="list.length <= 0"></el-empty>
|
|
|
|
<!-- 分页 -->
|
|
<!-- <div style="text-align: right; margin-top: 20px;">
|
|
<el-pagination
|
|
@size-change="handleSizeChange"
|
|
@current-change="handleCurrentChange"
|
|
:current-page="currentPage"
|
|
:page-sizes="[5, 10, 20]"
|
|
:page-size="pageSize"
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
:total="list.length"
|
|
></el-pagination>
|
|
</div> -->
|
|
<div class="cart-footer">
|
|
<el-button
|
|
:disabled="selectedRows.length === 0"
|
|
type="text"
|
|
size="mini"
|
|
@click="deleteSelected"
|
|
>
|
|
删除选中商品
|
|
</el-button>
|
|
<div class="flex-between">
|
|
<div class="selected-info">
|
|
已选商品
|
|
<span class="import-text">{{ selectedRows.length }}</span> 件
|
|
总价:
|
|
<span class="import-text total-price">{{ totalPrice }}</span>
|
|
(不含运费)
|
|
</div>
|
|
<el-button
|
|
type="primary"
|
|
:disabled="selectedRows.length === 0"
|
|
@click="handleCheckout"
|
|
>去结算</el-button
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapActions } from "vuex";
|
|
export default {
|
|
name: "OrderList",
|
|
data() {
|
|
return {
|
|
activeTab: "all",
|
|
currentPage: 1,
|
|
pageSize: 10,
|
|
|
|
// 订单数据 - 按商家合并商品
|
|
list: [],
|
|
selectAll: false,
|
|
};
|
|
},
|
|
mounted() {
|
|
this.getList();
|
|
},
|
|
computed: {
|
|
selectedRows() {
|
|
let rows = [];
|
|
this.list.forEach((v) => {
|
|
v.goods.forEach((goods) => {
|
|
if (goods.selected) {
|
|
rows.push(goods);
|
|
}
|
|
});
|
|
});
|
|
return rows;
|
|
},
|
|
totalPrice() {
|
|
let price = 0;
|
|
this.selectedRows.forEach((v) => {
|
|
price += (v.num * v.sku.price) / 100;
|
|
});
|
|
return price.toFixed(2);
|
|
},
|
|
},
|
|
methods: {
|
|
...mapActions(["submitOrderData"]),
|
|
// 去结算
|
|
handleCheckout() {
|
|
// 构建参数数组(多个商品)
|
|
console.log(this.selectedRows);
|
|
const orderItems = this.selectedRows.map((goods) => ({
|
|
product: goods.product,
|
|
sku: goods.sku,
|
|
quantity: goods.num, // 购买数量(购物车中数量字段为num)
|
|
}));
|
|
|
|
// 按供应商分组(下单页需要按供应商展示)
|
|
const supplierGroups = {};
|
|
orderItems.forEach((item) => {
|
|
const supplier = item.product.supplier_name;
|
|
if (!supplierGroups[supplier]) {
|
|
supplierGroups[supplier] = [];
|
|
}
|
|
supplierGroups[supplier].push(item);
|
|
});
|
|
|
|
// Vuex传递
|
|
this.submitOrderData({
|
|
from: "cart",
|
|
groups: supplierGroups, // 按供应商分组的商品数组
|
|
});
|
|
this.$router.push("/Order");
|
|
},
|
|
getList() {
|
|
this.post({ customBaseURL: "/api" }, "/api/cart/get_list", true).then(
|
|
(res) => {
|
|
let resData = res.data || [];
|
|
let currentSelectGoodsIds = this.selectedRows.map((v) => v.id);
|
|
resData.forEach((item) => {
|
|
item.selected = false;
|
|
item.goods.forEach((goods) => {
|
|
goods.selected = currentSelectGoodsIds.includes(goods.id);
|
|
});
|
|
});
|
|
this.list = resData;
|
|
this.judgeSelectAll();
|
|
}
|
|
);
|
|
},
|
|
handleSelectAll(val) {
|
|
if (val) {
|
|
this.list.forEach((t) => {
|
|
t.goods.forEach((v) => {
|
|
if (v && v.product && v.sku && v.sku.flag == "off") {
|
|
v.selected = false;
|
|
} else {
|
|
v.selected = true;
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
this.cartList.forEach((t) => {
|
|
t.selected = false;
|
|
});
|
|
}
|
|
this.judgeSelectAll();
|
|
},
|
|
handleSelectShop(shop) {
|
|
if (shop.selected) {
|
|
shop.goods.forEach((v) => {
|
|
if (v && v.product && v.sku && v.sku.flag == "off") {
|
|
v.selected = false;
|
|
} else {
|
|
v.selected = true;
|
|
}
|
|
});
|
|
}
|
|
this.judgeSelectAll();
|
|
},
|
|
handleSelect() {
|
|
this.judgeSelectAll();
|
|
},
|
|
// 判断全选
|
|
judgeSelectAll() {
|
|
this.list.forEach((v) => {
|
|
if (v.goods.some((x) => x.sku.flag == "on")) {
|
|
if (v.goods.some((x) => x.sku.flag == "on" && !x.selected)) {
|
|
v.selected = false;
|
|
} else {
|
|
v.selected = true;
|
|
}
|
|
} else {
|
|
v.selected = false;
|
|
}
|
|
});
|
|
|
|
if (this.list.every((v) => v.selected) && this.list.length > 0) {
|
|
this.selectAll = true;
|
|
} else {
|
|
this.selectAll = false;
|
|
}
|
|
},
|
|
|
|
// 购物车加减
|
|
handleNumChange(goods) {
|
|
this.post(
|
|
{ id: goods.id, num: goods.num, customBaseURL: "/api" },
|
|
"/api/cart/update_sku"
|
|
).then((res) => {});
|
|
},
|
|
|
|
delItem(item) {
|
|
this.post(
|
|
{ id: item.id, customBaseURL: "/api" },
|
|
"/api/cart/del_sku"
|
|
).then((res) => {
|
|
this.getList();
|
|
});
|
|
},
|
|
deleteSelected() {
|
|
let ids = this.selectedRows.map((v) => v.id).join(",");
|
|
this.post({ ids: ids, customBaseURL: "/api" }, "/api/cart/del_skus").then(
|
|
(res) => {
|
|
this.getList();
|
|
}
|
|
);
|
|
},
|
|
|
|
// 分页大小改变
|
|
handleSizeChange(val) {
|
|
this.pageSize = val;
|
|
},
|
|
|
|
// 当前页改变
|
|
handleCurrentChange(val) {
|
|
this.currentPage = val;
|
|
},
|
|
|
|
// 去付款
|
|
payOrder(orderId) {
|
|
this.$message({
|
|
message: `订单 ${orderId} 去付款`,
|
|
type: "info",
|
|
});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.bg {
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
::v-deep .el-button--text {
|
|
color: #6a8a27;
|
|
}
|
|
::v-deep .el-tabs__item.is-active {
|
|
color: #6a8a27;
|
|
}
|
|
::v-deep .el-tabs__active-bar {
|
|
background-color: #6a8a27;
|
|
}
|
|
::v-deep .el-tabs__item:hover {
|
|
color: #6a8a27;
|
|
}
|
|
}
|
|
|
|
/* 订单卡片样式 */
|
|
.order-card {
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* 订单头部 - 包含商家信息 */
|
|
.order-header {
|
|
padding: 12px 20px;
|
|
display: flex;
|
|
align-items: center;
|
|
background: rgb(248, 249, 250);
|
|
border-bottom: 1px solid #999;
|
|
color: #666;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* 订单商品列表 */
|
|
.order-products {
|
|
padding: 10px 20px;
|
|
}
|
|
|
|
.product-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 15px 0;
|
|
border-bottom: 1px dashed #eee;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.product-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.product-image {
|
|
width: 80px;
|
|
height: 80px;
|
|
object-fit: cover;
|
|
margin-right: 15px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.product-details {
|
|
flex: 1;
|
|
}
|
|
|
|
.product-name {
|
|
color: #333;
|
|
}
|
|
|
|
.product-spec {
|
|
color: #999;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.product-box {
|
|
width: 100px;
|
|
text-align: center;
|
|
color: #333;
|
|
}
|
|
.product-quantity {
|
|
width: 160px;
|
|
text-align: center;
|
|
color: #333;
|
|
}
|
|
|
|
.product-select {
|
|
width: 80px;
|
|
color: #333;
|
|
}
|
|
.product-price {
|
|
color: #ff5252;
|
|
}
|
|
|
|
.cart-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-top: 10px;
|
|
padding: 15px;
|
|
background-color: #f5f7fa;
|
|
border-radius: 4px;
|
|
}
|
|
.selected-info {
|
|
color: #666;
|
|
font-size: 14px;
|
|
padding-right: 50px;
|
|
}
|
|
.import-text {
|
|
color: #c7020b;
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
}
|
|
.total-price {
|
|
&::before {
|
|
content: "¥";
|
|
margin-right: 5px;
|
|
font-size: 12px;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
|
|
|
|
|