qiyunfeng-create
2 天以前 5f00696dfb25bc90034448ceb634ed1ef256681a
src/views/personalCenter/myCart.vue
@@ -1,3 +1,578 @@
<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: 110px">
                <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="warning" @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 { InfoFilled } from "@element-plus/icons-vue";
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 = 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: "#FF6C00" };
  }
};
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) => {
      console.log(item.saleMethod.type, "item.saleMethod.type");
      if (item.productMonWithLinkDto.links[0].storeRefCode == "jsek_digitalTextbooks") {
        item.typeTxt = "数字教材";
        item.productType = "数字教材";
      } else if (
        item.productMonWithLinkDto.links[0].storeRefCode == "jsek_digitalCourses"
      ) {
        item.typeTxt = "数字课程";
        item.productType = "数字课程";
      } else {
        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: {
            crumbsKey: key,
            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;
    }
  }
}
.selectproduct {
  margin-top: 30px;
}
::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: 110px;
    height: 140px;
  }
  .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;
  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>