tiefen_space_web/app/pay/page.jsx

324 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { Toast } from "antd-mobile";
import { generateSignature } from "@/utils/crypto";
import webviewBaseRequest from "@/utils/webviewBaseRequest";
export default function Pay() {
const router = useRouter();
//商品列表
const [productList, setProductList] = useState([]);
//选择的价格档位
const [selectedPrice, setSelectedPrice] = useState({});
//选择任意金额充值
const [customCoin, setCustomCoin] = useState({ selected: false, num: 1000 });
//任意金额充值的金币数量
const handleChangeCustomCoin = (e) => {
let newValue = parseInt(e.target.value, 10);
// 确保输入的值在最小值和最大值范围内
if (newValue >= 0 && newValue <= 100000) {
setCustomCoin({ ...customCoin, num: newValue });
} else if (isNaN(newValue)) {
setCustomCoin({ ...customCoin, num: 0 });
} else if (newValue > 100000) {
setCustomCoin({ ...customCoin, num: 100000 });
}
};
//获取当前充值档位
const [isFetching, setIsFetching] = useState(true);
useEffect(() => {
const getData = async () => {
const base = webviewBaseRequest();
const body = { ...base };
const signature = generateSignature(body);
try {
const response = await fetch(
`/api/vas/get_coins_product_list?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const data = await response.json();
if (data.ret === -1) {
Toast.show({
content: data.msg,
});
return;
}
setProductList(data.data.list_alipay_h5);
setIsFetching(false);
} catch (error) {
console.error(error);
}
};
getData();
}, []);
//创建充值订单
const [isLoading, setIsLoading] = useState(false);
const createOrder = async () => {
if (!selectedPrice.id && !customCoin.selected) {
Toast.show({
content: "请选择充值档位",
});
return;
}
if (customCoin.selected && customCoin.num < 10) {
Toast.show({
content: "最低充值1元哦",
});
return;
}
setIsLoading(true);
const base = webviewBaseRequest();
const body = {
...base,
product_id: customCoin.selected ? "h5_custom_coin" : selectedPrice.id,
custom_coins: customCoin.selected ? customCoin.num : 0,
pay_type: "alipay_h5",
from: "app",
};
const signature = generateSignature(body);
try {
const response = await fetch(
`/api/vas/create_order?signature=${signature}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const data = await response.json();
if (data.ret === -1) {
Toast.show({
content: data.msg,
});
return;
}
router.push(`${data.data.alipay_h5_param_str}`);
} catch (error) {
console.error(error);
} finally {
setIsLoading(false);
}
};
//跳转联系客服
const handleContact = () => {
if (navigator.userAgent.includes("FromWebview")) {
window.ReactNativeWebView.postMessage(
JSON.stringify({
type: "NAVIGATE",
data: {
page: "MessageDetail",
params: {
mid: 1,
},
},
})
);
} else {
Toast.show({
content: "请下载app联系客服充值",
});
}
document.getElementById("manual_pay_modal").close();
};
const PriceItem = ({ item }) => {
const handleClickPrice = (item) => {
setSelectedPrice(item);
setCustomCoin({ ...customCoin, selected: false });
};
return (
<div className="basis-1/3 p-2">
<button
onClick={() => handleClickPrice(item)}
className={
selectedPrice.id === item.id
? "flex flex-col w-full py-4 border bg-[#FF61B030] border-primary rounded-lg items-center"
: "flex flex-col w-full py-4 border bg-[#FFFFFF1A] border-secondary rounded-lg items-center"
}
>
<p
className={
selectedPrice.id === item.id
? "text-base text-primary"
: "text-base text-secondary"
}
>
{item.name}
</p>
<p
className={
selectedPrice.real_price === item.real_price
? "text-base text-primary"
: "text-base text-secondary"
}
>
¥{item.real_price / 100}
</p>
</button>
</div>
);
};
if (isFetching) {
return (
<section className="flex flex-1 justify-center container">
<span className="absolute top-1/2 loading loading-spinner loading-lg"></span>
</section>
);
}
return (
<section className="flex flex-1 justify-center container">
{isLoading && (
<span className="absolute top-1/2 loading loading-spinner loading-lg"></span>
)}
<div className="flex flex-1 flex-col p-4">
<div
onClick={() => router.push("/pay/info")}
className="flex flex-row items-center bg-neutral rounded-lg w-full p-2"
>
<svg viewBox="0 0 1024 1024" width="24" height="24">
<path
d="M512 65.983389c-245.952318 0-446.016611 200.064292-446.016611 446.016611S266.047682 958.016611 512 958.016611 958.016611 757.952318 958.016611 512 757.952318 65.983389 512 65.983389zM544.00086 736.00086c0 17.695686-14.303454 32.00086-32.00086 32.00086s-32.00086-14.303454-32.00086-32.00086L479.99914 448c0-17.695686 14.303454-32.00086 32.00086-32.00086 17.695686 0 32.00086 14.303454 32.00086 32.00086L544.00086 736.00086zM512 352.00086c-26.496224 0-48.00043-21.53689-48.00043-48.00043 0-26.527187 21.504206-48.00043 48.00043-48.00043s48.00043 21.471523 48.00043 48.00043C560.00043 330.46397 538.496224 352.00086 512 352.00086z"
fill="#FFF04C"
></path>
</svg>
<div className="ml-2 flex flex-col">
<p className="text-base font-semibold text-white">支付遇到问题</p>
<p className="text-xs text-secondary">
无法唤起支付宝APP点击支付无反应
</p>
</div>
<div className="ml-auto">
<svg viewBox="0 0 1024 1024" width="24" height="24">
<path
d="M761.055557 532.128047c0.512619-0.992555 1.343475-1.823411 1.792447-2.848649 8.800538-18.304636 5.919204-40.703346-9.664077-55.424808L399.935923 139.743798c-19.264507-18.208305-49.631179-17.344765-67.872168 1.888778-18.208305 19.264507-17.375729 49.631179 1.888778 67.872168l316.960409 299.839269L335.199677 813.631716c-19.071845 18.399247-19.648112 48.767639-1.247144 67.872168 9.407768 9.791372 21.984142 14.688778 34.560516 14.688778 12.000108 0 24.000215-4.479398 33.311652-13.439914l350.048434-337.375729c0.672598-0.672598 0.927187-1.599785 1.599785-2.303346 0.512619-0.479935 1.056202-0.832576 1.567101-1.343475C757.759656 538.879828 759.199462 535.391265 761.055557 532.128047z"
fill="#ffffff"
></path>
</svg>
</div>
</div>
<p className="text-white text-base font-semibold my-2">选择充值金额</p>
<div className="flex flex-wrap">
{productList?.map((item) => (
<PriceItem key={item.id} item={item} />
))}
{/* 任意金额充值 */}
<div className="basis-1/3 p-2">
<button
onClick={() => {
setSelectedPrice([]);
setCustomCoin({ ...customCoin, selected: true });
}}
className={
customCoin.selected
? "flex flex-col w-full h-full py-4 border bg-[#FF61B030] border-primary rounded-lg items-center justify-center"
: "flex flex-col w-full h-full py-4 border bg-[#FFFFFF1A] border-secondary rounded-lg items-center justify-center"
}
>
<p
className={
customCoin.selected
? "text-base text-primary"
: "text-base text-secondary"
}
>
自定义金币
</p>
</button>
</div>
</div>
{customCoin.selected && (
<div className="px-2 mt-2">
<input
type="number"
name="custom_price"
placeholder="请输入金币数额"
value={customCoin.num.toString()}
onChange={handleChangeCustomCoin}
className="input input-bordered input-md input-primary w-full"
/>
<p className="text-secondary text-base mt-2">
预估金额¥{customCoin.num / 10}
</p>
</div>
)}
<div className="flex mt-auto mb-12">
<div className="basis-1/2 px-2">
<button
onClick={createOrder}
className="flex flex-row w-full items-center justify-center bg-primary rounded-lg py-2"
>
<svg viewBox="0 0 1024 1024" width="28" height="28">
<path
d="M42.666667 42.666667h938.666666v938.666666H42.666667z"
fillOpacity="0"
></path>
<path
d="M981.333333 823.466667v4.266666c0 81.066667-68.266667 149.333333-149.333333 149.333334h-640c-38.4 0-76.8-17.066667-106.666667-42.666667s-42.666667-68.266667-42.666666-106.666667v-640c0-34.133333 17.066667-72.533333 42.666666-102.4s68.266667-42.666667 106.666667-42.666666h640C913.066667 42.666667 981.333333 110.933333 981.333333 192v631.466667z"
fill="#009FE9"
></path>
<path
d="M819.2 635.733333c-38.4-12.8-89.6-29.866667-145.066667-51.2 34.133333-64 64-132.266667 81.066667-204.8h-187.733333V324.266667h226.133333v-38.4l-226.133333 4.266666V174.933333h-93.866667c-17.066667 0-21.333333 17.066667-21.333333 17.066667v93.866667H230.4v38.4h226.133333v55.466666H268.8v38.4h375.466667c-17.066667 46.933333-34.133333 93.866667-59.733334 136.533334-119.466667-38.4-243.2-72.533333-324.266666-51.2-38.4 8.533333-76.8 29.866667-102.4 59.733333-85.333333 106.666667-25.6 268.8 162.133333 268.8 110.933333 0 217.6-59.733333 298.666667-162.133333 123.733333 59.733333 366.933333 162.133333 366.933333 162.133333v-145.066667c-4.266667 0-34.133333-4.266667-166.4-51.2zM298.666667 768c-145.066667 0-187.733333-115.2-115.2-179.2 21.333333-21.333333 51.2-34.133333 85.333333-42.666667 85.333333-8.533333 174.933333 34.133333 268.8 81.066667C469.333333 716.8 384 768 298.666667 768z"
fill="#FFFFFF"
></path>
</svg>
<p className="text-white text-base ml-1">支付宝支付</p>
</button>
</div>
<div className="basis-1/2 px-2">
<button
onClick={() =>
document.getElementById("manual_pay_modal").showModal()
}
className="flex flex-row w-full items-center justify-center border border-primary rounded-lg py-2"
>
<p className="text-primary text-base ml-1">人工充值</p>
</button>
</div>
</div>
</div>
<dialog id="manual_pay_modal" className="modal">
<div className="modal-box bg-[#13121F]">
<h3 className="font-semibold text-xl text-white text-center">
人工充值
</h3>
<p className="text-secondary text-base font-medium">
请联系人工客服进行充值单笔金额不低于500人民币
</p>
<div className="flex flex-row">
<button
onClick={handleContact}
className="flex flex-row flex-1 mx-2 items-center justify-center bg-[#FF669E] rounded-lg py-2 mt-4"
>
<p className="text-white text-base ml-1">联系客服</p>
</button>
<form method="dialog" className="flex flex-row flex-1 mx-2">
<button className="flex flex-row flex-1 items-center justify-center border border-secondary rounded-lg py-2 mt-4">
<p className="text-secondary text-base ml-1">取消</p>
</button>
</form>
</div>
</div>
</dialog>
</section>
);
}