150 lines
6.7 KiB
TypeScript
150 lines
6.7 KiB
TypeScript
import React, { useState } from 'react';
|
|
import {
|
|
Button, Card, Form, Input, message, Switch, Typography, Divider,
|
|
} from 'antd';
|
|
import {
|
|
SaveOutlined, WechatOutlined, AlipayCircleOutlined, DollarOutlined,
|
|
} from '@ant-design/icons';
|
|
|
|
interface PaymentSetting {
|
|
key: string;
|
|
value: string;
|
|
label: string;
|
|
description: string;
|
|
secret?: boolean;
|
|
}
|
|
|
|
const AdminPaymentConfig: React.FC = () => {
|
|
const [saving, setSaving] = useState(false);
|
|
const [wechatEnabled, setWechatEnabled] = useState(false);
|
|
const [alipayEnabled, setAlipayEnabled] = useState(false);
|
|
const [form] = Form.useForm();
|
|
|
|
const handleSave = async () => {
|
|
try {
|
|
const values = await form.validateFields();
|
|
setSaving(true);
|
|
await new Promise(r => setTimeout(r, 500));
|
|
message.success('支付配置已保存');
|
|
setSaving(false);
|
|
} catch { setSaving(false); }
|
|
};
|
|
|
|
return (
|
|
<div style={{ maxWidth: 720 }}>
|
|
{/* WeChat Pay */}
|
|
<Card bordered={false} style={{ borderRadius: 12, border: '1px solid #f0f0f5', marginBottom: 16 }}>
|
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20 }}>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
|
<div style={{
|
|
width: 44, height: 44, borderRadius: 10,
|
|
background: 'rgba(7,193,96,0.08)',
|
|
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
fontSize: 22, color: '#07c160',
|
|
}}><WechatOutlined /></div>
|
|
<div>
|
|
<Typography.Title level={5} style={{ margin: 0 }}>微信支付</Typography.Title>
|
|
<Typography.Text type="secondary" style={{ fontSize: 12 }}>微信商户号支付配置</Typography.Text>
|
|
</div>
|
|
</div>
|
|
<Switch checked={wechatEnabled} onChange={setWechatEnabled} checkedChildren="已启用" unCheckedChildren="未启用" />
|
|
</div>
|
|
|
|
<Form form={form} layout="vertical" initialValues={{
|
|
wechat_mch_id: '',
|
|
wechat_api_key: '',
|
|
wechat_cert_path: '',
|
|
wechat_notify_url: '',
|
|
}}>
|
|
<Form.Item name="wechat_mch_id" label="商户号 (MchID)">
|
|
<Input placeholder="微信支付商户号" size="large" disabled={!wechatEnabled} />
|
|
</Form.Item>
|
|
<Form.Item name="wechat_api_key" label="API密钥">
|
|
<Input.Password placeholder="微信支付API密钥" size="large" disabled={!wechatEnabled} />
|
|
</Form.Item>
|
|
<Form.Item name="wechat_cert_path" label="证书路径">
|
|
<Input placeholder="apiclient_cert.pem 路径" size="large" disabled={!wechatEnabled} />
|
|
</Form.Item>
|
|
<Form.Item name="wechat_notify_url" label="回调地址">
|
|
<Input placeholder="https://yourdomain.com/api/payments/wechat/callback" size="large" disabled={!wechatEnabled} />
|
|
</Form.Item>
|
|
</Form>
|
|
</Card>
|
|
|
|
{/* Alipay */}
|
|
<Card bordered={false} style={{ borderRadius: 12, border: '1px solid #f0f0f5', marginBottom: 16 }}>
|
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20 }}>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
|
<div style={{
|
|
width: 44, height: 44, borderRadius: 10,
|
|
background: 'rgba(0,122,255,0.08)',
|
|
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
fontSize: 22, color: '#007aff',
|
|
}}><AlipayCircleOutlined /></div>
|
|
<div>
|
|
<Typography.Title level={5} style={{ margin: 0 }}>支付宝</Typography.Title>
|
|
<Typography.Text type="secondary" style={{ fontSize: 12 }}>支付宝应用支付配置</Typography.Text>
|
|
</div>
|
|
</div>
|
|
<Switch checked={alipayEnabled} onChange={setAlipayEnabled} checkedChildren="已启用" unCheckedChildren="未启用" />
|
|
</div>
|
|
|
|
<Form form={form} layout="vertical" initialValues={{
|
|
alipay_app_id: '',
|
|
alipay_private_key: '',
|
|
alipay_public_key: '',
|
|
alipay_notify_url: '',
|
|
}}>
|
|
<Form.Item name="alipay_app_id" label="AppID">
|
|
<Input placeholder="支付宝应用AppID" size="large" disabled={!alipayEnabled} />
|
|
</Form.Item>
|
|
<Form.Item name="alipay_private_key" label="应用私钥">
|
|
<Input.TextArea rows={3} placeholder="支付宝应用私钥 (PKCS8格式)" disabled={!alipayEnabled} />
|
|
</Form.Item>
|
|
<Form.Item name="alipay_public_key" label="支付宝公钥">
|
|
<Input.TextArea rows={3} placeholder="支付宝公钥" disabled={!alipayEnabled} />
|
|
</Form.Item>
|
|
<Form.Item name="alipay_notify_url" label="回调地址">
|
|
<Input placeholder="https://yourdomain.com/api/payments/alipay/callback" size="large" disabled={!alipayEnabled} />
|
|
</Form.Item>
|
|
</Form>
|
|
</Card>
|
|
|
|
{/* Recharge Packages */}
|
|
<Card bordered={false} style={{ borderRadius: 12, border: '1px solid #f0f0f5', marginBottom: 16 }}
|
|
title={<span><DollarOutlined style={{ marginRight: 8 }} />充值套餐</span>}>
|
|
{[
|
|
{ name: '体验包', credits: 500, price: 49, color: '#f59e0b' },
|
|
{ name: '进阶包', credits: 2000, price: 168, color: '#6366f1' },
|
|
{ name: '专业包', credits: 5000, price: 388, color: '#06b6d4' },
|
|
{ name: '企业包', credits: 20000, price: 1280, color: '#10b981' },
|
|
].map(p => (
|
|
<div key={p.name} style={{
|
|
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
|
|
padding: '12px 0', borderBottom: '1px solid #f5f6fa',
|
|
}}>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
<div style={{ width: 8, height: 8, borderRadius: '50%', background: p.color }} />
|
|
<Typography.Text strong>{p.name}</Typography.Text>
|
|
</div>
|
|
<div>
|
|
<Typography.Text strong style={{ color: p.color, fontSize: 16 }}>¥{p.price}</Typography.Text>
|
|
<Typography.Text type="secondary" style={{ fontSize: 12, marginLeft: 8 }}>{p.credits.toLocaleString()} 积分</Typography.Text>
|
|
<Typography.Text type="secondary" style={{ fontSize: 11, marginLeft: 4 }}>({(p.price / p.credits * 100).toFixed(1)}元/百积分)</Typography.Text>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</Card>
|
|
|
|
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
<Button type="primary" icon={<SaveOutlined />} onClick={handleSave} loading={saving}
|
|
size="large" style={{ borderRadius: 8, minWidth: 140 }}>
|
|
保存配置
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AdminPaymentConfig;
|