QYF-GitLab1
20 小时以前 cf7e71c6d0fb64eeb6b5deac540da843b4bb465c
src/views/personalCenter/myCart.vue
@@ -1,3 +1,545 @@
<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>