feat: change center-component to components
This commit is contained in:
91
src/pages/pay/index.tsx
Normal file
91
src/pages/pay/index.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { X, ChevronRight } from 'lucide-react';
|
||||
import { usePayStore } from './store/pay';
|
||||
import { createQrcode } from './modules/create-qrcode';
|
||||
import Panda from '@/assets/panda.png';
|
||||
import Button from '@mui/material/Button/Button';
|
||||
export const App = () => {
|
||||
const [isAgreed, setIsAgreed] = useState(false);
|
||||
const qrcodeRef = useRef<HTMLImageElement>(null);
|
||||
const { getPayUrl, codeUrl, user, init, money, setMoney, subject, setSubject } = usePayStore();
|
||||
|
||||
useEffect(() => {
|
||||
// getPayUrl({ money: money, subject: subject });
|
||||
init();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (qrcodeRef.current) {
|
||||
createQrcode(codeUrl, qrcodeRef.current);
|
||||
}
|
||||
}, [codeUrl]);
|
||||
let username = user?.nickname || user?.username || '--';
|
||||
if (username === 'root') {
|
||||
username = 'kevisual';
|
||||
}
|
||||
const redirectToPay = async () => {
|
||||
const res = await getPayUrl({ money: money, subject: subject });
|
||||
if (res.code === 200) {
|
||||
const newLink = res?.data?.form;
|
||||
if (newLink) {
|
||||
// window.location.href = newLink;
|
||||
window.open(newLink, '_blank');
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className='min-h-screen bg-gray-50 flex items-center justify-center border-gray-200'>
|
||||
<div className='w-[600px] h-[400px] bg-white rounded-lg shadow-lg overflow-hidden'>
|
||||
{/* Header */}
|
||||
<div className='bg-white p-3 flex justify-between items-center border-b border-gray-200'>
|
||||
<div className='flex items-center gap-2'>
|
||||
<img src={user?.avatar ?? Panda} alt='User Avatar' className='w-8 h-8 rounded-full' />
|
||||
<div>
|
||||
<h2 className='text-base font-semibold'>{username}</h2>
|
||||
<span className='text-gray-500 text-xs'>会员:已过期</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex items-center gap-3 text-gray-600 text-sm'>
|
||||
<span>赠送好友</span>
|
||||
<span>积分兑换</span>
|
||||
<span>激活码开通</span>
|
||||
<X className='w-4 h-4' />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main Content */}
|
||||
<div className='p-4 h-[calc(400px-56px)] overflow-y-auto'>
|
||||
{/* Membership Type */}
|
||||
<div className='flex items-center gap-2 mb-6'>
|
||||
<span className='bg-pink-100 text-pink-500 px-2 py-0.5 rounded text-xs'>会员</span>
|
||||
<div className='flex-1'></div>
|
||||
<button className='flex items-center text-gray-600 text-xs'>
|
||||
切换高级套餐
|
||||
<ChevronRight className='w-3 h-3' />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Payment QR Code */}
|
||||
<div className='bg-white border border-gray-200 rounded-lg p-4 text-center min-h-[200px] flex flex-col justify-center items-center'>
|
||||
<div className='text-2xl font-bold mb-3'>¥ {(money / 100).toFixed(2)}</div>
|
||||
{/* <QrCode className='w-32 h-32 mx-auto mb-2' /> */}
|
||||
{/* <img id='qrcode' className='w-32 h-32 mx-auto mb-2' ref={qrcodeRef} /> */}
|
||||
{/* <p className='text-gray-600 text-xs'>请使用支付宝扫码支付</p> */}
|
||||
<div className='flex justify-center items-center gap-2'>
|
||||
<div className='text-center px-4 py-2 cursor-pointer rounded-md shadow-md text-gray-600 text-xs border border-gray-300' onClick={redirectToPay}>
|
||||
提交订单
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Terms */}
|
||||
<div className='mt-4 text-xs text-gray-500 text-center flex items-center justify-center gap-1'>
|
||||
<input type='checkbox' id='terms' checked={isAgreed} onChange={(e) => setIsAgreed(e.target.checked)} className='w-3 h-3 accent-pink-500' />
|
||||
<label className='text-gray-300 underline' htmlFor='terms'>
|
||||
已阅读《会员服务协议》
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
27
src/pages/pay/modules/create-qrcode.ts
Normal file
27
src/pages/pay/modules/create-qrcode.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import QRCode from 'qrcode';
|
||||
|
||||
export const createQrcode = (url: string, element: HTMLImageElement) => {
|
||||
if (!url) return;
|
||||
console.log('pay url', url);
|
||||
QRCode.toDataURL(
|
||||
url,
|
||||
{
|
||||
errorCorrectionLevel: 'H',
|
||||
type: 'image/jpeg',
|
||||
margin: 1,
|
||||
|
||||
width: 300,
|
||||
color: {
|
||||
dark: '#000000',
|
||||
light: '#ffffff',
|
||||
},
|
||||
},
|
||||
function (err, url) {
|
||||
if (err) {
|
||||
console.log('err', err);
|
||||
throw err;
|
||||
}
|
||||
element.src = url;
|
||||
},
|
||||
);
|
||||
};
|
||||
46
src/pages/pay/store/pay.ts
Normal file
46
src/pages/pay/store/pay.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { create } from 'zustand';
|
||||
import { query, queryLogin } from '@/modules/query';
|
||||
import { toast } from 'react-toastify';
|
||||
interface PayState {
|
||||
getPayUrl: (data: { money: number; subject: string }) => Promise<any>;
|
||||
codeUrl: string;
|
||||
setCodeUrl: (url: string) => void;
|
||||
user: any;
|
||||
money: number;
|
||||
subject: string;
|
||||
setMoney: (money: number) => void;
|
||||
setSubject: (subject: string) => void;
|
||||
init: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const usePayStore = create<PayState>((set) => ({
|
||||
money: 12800,
|
||||
setMoney: (money) => set({ money }),
|
||||
subject: 'kevisual 会员',
|
||||
setSubject: (subject) => set({ subject }),
|
||||
getPayUrl: async (data) => {
|
||||
const res = await query.post({
|
||||
path: 'alipay',
|
||||
key: 'pay',
|
||||
data,
|
||||
});
|
||||
if (res.code === 200) {
|
||||
if (res.data?.form) {
|
||||
set({ codeUrl: res.data?.form });
|
||||
}
|
||||
} else {
|
||||
toast.error(res.message);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
codeUrl: '',
|
||||
setCodeUrl: (url) => set({ codeUrl: url }),
|
||||
user: null,
|
||||
init: async () => {
|
||||
const res = await queryLogin.cacheStore.getCurrentUser();
|
||||
console.log(res);
|
||||
if (res) {
|
||||
set({ user: res });
|
||||
}
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user