tiefen_space_web/app/pay/page.jsx

341 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 alipayBlock = () => {
const base = webviewBaseRequest();
if (base?.b_mid === 161) {
createOrder("alipay_h5");
return;
}
Toast.show({
content: "支付渠道维护升级中请24小时后再试",
});
};
//商品列表
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 (type = "alipay_h5") => {
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: type,
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;
}
switch (type) {
case "alipay_h5":
router.push(`${data.data.alipay_h5_param_str}`);
break;
case "wxpay_native":
router.push(
`/pay/${encodeURIComponent(data.data.wxpay_native_param_str)}`
);
break;
default:
router.push(`${data.data.alipay_h5_param_str}`);
break;
}
} 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={alipayBlock}
className="flex flex-row h-12 w-full items-center justify-center bg-primary rounded-full py-2"
>
<svg viewBox="0 0 1024 1024" width="18" height="18">
<path
d="M1024.0512 701.0304V196.864A196.9664 196.9664 0 0 0 827.136 0H196.864A196.9664 196.9664 0 0 0 0 196.864v630.272A196.9152 196.9152 0 0 0 196.864 1024h630.272a197.12 197.12 0 0 0 193.8432-162.0992c-52.224-22.6304-278.528-120.32-396.4416-176.64-89.7024 108.6976-183.7056 173.9264-325.3248 173.9264s-236.1856-87.2448-224.8192-194.048c7.4752-70.0416 55.552-184.576 264.2944-164.9664 110.08 10.3424 160.4096 30.8736 250.1632 60.5184 23.1936-42.5984 42.496-89.4464 57.1392-139.264H248.064v-39.424h196.9152V311.1424H204.8V267.776h240.128V165.632s2.1504-15.9744 19.8144-15.9744h98.4576V267.776h256v43.4176h-256V381.952h208.8448a805.9904 805.9904 0 0 1-84.8384 212.6848c60.672 22.016 336.7936 106.3936 336.7936 106.3936zM283.5456 791.6032c-149.6576 0-173.312-94.464-165.376-133.9392 7.8336-39.3216 51.2-90.624 134.4-90.624 95.5904 0 181.248 24.4736 284.0576 74.5472-72.192 94.0032-160.9216 150.016-253.0816 150.016z"
fill="#FFFFFF"
></path>
</svg>
<p className="text-white text-base ml-1">
支付宝<span className="text-xs">维护中</span>
</p>
</button>
</div>
<div className="basis-1/2 px-2">
<button
onClick={() =>
document.getElementById("manual_pay_modal").showModal()
}
className="flex flex-row h-12 w-full items-center justify-center bg-[#2E2E2E] rounded-full py-2"
>
<p className="text-white 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>
);
}