| | |
| | | <template> |
| | | <div>购物车</div> |
| | | <div class="personalPage-box"> |
| | | <div class="personalPage-title">我的购物车</div> |
| | | <div class="personalPage-content"> |
| | | <div class="deleteBox"> |
| | | <el-dialog v-model="dialogVisible" width="30%" draggable align-center :modal="false"> |
| | | <span> |
| | | <el-icon style="color: orange"> <Warning /> </el-icon>确认要删除选中的商品吗?</span |
| | | > |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="dialogVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="handleDelete"> 确定 </el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <el-dialog v-model="showHide" width="30%" draggable align-center :modal="false"> |
| | | <span |
| | | ><el-icon style="color: orange"> <Warning /> </el-icon>确认要删除选中的商品吗?</span |
| | | > |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="showHide = false">取消</el-button> |
| | | <el-button type="primary" @click="confirmEvent"> 确定 </el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | <div class="selectproduct"> |
| | | <el-table |
| | | ref="multipleTableRef" |
| | | :data="shoppingCartData" |
| | | style="width: 100%" |
| | | @selection-change="handleSelectionChange" |
| | | :cell-style="cellStyle" |
| | | v-loading="loading" |
| | | > |
| | | <template v-slot:empty> |
| | | <el-empty class="noData" image-size="100" description="暂无数据" /> |
| | | </template> |
| | | |
| | | <el-table-column type="selection" width="30" /> |
| | | |
| | | <el-table-column label="全选" width="200"> |
| | | <template #default="scope"> |
| | | <div style="position: relative;width: 120px;"> |
| | | <el-image :src="scope.row.imgUrl ? scope.row.imgUrl : defaultImg" class="bookImg"> |
| | | </el-image> |
| | | <div |
| | | class="labelBox" |
| | | :style="{ |
| | | background: scope.row.type == 'product' ? '#019e58 ' : '#5f92fd', |
| | | }" |
| | | > |
| | | <p>{{ scope.row.typeTxt }}</p> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column property="name" label="商品信息" width="200" /> |
| | | <el-table-column property="productType" label="商品类型" width="200" /> |
| | | <el-table-column label="价格"> |
| | | <template #default="scope">¥{{ scope.row.unitprice.toFixed(2) }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="操作"> |
| | | <template #default="scope"> |
| | | <span @click="dialog(scope.$index, scope.row)" class="deleteBtn">删除</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | <div class="settlement"> |
| | | <div class="box"> |
| | | <div class="gaugeOutfit"> |
| | | <div class="leftBox"> |
| | | <el-checkbox |
| | | v-if="shoppingCartData.length" |
| | | class="checkbox" |
| | | v-model="selectAll" |
| | | label="全选" |
| | | name="type" |
| | | @change="toggleAllSelection" |
| | | /> |
| | | <el-checkbox |
| | | v-else |
| | | class="checkbox" |
| | | v-model="select" |
| | | disabled |
| | | label="全选" |
| | | name="type" |
| | | @change="toggleAllSelection" |
| | | /> |
| | | <el-button class="buttonBox" @click="batchDelete">批量删除</el-button> |
| | | </div> |
| | | |
| | | <div class="rightBox"> |
| | | <p> |
| | | 已选择 <span>{{ selectedItemCount }}</span> 件商品 |
| | | </p> |
| | | <p> |
| | | 总价:<span v-if="sumUnitprice">¥{{ sumUnitprice.toFixed(2) }}</span> |
| | | <span v-else>¥0.00</span> |
| | | </p> |
| | | <el-button class="button" type="primary" @click="goPaymentPage">结算</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { onMounted, ref, inject, watch } from 'vue' |
| | | import { ElTable, ElMessage } from 'element-plus' |
| | | import { reactive } from 'vue' |
| | | import { useRouter } from 'vue-router' |
| | | import { useUserStore } from '@/store' |
| | | import { getPublicImage } from '@/assets/js/middleGround/tool.js' |
| | | import defaultImg from '@/assets/images/default-book-img.png' |
| | | const dialogVisible = ref(false) |
| | | const router = useRouter() |
| | | const userStore = useUserStore() |
| | | const MG: any = inject('MG') |
| | | const total = ref() |
| | | const multipleTableRef = ref() |
| | | const loading = ref(true) |
| | | const selectAll = ref(false) |
| | | const multipleSelection = ref([]) |
| | | const orderNumber = ref() |
| | | const select = ref(false) |
| | | const showHide = ref(false) |
| | | const selectedItemCount = ref(0) // 新增一个变量用于存储已选商品数量 |
| | | const sumUnitprice = ref() |
| | | |
| | | watch(multipleSelection, (newSelection) => { |
| | | // 当 multipleSelection.value 发生变化时触发的回调函数 |
| | | let sum = 0 |
| | | newSelection.forEach((item) => { |
| | | sum += item.unitprice |
| | | }) |
| | | |
| | | sumUnitprice.value = sum |
| | | |
| | | selectedItemCount.value = newSelection.length |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | shoppingCartGet() |
| | | // totalPrice() |
| | | }) |
| | | const batchDelete = (evt) => { |
| | | let target = evt.target |
| | | if (target.nodeName == 'SPAN') { |
| | | target = evt.target.parentNode |
| | | } |
| | | target.blur() |
| | | if (multipleSelection.value.length === 0) { |
| | | // 如果没有选择任何商品,可以在此处给出提示或者直接返回 |
| | | ElMessage({ |
| | | message: '未选择商品', |
| | | type: 'warning', |
| | | }) |
| | | } else { |
| | | showHide.value = true |
| | | // showHide.value = false |
| | | } |
| | | } |
| | | |
| | | const handleSelectionChange = (val) => { |
| | | // console.log(val); |
| | | |
| | | multipleSelection.value = val |
| | | // 判断是否全部选择 |
| | | if (!delShoppingSelec.value) { |
| | | if (val.length === shoppingCartData.length) { |
| | | selectAll.value = true |
| | | } else { |
| | | selectAll.value = false |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 切换所有行选中状态的方法 |
| | | const toggleAllSelection = () => { |
| | | if (shoppingCartData.length === 0) { |
| | | selectAll.value = false |
| | | |
| | | ElMessage({ |
| | | message: '没有可选择的商品', |
| | | type: 'warning', |
| | | }) |
| | | } else { |
| | | multipleTableRef.value.toggleAllSelection() |
| | | } |
| | | } |
| | | const selectedRow = ref() |
| | | const dialog = (index, row) => { |
| | | dialogVisible.value = true |
| | | |
| | | // 将当前行数据存储起来,以备删除时使用 |
| | | selectedRow.value = row |
| | | } |
| | | |
| | | const handleDelete = () => { |
| | | const row = selectedRow.value |
| | | dialogVisible.value = false |
| | | MG.store |
| | | .delShoppingCart({ |
| | | ids: [row.id], |
| | | }) |
| | | .then((res) => { |
| | | shoppingCartGet() |
| | | ElMessage({ |
| | | message: '删除成功', |
| | | type: 'success', |
| | | }) |
| | | //更新购物车数量 |
| | | userStore.updateRightPop() |
| | | }) |
| | | .catch((error) => { |
| | | ElMessage.error('删除失败') |
| | | }) |
| | | } |
| | | |
| | | //表单的样式 |
| | | const cellStyle = ({ row, column, rowIndex, columnIndex }) => { |
| | | if (columnIndex === 4) { |
| | | return { color: '#019e58' } |
| | | } |
| | | } |
| | | |
| | | const shoppingCartData = reactive([]) |
| | | |
| | | const shoppingCartGet = () => { |
| | | let query = { |
| | | start: 0, |
| | | size: 999, |
| | | filterList: [], |
| | | searchList: [], |
| | | } |
| | | MG.store.getShoppingCartProductList(query).then((res) => { |
| | | const newData = res.datas.map((item) => { |
| | | item.typeTxt = '数字教材' |
| | | item.productType = '数字教材' |
| | | |
| | | // console.log(item.saleMethod.id); |
| | | console.log(item.saleMethod.type, 'item.saleMethod.type') |
| | | return { |
| | | saleMethodId: item.saleMethod.id, |
| | | id: item.id, |
| | | name: |
| | | item.linkCmsItems.length && item.linkCmsItems[0].name |
| | | ? item.productMonWithLinkDto.product.name + ':' + item.linkCmsItems[0].name |
| | | : item.productMonWithLinkDto.product.name, |
| | | type: item.saleMethod.type == 'createProductItemSaleMethod' ? 'item' : 'product', |
| | | typeTxt: item.typeTxt, |
| | | productType: item.productType, |
| | | imgUrl: getPublicImage(item.productMonWithLinkDto.product.icon, '', '160'), |
| | | unitprice: item.saleMethod.price, |
| | | expire: |
| | | new Date(item.saleMethod.endDate).getTime() < new Date().getTime() || |
| | | new Date().getTime() < new Date(item.saleMethod.beginDate).getTime() |
| | | ? true |
| | | : false, |
| | | } |
| | | }) |
| | | |
| | | // 重新赋值 shoppingCartData.value |
| | | shoppingCartData.splice(0, shoppingCartData.length, ...newData) |
| | | loading.value = false |
| | | }) |
| | | } |
| | | |
| | | //跳转面包屑 |
| | | const goPaymentPage = async () => { |
| | | try { |
| | | // console.log(multipleSelection.value, 346588998) |
| | | let expire = multipleSelection.value.filter((item) => item.expire == true) |
| | | if (expire.length > 0) { |
| | | ElMessage({ |
| | | message: '您选择的商品有不在有效期内的,请重新选择可购买商品!', |
| | | type: 'warning', |
| | | }) |
| | | } else { |
| | | const selectedIds = multipleSelection.value.map((item) => item.id) |
| | | const saleMethodId = multipleSelection.value.map((item) => item.saleMethodId) |
| | | |
| | | console.log(saleMethodId, 789) |
| | | |
| | | let queryCreateOrder = { linkIds: selectedIds } |
| | | const createOrderResult = await MG.store.shoppingCartCreateOrder(queryCreateOrder) |
| | | orderNumber.value = createOrderResult.orderNumber |
| | | |
| | | if (selectedIds.length) { |
| | | router.push({ |
| | | name: 'paymentPage', |
| | | query: { |
| | | orderNumber: orderNumber.value, |
| | | // type: route.query.type, |
| | | type: 'shoppingCart', |
| | | onNorderSaleMethod: saleMethodId, |
| | | }, |
| | | }) |
| | | } else { |
| | | ElMessage({ |
| | | message: '请选择商品', |
| | | type: 'warning', |
| | | }) |
| | | } |
| | | } |
| | | } catch (error) { |
| | | console.error(error) |
| | | // 错误处理逻辑 |
| | | } |
| | | } |
| | | |
| | | const delShoppingSelec = ref() |
| | | |
| | | const confirmEvent = () => { |
| | | showHide.value = false |
| | | if (multipleSelection.value.length === 0) { |
| | | // 如果没有选择任何商品,可以在此处给出提示或者直接返回 |
| | | return |
| | | } else { |
| | | const selectedIds = multipleSelection.value.map((item) => item.id) |
| | | MG.store |
| | | .delShoppingCart({ ids: selectedIds }) |
| | | .then((res) => { |
| | | delShoppingSelec.value = res |
| | | ElMessage({ |
| | | message: '批量删除成功', |
| | | type: 'success', |
| | | }) |
| | | selectAll.value = false |
| | | // 删除成功后,刷新购物车列表 |
| | | shoppingCartGet() |
| | | //更新购物车数量 |
| | | userStore.updateRightPop() |
| | | }) |
| | | .catch((error) => { |
| | | console.error('批量删除失败', error) |
| | | ElMessage.error('批量删除失败') |
| | | }) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .deleteBtn { |
| | | cursor: pointer; |
| | | color: #019e58; |
| | | } |
| | | |
| | | page { |
| | | position: relative; |
| | | min-height: calc(100vh - 430px); |
| | | } |
| | | |
| | | .bookImg { |
| | | box-shadow: 0px 3px 6px 1px rgba(0, 0, 0, 0.16); |
| | | |
| | | /deep/ .el-image__inner { |
| | | object-fit: contain !important; |
| | | } |
| | | } |
| | | |
| | | .settlement { |
| | | width: 100%; |
| | | box-shadow: 0px -2px 10px 1px rgba(0, 0, 0, 0.08); |
| | | |
| | | position: sticky; |
| | | |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background-color: #fff; |
| | | z-index: 2; |
| | | |
| | | .box { |
| | | position: relative; |
| | | |
| | | .gaugeOutfit { |
| | | padding-left: 12px; |
| | | box-shadow: 0px -2px 5px 1px rgba(0, 0, 0, 0.02); |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | position: sticky; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | z-index: 2; |
| | | background-color: #fff; |
| | | height: 60px; |
| | | |
| | | .leftBox { |
| | | display: flex; |
| | | flex-direction: row; |
| | | |
| | | .checkbox { |
| | | margin-right: 20px; |
| | | } |
| | | |
| | | /deep/ .el-checkbox__input.is-checked + .el-checkbox__label { |
| | | color: #000 !important; |
| | | } |
| | | } |
| | | |
| | | .rightBox { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | |
| | | p { |
| | | margin: 0 10px; |
| | | font-size: 14px; |
| | | |
| | | span { |
| | | color: #019e58; |
| | | font-size: 18px; |
| | | } |
| | | } |
| | | |
| | | .button { |
| | | margin-left: 50px; |
| | | background-color: #019e58; |
| | | width: 150px; |
| | | height: 50px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .selected { |
| | | display: flex; |
| | | justify-content: center; |
| | | height: 200px; |
| | | min-width: 1370px; |
| | | width: 1370px; |
| | | margin: 0 auto; |
| | | } |
| | | } |
| | | } |
| | | |
| | | ::v-deep { |
| | | .el-checkbox__label { |
| | | margin-left: 6px; |
| | | color: #000; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .el-table td.el-table__cell div { |
| | | margin-right: 20px; |
| | | } |
| | | |
| | | .el-table th { |
| | | background-color: #f3f3f3; |
| | | color: #000; |
| | | } |
| | | |
| | | .el-table td { |
| | | color: #333333; |
| | | } |
| | | |
| | | .el-table--enable-row-transition .el-table__body td.el-table__cell { |
| | | height: 180px; |
| | | } |
| | | |
| | | .el-checkbox__inner { |
| | | width: 16px; |
| | | height: 16px; |
| | | } |
| | | |
| | | .el-image__inner { |
| | | box-shadow: 0px 0px 20px 1px #ccc; |
| | | object-fit: contain !important; |
| | | width: 120px; |
| | | height: 160px; |
| | | } |
| | | |
| | | .el-icon { |
| | | margin-right: 10px; |
| | | font-size: 20px; |
| | | position: relative; |
| | | top: 3px; |
| | | left: 0px; |
| | | } |
| | | |
| | | .deleteBox { |
| | | .el-dialog.is-align-center { |
| | | width: 350px; |
| | | } |
| | | |
| | | .el-dialog__body { |
| | | display: flex; |
| | | justify-content: center; |
| | | font-size: 16px; |
| | | } |
| | | } |
| | | |
| | | .el-table__inner-wrapper::before { |
| | | height: 0px; |
| | | } |
| | | } |
| | | |
| | | .labelBox { |
| | | // width: 50px; |
| | | padding: 0 4px; |
| | | height: 25px; |
| | | color: #fff; |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | margin: 0 !important; |
| | | border-radius: 0px 0px 0px 5px; |
| | | box-sizing: border-box; |
| | | |
| | | p { |
| | | display: flex; |
| | | justify-content: center; |
| | | } |
| | | } |
| | | |
| | | .breadcrumbsBox { |
| | | height: 60px; |
| | | border-bottom: 1px solid #f5f5f5; |
| | | |
| | | p { |
| | | line-height: 60px; |
| | | font-size: 14px; |
| | | color: #545c63; |
| | | } |
| | | } |
| | | |
| | | .noData { |
| | | font-size: 26px; |
| | | font-weight: bold; |
| | | display: flex; |
| | | justify-content: center; |
| | | margin: 0 auto; |
| | | } |
| | | </style> |