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.
 
 

438 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"
@click="gotoDetail(goods.product.id)"
style="cursor: pointer"
>
<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"]),
// 去详情
gotoDetail(id) {
this.$router.push("/Detail/" + id);
},
// 去结算
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({}, "/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.list.forEach((t) => {
t.selected = false;
t.goods.forEach((v) => {
v.selected = false;
});
});
}
this.judgeSelectAll();
},
handleSelectShop(shop) {
if (shop.selected) {
shop.goods.forEach((v) => {
v.selected = false;
});
} else {
shop.goods.forEach((v) => {
v.selected = false;
});
}
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 }, "/api/cart/update_sku").then(
(res) => {}
);
},
delItem(item) {
this.post({ id: item.id }, "/api/cart/del_sku").then((res) => {
this.getList();
});
},
deleteSelected() {
let ids = this.selectedRows.map((v) => v.id).join(",");
this.post({ id: ids }, "/api/cart/del_sku").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;
background: #fff;
}
.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>