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.

608 lines
21 KiB

<template>
<!-- Header Start -->
<header class="header">
<div class="logo-wrap">
<i class="icon-arrow-left-bold-box icli" @click="$router.go(-1)"></i>
<h1 class="title-color font-md">
商品結帳
<span class="font-sm content-color">({{ cartStore.cartNum }} 樣商品)</span>
</h1>
</div>
<div class="avatar-wrap" @click="$router.push('/home')">
<i class="icon-home icli"></i>
</div>
</header>
<!-- Header End -->
<!-- Main Start -->
<main class="main-wrap payment-page cart-page mb-xxl">
<div class="cartitem-list">
<div>訂單詳細</div>
<div></div>
</div>
<!-- Cart Item Section Start -->
<div class="cart-item-wrap pt-0">
<div class="swipe-to-show" v-for="item in items" :key="item.rec_id">
<div class="product-list media">
<a href="javascript:void(0);">
<img :src="`https://shop.h888.fun/${item.goods_thumb}`" alt="offer" />
</a>
<div class="media-body">
<a href="product.html" class="font-sm"> {{ item.goods_name }} </a>
<span class="price-color font-sm">${{ item.goods_price }}</span>
<div class="plus-minus">X {{ item.goods_number }}</div>
</div>
</div>
</div>
</div>
<!-- Cart Item Section End -->
<!-- <button class="d-block btn-outline-grey" data-bs-toggle="offcanvas" data-bs-target="#add-card"
aria-controls="add-card">+ Add New Card</button> -->
<!-- Payment Section Start -->
<section class="payment-section">
<!-- Payment Method Accordian Start -->
<div class="accordion" id="accordionShipping">
<!-- Accordion Start -->
<div class="accordion-item">
<h2 class="accordion-header" id="headingTwo">
<button
class="accordion-button font-md title-color"
type="button"
data-bs-toggle="collapse"
aria-expanded="true"
data-bs-target="#shipping"
aria-controls="shipping"
>
配送方式
</button>
</h2>
<div
id="shipping"
class="accordion-collapse collapse show"
aria-labelledby="headingOne"
data-bs-parent="#accordionShipping"
>
<div class="accordion-body">
<ul class="filter-row">
<li
class="filter-col"
:class="{ active: shippingData.shipping_code === v.shipping_code }"
@click="selectShipping(v)"
v-for="(v, index) in shippingList"
:key="index"
>
{{ v.shipping_name }}
<span class="check"><img src="@/assets/icons/svg/active.svg" alt="active" /></span>
</li>
</ul>
</div>
<div class="shipping-data">
<div v-show="showExtra">
<template v-if="shippingData.shipping_code == 'shipping'">
<div>
<ul>
<li>收件人:{{ shippingData.extra_data.consignee }}</li>
<li>電 話:{{ shippingData.extra_data.tel }}</li>
<li>
地 址:{{
shippingData.extra_data.zipcode +
shippingData.extra_data.city +
shippingData.extra_data.district +
shippingData.extra_data.address
}}
</li>
</ul>
</div>
</template>
<template v-else-if="shippingData.shipping_code == 'ecpay'">
<div>
<ul v-if="shippingData.extra_data.type">
<li>
店 名:{{
logisticType[shippingData.extra_data.type] +
" " +
shippingData.extra_data.store_name
}}
</li>
<li>地 址:{{ shippingData.extra_data.store_address }}</li>
<li>電 話:{{ shippingData.extra_data.store_tel }}</li>
</ul>
</div>
</template>
</div>
<div v-show="orderStore.shipping.shipping_id">
<van-button type="success" size="mini" @click="changeShipping">修改</van-button>
</div>
</div>
</div>
</div>
<!-- Accordion End -->
</div>
<div class="accordion" id="accordionExample">
<!-- Accordion Start -->
<div class="accordion-item">
<h2 class="accordion-header" id="headingOne">
<button
class="accordion-button font-md title-color"
type="button"
data-bs-toggle="collapse"
data-bs-target="#payment"
aria-expanded="true"
aria-controls="payment"
>
支付方式
</button>
</h2>
<div
id="payment"
class="accordion-collapse collapse show"
aria-labelledby="headingOne"
data-bs-parent="#accordionExample"
>
<div class="accordion-body">
<ul class="filter-row">
<li
class="filter-col"
:class="{ active: orderStore.payment.pay_code === 'cod' }"
v-if="orderStore.shipping.shipping_code === 'ecpay'"
@click="selectPayment({ pay_id: 0, pay_code: 'cod', pay_name: '貨到付款' })"
>
貨到付款
<span class="check"><img src="@/assets/icons/svg/active.svg" alt="active" /></span>
</li>
<li
class="filter-col"
:class="{ active: orderStore.payment.pay_code === v.pay_code }"
@click="selectPayment(v)"
v-for="(v, index) in paymentList"
:key="index"
>
<img class="payment-card" :src="v.logo" :alt="v.pay_name" />
{{ v.pay_name }}
<span class="check"><img src="@/assets/icons/svg/active.svg" alt="active" /></span>
</li>
</ul>
</div>
</div>
</div>
<!-- Accordion End -->
</div>
<!-- Payment Method Accordian End -->
<div class="accordion" id="accordionShipping">
<!-- Accordion Start -->
<div class="accordion-item">
<h2 class="accordion-header" id="headingTwo">
<button
class="accordion-button font-md title-color"
type="button"
data-bs-toggle="collapse"
aria-expanded="true"
data-bs-target="#bonus"
aria-controls="bonus"
>
優惠代碼
</button>
</h2>
<div
id="bonus"
class="accordion-collapse collapse show"
aria-labelledby="headingOne"
data-bs-parent="#accordionBonus"
>
<div class="accordion-body">
<div class="input-box">
<input
type="text"
placeholder="請輸入優惠代碼"
v-model="bonus.sn"
class="form-control"
/>
</div>
<div class="bonus-desc">
{{ bonus.name }}
<span v-if="bonus.number > 0"
>數量: {{ bonus.number }} 剩下: {{ bonus.remain }} 張</span
>
</div>
</div>
</div>
</div>
<!-- Accordion End -->
</div>
</section>
<!-- Payment Section End -->
<!-- Order Detail Start -->
<section class="order-detail">
<h3 class="title-2">訂單詳細</h3>
<!-- Product Detail Start -->
<ul>
<li>
<span>金額</span>
<span>${{ detail.sum_amount }}</span>
</li>
<li>
<span>折扣</span>
<span class="font-theme">-${{ detail.discount }}</span>
</li>
<!-- <li>
<span>折價卷</span>
<a href="javascript:void(0);" class="font-danger">Apply Coupon</a>
</li> -->
<li v-show="detail.pay_fee > 0">
<span>金流手續費</span>
<span>{{ detail.pay_fee }}</span>
</li>
<li v-show="detail.shipping_fee > 0">
<span>運費</span>
<span>{{ detail.shipping_fee }}</span>
</li>
<li>
<span>總金額</span>
<span>${{ detail.total_amount }}</span>
</li>
</ul>
<!-- Product Detail End -->
</section>
<!-- Order Detail End -->
</main>
<!-- Main End -->
<!-- Footer Start -->
<footer class="footer-wrap footer-button">
<!-- <el-button type="primary" color="#0baf9a" disabled ></el-button> -->
<van-button type="success" color="#0baf9a" @click="handleFinish" block :loading="btnLoading"
>完成訂單</van-button
>
</footer>
<!-- Footer End -->
</template>
<script setup>
import _ from "lodash";
import { ref, reactive, onMounted, computed, watch } from "vue";
import { useCartStore } from "@/store/Cart";
import { useOrderStore } from "@/store/Order";
import { storeToRefs } from "pinia";
import { showToast } from "vant";
import { addOrder } from "@/services/order";
import { getPayments } from "@/services/payment";
import { getShippings, getUserDefaultCvs } from "@/services/shipping";
import { getUserDefaultAddress } from "@/services/user";
import { checkBonusSn } from "@/services/bonus";
import router from "@/router";
import linepayicon from "/src/assets/icons/png/linepay.png";
import mastericon from "/src/assets/icons/png/mastercard1.png";
const cartStore = useCartStore();
const orderStore = useOrderStore();
const { goodsItems: items } = storeToRefs(orderStore);
const order = reactive({
payment: 0,
shipping: 0,
goods: [],
});
const paymentList = ref([]);
const shippingList = ref([]);
const logisticType = {
1: "711",
2: "全家",
3: "萊爾富",
4: "OK",
};
const btnLoading = ref(false);
onMounted(async () => {
cartToOrder();
let res1 = await getPayments();
if (res1.code === 200) {
paymentList.value = res1.data;
}
let res2 = await getShippings();
if (res2.code === 200) {
shippingList.value = res2.data;
}
});
const bonus = reactive({
name: "沒有優惠劵",
sn: "",
number: 0,
remain: 0,
});
//檢查優惠代碼
const handleCheckBonusSn = async () => {
if (bonus.sn.length !== 10) {
bonus.name = "沒有優惠劵";
bonus.number = 0;
bonus.remain = 0;
orderStore.discount = 0;
return;
}
let res = await checkBonusSn(bonus.sn);
if (res.code === 200) {
orderStore.bonus_sn = bonus.sn;
bonus.name = res.data.type_name;
bonus.remain = res.data.remain_number;
bonus.number = res.data.bonus_number;
//如果res.data最後是% 就相剩,沒有%就直接扣
if (res.data.type_money.slice(-1) === "%") {
orderStore.discount = ((100 - res.data.type_money.slice(0, -1)) / 100) * orderStore.sum_amount;
} else {
orderStore.discount = res.data;
}
} else {
showToast(res.data);
}
};
watch(() => bonus.sn, _.debounce(handleCheckBonusSn, 500));
//將購物車商品資料轉換成訂單商品資料
const cartToOrder = () => {
if (cartStore.cartItems.length === 0) {
showToast("購物車中沒有商品,請先加入商品");
return router.push("/card");
}
items.value = cartStore.cartItems;
//檢查商品是否有goods_id為1的商品,有的話則設定order的extension_code為slashcard
let is_slashcard = items.value.find((item) => item.goods_id === 1);
if (is_slashcard) {
orderStore.extension_code = "slashcard";
}
};
// 物流
const selectShipping = async (value) => {
if (shippingData.value.shipping_code === value.shipping_code) return;
switch (value.shipping_code) {
case "shipping":
let resAddr = await getUserDefaultAddress();
console.log(resAddr.data);
if (resAddr.code === 200) {
orderStore.shipping = {
shipping_code: value.shipping_code,
shipping_id: value.shipping_id,
shipping_fee: 0,
extra_data: {
zipcode: resAddr.data.zipcode,
address: resAddr.data.address,
city: resAddr.data.city,
district: resAddr.data.district,
consignee: resAddr.data.consignee,
tel: resAddr.data.tel,
},
};
} else {
orderStore.shipping = {
shipping_code: value.shipping_code,
shipping_id: value.shipping_id,
shipping_fee: 0,
extra_data: {},
};
router.push("/address?from=order");
}
break;
case "ecpay":
let res = await getUserDefaultCvs();
if (res.code === 200) {
orderStore.shipping = {
shipping_code: value.shipping_code,
shipping_id: value.shipping_id,
shipping_fee: 0,
extra_data: {
type: res.data.type,
store_id: res.data.store_id,
store_name: res.data.store_name,
store_address: res.data.store_address,
store_tel: res.data.store_tel,
},
};
} else {
orderStore.shipping = {
shipping_code: value.shipping_code,
shipping_id: value.shipping_id,
shipping_fee: 0,
extra_data: {},
};
router.push("/order/shipping");
}
break;
default:
break;
}
};
const changeShipping = () => {
switch (shippingData.value.shipping_code) {
case "ecpay":
router.push("/order/shipping");
break;
case "shipping":
router.push("/address?from=order");
break;
default:
break;
}
};
const shippingData = computed(() => {
return orderStore.shipping;
});
// 顯示物流額外資訊
const showExtra = computed(() => {
let is_empty = _.isEmpty(orderStore.shipping.extra_data);
if (is_empty) {
return false;
} else {
return true;
}
});
// 金流
const selectPayment = (value) => {
orderStore.payment = {
pay_code: value.pay_code,
pay_id: value.pay_id,
pay_fee: 0,
};
};
//完成訂單
const handleFinish = async () => {
let order = orderStore.$state;
if (!order.shipping.shipping_id) {
return showToast("請選擇配送方式");
}
if (order.payment.pay_id === null) {
return showToast("請選擇付款方式");
}
if (JSON.stringify(order.shipping.extra_data) == "{}") {
return showToast("請選擇配送地址");
}
if (order.goodsItems.length === 0) {
showToast("購物車中沒有商品,請先加入商品");
router.push("/card");
}
order = { ...order, goods_amount: orderStore.sum_amount, order_amount: orderStore.total_amount };
btnLoading.value = true;
try {
let res = await addOrder(order);
if (res.code === 200) {
// 清空購物車
cartStore.clearCart();
orderStore.$reset();
// window.location.href = res.data.info.paymentUrl.web
// console.log('resdata',res.data)
return router.replace({
name: "Payment",
query: {
order_sn: res.data.order_sn,
pay_code: res.data.pay_code,
},
});
}
} catch (err) {
btnLoading.value = false;
return
}
btnLoading.value = false;
return showToast("操作失敗");
};
// 計算訂單詳細
const detail = computed(() => {
let sum_amount = orderStore.sum_amount;
let discount = orderStore.discount;
let shipping_fee = orderStore.shipping.shipping_fee;
let pay_fee = orderStore.payment.pay_fee;
let total_amount = orderStore.total_amount;
return { sum_amount, discount, shipping_fee, pay_fee, total_amount };
});
</script>
<style lang="less" scoped>
.cart-item-wrap {
margin-bottom: 20px;
}
.delete-button {
i {
font-size: 20px;
color: #ffffff;
}
}
.cartitem-list {
width: 100%;
border: 1px #cacaca solid;
border-radius: 5px;
height: 45px;
display: flex;
justify-content: space-between;
align-items: center;
div:nth-child(1) {
color: red;
padding-left: 10px;
}
div:nth-child(2) {
padding-right: 10px;
}
}
.price-color {
color: red;
}
.filter-row {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
.filter-col {
width: 40%;
}
}
// 物流
.shipping-data {
width: 100%;
display: flex;
padding: 10px 15px;
align-items: center;
justify-content: space-between;
div:nth-child(1) {
flex: 1;
width: 100%;
// padding: 10px 0;
// border-bottom: 1px #cacaca solid;
}
div:nth-child(2) {
width: 40px;
i {
font-size: 20px;
color: #cacaca;
}
}
}
.footer-wrap {
background-color: initial;
}
.bonus-desc {
padding: 0 10px;
}
</style>