Kaynağa Gözat

结账页丢件险功能

fogwind 6 gün önce
ebeveyn
işleme
5bd6c24c58

+ 4 - 4
src/app/(checkout)/checkout/_components/CheckoutCoupon/CheckoutCoupon.tsx

@@ -34,11 +34,11 @@ export default function CheckoutCoupon({
 
         overlayLoading.start();
         const saveRes = await saveCheckoutCart({ 
-            shippingMethod: '-1',
-            paymentMethod: '-1',
+            // shippingMethod: '-1',
+            // paymentMethod: '-1',
             couponCode: code,// '' 表示取消应用
-            giftCardNumber: '-1',
-            memberDiscount: '-1'
+            // giftCardNumber: '-1',
+            // memberDiscount: '-1'
         });
         overlayLoading.stop();
         if(!saveRes.error) {

+ 21 - 12
src/app/(checkout)/checkout/_components/CheckoutWrapper.tsx

@@ -32,6 +32,7 @@ import PromotionsDetails from "./PromotionsDetails";
 import CheckoutVipPlus from "./VipPlus/CheckoutVipPlus";
 import CheckoutProducts from "./CheckoutProducts/CheckoutProducts";
 import CheckoutCoupon from "./CheckoutCoupon/CheckoutCoupon";
+import LostInsurance from "./LostInsurance/LostInsurance";
 /***
  * 保存完地址之后要重新获取运输方式和支付方式
  * 变更运输方式后重新获取支付方式
@@ -127,11 +128,11 @@ export default function CheckoutWrapper({
    
         overlayLoading.start();
         const saveRes = await saveCheckoutCart({ 
-            shippingMethod: '-1',
+            // shippingMethod: '-1',
             paymentMethod: method,
-            couponCode: '-1',
-            giftCardNumber: '-1',
-            memberDiscount: '-1'
+            // couponCode: '-1',
+            // giftCardNumber: '-1',
+            // memberDiscount: '-1'
         });
         overlayLoading.stop();
         if(!saveRes.error) {
@@ -151,10 +152,10 @@ export default function CheckoutWrapper({
         overlayLoading.start();
         const saveRes = await saveCheckoutCart({ 
             shippingMethod: method,
-            paymentMethod: '-1',
-            couponCode: '-1',
-            giftCardNumber: '-1',
-            memberDiscount: '-1'
+            // paymentMethod: '-1',
+            // couponCode: '-1',
+            // giftCardNumber: '-1',
+            // memberDiscount: '-1'
         });
         overlayLoading.stop();
         if(!saveRes.error) {
@@ -224,11 +225,11 @@ export default function CheckoutWrapper({
         if(cartData.paymentMethod === null) {
             const pmethod = methodPaymentRef.current.getSelectPaymentMethod();
             const saveRes = await saveCheckoutCart({ 
-                shippingMethod: '-1',
+                // shippingMethod: '-1',
                 paymentMethod: pmethod,
-                couponCode: '-1',
-                giftCardNumber: '-1',
-                memberDiscount: '-1'
+                // couponCode: '-1',
+                // giftCardNumber: '-1',
+                // memberDiscount: '-1'
             });
             if(!saveRes.error) {
                 if(saveRes.data) {
@@ -354,6 +355,14 @@ export default function CheckoutWrapper({
                     onShipMethodChange={handleShippingMethodChange}  
                 />
             </div>
+            {cartData.shippingInsuranceEnabled &&
+                <div className="mt-3 box-border px-4">
+                    <LostInsurance 
+                        cartData={cartData}
+                        onSwitchInsurance={onCartDataChange}
+                    />
+                </div>
+            }
             <div className="mt-6 box-border px-4">
                 <CheckoutCoupon 
                     couponCode={cartData.couponCode || ''}

+ 6 - 0
src/app/(checkout)/checkout/_components/ContinueToPay/ContinueToPayOrderInfo.tsx

@@ -170,6 +170,12 @@ export default function ContinueToPayOrderInfo({
                         <p className="text-ly-12 leading-ly-20">{orderSymbol}{orderDetail.shippingAmount}</p>
                     </div>
                 }
+                {Number(orderDetail?.shippingInsuranceAmount) > 0 &&
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-12 leading-ly-20">Shipping</p>
+                        <p className="text-ly-12 leading-ly-20">{orderSymbol}{Number(orderDetail.shippingInsuranceAmount)}</p>
+                    </div>
+                }
                 {orderDetail.taxAmount !== 0 &&
                     <div className="flex justify-between mt-3 first:mt-0">
                         <p className="text-ly-12 leading-ly-20">Tax</p>

+ 4 - 4
src/app/(checkout)/checkout/_components/GiftCard/CheckoutGiftCardGate.tsx

@@ -86,11 +86,11 @@ export default function CheckoutGiftCardGate({
         const paramCode = code === giftcardNumber ? '' : code; // '' 表示取消应用
         overlayLoading.start();
         const saveRes = await saveCheckoutCart({ 
-            shippingMethod: '-1',
-            paymentMethod: '-1',
-            couponCode: '-1',
+            // shippingMethod: '-1',
+            // paymentMethod: '-1',
+            // couponCode: '-1',
             giftCardNumber: paramCode,
-            memberDiscount: '-1'
+            // memberDiscount: '-1'
         });
         overlayLoading.stop();
         if(!saveRes.error) {

+ 87 - 0
src/app/(checkout)/checkout/_components/LostInsurance/LostInsurance.tsx

@@ -0,0 +1,87 @@
+"use client";
+
+
+import {useConfig} from "@/utils/hooks/useConfig";
+import { useCustomToast } from "@/utils/hooks/useToast";
+import {useSaveCheckoutCart} from "@/utils/hooks/useSaveCheckoutCart";
+import { formatCartDetail } from "@/utils/cartDetailTools";
+import { overlayLoading } from "@/components/theme/ui/kernel/loading/api";
+import {CartDetail} from "@/types/cart/type";
+
+/**
+ * 先通过 shippingInsuranceEnabled 判断网站是否开通丢件险功能
+ * 再通过 useShippingInsurance 判断用户是否勾选丢件险 
+ */
+
+export default function LostInsurance({
+    cartData,
+    onSwitchInsurance
+}: {
+    cartData: CartDetail
+    onSwitchInsurance: (payload:CartDetail) => void;
+}) {
+
+    const {getCurrentCurrencyItem} = useConfig();
+    const currentCurrency = getCurrentCurrencyItem();
+    const currencySymbol = currentCurrency.symbol;
+    const { showToast } = useCustomToast();
+    const {saveCheckoutCart} = useSaveCheckoutCart();
+    const clickSwitchButton = async (bool: boolean) => {
+        let isInsurance = bool ? '1' : '';
+        await setInsurance(isInsurance);
+    };
+    const setInsurance = async (insurance: string) => {
+        overlayLoading.start();
+        const saveRes = await saveCheckoutCart({ 
+            useShippingInsurance: insurance
+        });
+        overlayLoading.stop();
+        if(!saveRes.error) {
+            if(saveRes.data) {
+                const newCartDetail = formatCartDetail(saveRes.data);
+                onSwitchInsurance(newCartDetail);
+            }
+            return true;
+        } else {
+            showToast(saveRes.msg, 'danger');
+            return false;
+        }
+    };
+
+    let title = "";
+    if(cartData.shippingInsuranceType === "percentage") {
+        title = `${cartData.shippingInsuranceValue}% Package Insurance`;
+    } else if(cartData.shippingInsuranceType === "fixed") {
+        title = `${currencySymbol}${cartData.shippingInsuranceAmount} Package Insurance`;
+    }
+    return (<>
+        <div className="relative box-border w-full bg-[#F9F9F9] p-3">
+            <div className="flex justify-between items-center">
+                <span className="text-ly-13">
+                    {title}
+                </span>
+                <span className="text-ly-12">
+                    {cartData.formattedShippingInsuranceAmount}
+                </span>
+            </div>
+            <div className="mt-2 w-57 text-ly-12 leading-3.5 text-ly-placeholder">
+                Increased compensation for courier packages issued within 30 days.
+            </div>
+            <div className="absolute bottom-3 right-3 flex justify-between items-center">
+                <label className="group relative w-9 h-5.5 flex-none">
+                    <input className="absolute w-full h-full top-0 left-0 opacity-0 z-10"
+                        type="checkbox" checked={cartData.useShippingInsurance}
+                        onChange={(e) => clickSwitchButton(e.target.checked)}
+                    />
+                    <span className="transition-all box-border block px-0.5 w-full h-full rounded-full flex items-center bg-[#c2c2c2] group-has-[:checked]:bg-[#363636]">
+                        <span className="transition-all block w-4.5 h-4.5 rounded-full bg-white group-has-[:checked]:ml-3.5"></span>
+                    </span>
+                </label>
+                
+            </div>
+
+            
+        </div>
+        
+    </>);
+}

+ 10 - 1
src/app/(checkout)/checkout/_components/PromotionsDetails.tsx

@@ -8,7 +8,10 @@ export default function PromotionsDetails({cartData}:{
     cartData: CartDetail
 }) { 
 
-
+    let title = "Insurance for Lost";
+    if(cartData.shippingInsuranceType === "percentage") {
+        title = `Insurance for Lost (${cartData.shippingInsuranceValue}%)`;
+    }
     return (
         <div className="w-full box-border">
             <ul className="w-full">
@@ -22,6 +25,12 @@ export default function PromotionsDetails({cartData}:{
                         <span>{cartData.formattedShippingAmount}</span>
                     </li>
                 }
+                {cartData.shippingInsuranceAmount !== 0 &&
+                    <li className="flex justify-between items-center text-ly-12 mt-4 first:mt-0">
+                        <span>{title}</span>
+                        <span>{cartData.formattedShippingInsuranceAmount}</span>
+                    </li>
+                }
                 {cartData.vipPlusAmount !== 0 &&
                     <li className="flex justify-between items-center text-ly-12 mt-4 first:mt-0">
                         <span>Vip Plus Fee</span>

+ 4 - 4
src/app/(checkout)/checkout/_components/VipPlus/CheckoutVipPlus.tsx

@@ -65,10 +65,10 @@ export default function CheckoutVipPlus({
     const setVipPlus = async (paramVip: string) => {
         overlayLoading.start();
         const saveRes = await saveCheckoutCart({ 
-            shippingMethod: '-1',
-            paymentMethod: '-1',
-            couponCode: '-1',
-            giftCardNumber: '-1',
+            // shippingMethod: '-1',
+            // paymentMethod: '-1',
+            // couponCode: '-1',
+            // giftCardNumber: '-1',
             memberDiscount: paramVip
         });
         overlayLoading.stop();

+ 6 - 0
src/app/(public)/paymentresult/_components/OrderDetailWrapper.tsx

@@ -182,6 +182,12 @@ export default function OrderDetailWrapper({
                         <p className="text-ly-12 leading-ly-20">{currency && currency.symbol}{orderDetailRes?.shippingAmount}</p>
                     </div>
                 }
+                {Number(orderDetailRes?.shippingInsuranceAmount) > 0 &&
+                    <div className="flex justify-between mt-3 first:mt-0">
+                        <p className="text-ly-12 leading-ly-20">Insurance of Lost</p>
+                        <p className="text-ly-12 leading-ly-20">{currency && currency.symbol}{Number(orderDetailRes?.shippingInsuranceAmount)}</p>
+                    </div>
+                }
                 {!!orderDetailRes?.taxAmount &&
                     <div className="flex justify-between mt-3 first:mt-0">
                         <p className="text-ly-12 leading-ly-20">Tax</p>

+ 4 - 3
src/app/(public)/paymentresult/result/page.tsx

@@ -16,13 +16,14 @@ import { GUEST_CART_TOKEN } from "@/utils/constants";
 export default async function SuccessPage({searchParams}: {
   searchParams?: Promise<{ [key: string]: string | string[] | undefined }>;
 })  {
+    const session = await getServerSession(authOptions);// 游客是null
+    const isGuest = session === null;
     const cookieStore = await cookies();
     // 登录用户cookie里没有GUEST_CART_ID
-    if(!cookieStore.get(GUEST_CART_TOKEN)) {
+    if(isGuest && !cookieStore.get(GUEST_CART_TOKEN)) {
         redirect('/', RedirectType.replace);
     }
-    const session = await getServerSession(authOptions);// 游客是null
-    const isGuest = session === null;
+    
     
     const query = await searchParams; // awx_return_result
     const orderid = query?.orderId;

+ 8 - 0
src/graphql/cart/mutations/AddProductToCart.ts

@@ -41,6 +41,14 @@ export const CREATE_ADD_PRODUCT_IN_CART: TypedDocumentNode<AddToCartData> = gql`
             }
           }
         }
+        useShippingInsurance
+        shippingInsuranceEnabled
+        shippingInsuranceName
+        shippingInsuranceType
+        shippingInsuranceValue
+        shippingInsuranceAmount
+        baseShippingInsuranceAmount
+        formattedShippingInsuranceAmount
         isVip
         vipDiscountAmount
         formattedVipDiscountAmount

+ 8 - 0
src/graphql/cart/mutations/CreateApplyCoupon.ts

@@ -31,6 +31,14 @@ export const CREATE_APPLY_COUPON: TypedDocumentNode<CreateApplyCouponData,{coupo
                         }
                     }
                     }
+                    useShippingInsurance
+                    shippingInsuranceEnabled
+                    shippingInsuranceName
+                    shippingInsuranceType
+                    shippingInsuranceValue
+                    shippingInsuranceAmount
+                    baseShippingInsuranceAmount
+                    formattedShippingInsuranceAmount
                     isVip
                     vipDiscountAmount
                     formattedVipDiscountAmount

+ 8 - 0
src/graphql/cart/mutations/CreateMergeCart.ts

@@ -33,6 +33,14 @@ export const CREATE_MERGE_CART: TypedDocumentNode<CreateMergeCartData> = gql`
             }
           }
         }
+        useShippingInsurance
+        shippingInsuranceEnabled
+        shippingInsuranceName
+        shippingInsuranceType
+        shippingInsuranceValue
+        shippingInsuranceAmount
+        baseShippingInsuranceAmount
+        formattedShippingInsuranceAmount
         isVip
         vipDiscountAmount
         formattedVipDiscountAmount

+ 8 - 0
src/graphql/cart/mutations/CreateRemoveCoupon.ts

@@ -27,6 +27,14 @@ export const CREATE_REMOVE_COUPON: TypedDocumentNode<CreateRemoveCouponData> = g
                         }
                     }
                     }
+                    useShippingInsurance
+                    shippingInsuranceEnabled
+                    shippingInsuranceName
+                    shippingInsuranceType
+                    shippingInsuranceValue
+                    shippingInsuranceAmount
+                    baseShippingInsuranceAmount
+                    formattedShippingInsuranceAmount
                     isVip
                     vipDiscountAmount
                     formattedVipDiscountAmount

+ 8 - 0
src/graphql/cart/mutations/GetCartItem.ts

@@ -27,6 +27,14 @@ export const GET_CART_ITEM: TypedDocumentNode<GetCartItemData> = gql`
             }
           }
         }
+        useShippingInsurance
+        shippingInsuranceEnabled
+        shippingInsuranceName
+        shippingInsuranceType
+        shippingInsuranceValue
+        shippingInsuranceAmount
+        baseShippingInsuranceAmount
+        formattedShippingInsuranceAmount
         isVip
         vipDiscountAmount
         formattedVipDiscountAmount

+ 8 - 0
src/graphql/cart/mutations/RemoveCartItem.ts

@@ -27,6 +27,14 @@ export const REMOVE_CART_ITEM: TypedDocumentNode<RemoveCartItemData,{cartItemId:
             }
           }
         }
+        useShippingInsurance
+        shippingInsuranceEnabled
+        shippingInsuranceName
+        shippingInsuranceType
+        shippingInsuranceValue
+        shippingInsuranceAmount
+        baseShippingInsuranceAmount
+        formattedShippingInsuranceAmount
         isVip
         vipDiscountAmount
         formattedVipDiscountAmount

+ 8 - 0
src/graphql/cart/mutations/UpdateCartItems.ts

@@ -36,6 +36,14 @@ export const UPDATE_CART_ITEM: TypedDocumentNode<UpdateCartItemData,{cartItemId:
             }
           }
         }
+        useShippingInsurance
+        shippingInsuranceEnabled
+        shippingInsuranceName
+        shippingInsuranceType
+        shippingInsuranceValue
+        shippingInsuranceAmount
+        baseShippingInsuranceAmount
+        formattedShippingInsuranceAmount
         isVip
         vipDiscountAmount
         formattedVipDiscountAmount

+ 10 - 0
src/graphql/checkout/mutations/CreateSaveCheckoutCart.ts

@@ -14,6 +14,7 @@ export const CREATE_SAVE_CHECKOUT_CART: TypedDocumentNode<SaveCheckoutCartData,{
         $couponCode: String
         $giftCardNumber: String
         $memberDiscount: String
+        $useShippingInsurance: String
     ) {
       createSaveCheckoutCart(
         input: {
@@ -22,6 +23,7 @@ export const CREATE_SAVE_CHECKOUT_CART: TypedDocumentNode<SaveCheckoutCartData,{
             couponCode: $couponCode
             giftCardNumber: $giftCardNumber
             memberDiscount: $memberDiscount
+            useShippingInsurance: $useShippingInsurance
         }
         ) {
             saveCheckoutCart {
@@ -47,6 +49,14 @@ export const CREATE_SAVE_CHECKOUT_CART: TypedDocumentNode<SaveCheckoutCartData,{
                         }
                     }
                 }
+                useShippingInsurance
+                shippingInsuranceEnabled
+                shippingInsuranceName
+                shippingInsuranceType
+                shippingInsuranceValue
+                shippingInsuranceAmount
+                baseShippingInsuranceAmount
+                formattedShippingInsuranceAmount
                 isVip
                 vipDiscountAmount
                 formattedVipDiscountAmount

+ 5 - 0
src/graphql/customer/query/GetOrderDetails.ts

@@ -38,6 +38,11 @@ export const GET_ORDER_DETAILS: TypedDocumentNode<OrderDetailsData> = gql`
     vipDiscountAmount
     baseVipPlusAmount
     baseVipDiscountAmount
+
+    shippingInsuranceAmount
+    baseShippingInsuranceAmount
+    shippingInsuranceInvoiced
+    baseShippingInsuranceInvoiced
     giftcardNumber
     giftcardAmount
     baseGiftcardAmount

+ 9 - 0
src/types/cart/type.ts

@@ -60,6 +60,15 @@ export interface CartDetail {
   shippingAmount: number;
   shippingAmountInclTax: number;
   grandTotal: number;
+  // 丢件险
+  useShippingInsurance: boolean;
+  shippingInsuranceEnabled: boolean;
+  shippingInsuranceName: string;
+  shippingInsuranceType: string;
+  shippingInsuranceValue: number;
+  shippingInsuranceAmount: number;
+  baseShippingInsuranceAmount: number;
+  formattedShippingInsuranceAmount: string;
 
   formattedSubtotal: string;
   formattedSubTotalInclTax: string;

+ 6 - 5
src/types/checkout/type.ts

@@ -229,11 +229,12 @@ export interface SaveCheckoutCartData {
   createSaveCheckoutCart: SaveCheckoutCartPayload;
 }
 export interface SaveCheckoutCartVariables {
-  shippingMethod: string;
-  paymentMethod: string;
-  couponCode: string;
-  giftCardNumber: string;
-  memberDiscount: string;
+  shippingMethod?: string;
+  paymentMethod?: string;
+  couponCode?: string;
+  giftCardNumber?: string;
+  memberDiscount?: string;
+  useShippingInsurance?: string;
 }
 // Checkout Place Order
 

+ 4 - 0
src/types/customer/order.ts

@@ -110,6 +110,10 @@ export interface OrderDetails {
     vipDiscountAmount: string;
     baseVipPlusAmount: string;
     baseVipDiscountAmount: string;
+    shippingInsuranceAmount: string;
+    baseShippingInsuranceAmount: string;
+    shippingInsuranceInvoiced: string;
+    baseShippingInsuranceInvoiced: string;
     giftcardNumber: string;
     giftcardAmount: string;
     baseGiftcardAmount: string;

+ 10 - 0
src/utils/cartDetailTools.ts

@@ -8,6 +8,16 @@ export function formatCartDetail(cart:CartDetail): CartDetail {
         isGuest: cart.isGuest,
         itemsCount: cart.itemsCount,
         items: cart.items,
+
+        useShippingInsurance: cart.useShippingInsurance,
+        shippingInsuranceEnabled: cart.shippingInsuranceEnabled,
+        shippingInsuranceName: cart.shippingInsuranceName,
+        shippingInsuranceType: cart.shippingInsuranceType,
+        shippingInsuranceValue: cart.shippingInsuranceValue,
+        shippingInsuranceAmount: cart.shippingInsuranceAmount,
+        baseShippingInsuranceAmount: cart.baseShippingInsuranceAmount,
+        formattedShippingInsuranceAmount: cart.formattedShippingInsuranceAmount,
+
         isVip: cart.isVip,
         vipDiscountAmount: cart.vipDiscountAmount,
         formattedVipDiscountAmount: cart.formattedVipDiscountAmount,

+ 10 - 1
src/utils/hooks/useSaveCheckoutCart.ts

@@ -14,10 +14,19 @@ interface SaveCheckoutCartResult {
 
 export const useSaveCheckoutCart = () => {
     const client = useApolloClient();
+    const defaultVariables = {
+        shippingMethod: '-1',
+        paymentMethod: '-1',
+        couponCode: '-1',
+        giftCardNumber: '-1',
+        memberDiscount: '-1',
+        useShippingInsurance: '-1',
+    };
     const saveCheckoutCart = useCallback((params: SaveCheckoutCartVariables) => {
+        const variables = Object.assign({},defaultVariables,params);
         return client.mutate({
             mutation: CREATE_SAVE_CHECKOUT_CART,
-            variables: params
+            variables: variables //params
         }).then((res) => {
             const resData = res.data?.createSaveCheckoutCart.saveCheckoutCart ?? null; 
             const result: SaveCheckoutCartResult = {