Files
SAAS/src/app/team/[teamCode]/payment-platforms/payment-platform-modal.tsx
2025-05-14 00:30:11 +08:00

272 lines
8.5 KiB
TypeScript

/**
* 支付平台模态框组件
* 作者: 阿瑞
* 功能: 提供支付平台信息的添加和编辑界面
* 版本: 1.0.0
*/
'use client';
import React, { useState, useEffect } from 'react';
import { useParams } from 'next/navigation';
import { PaymentPlatform, PaymentPlatformStatus } from '@/models/team/types/old/payment-platform';
import Modal from '@/components/ui/Modal';
interface PaymentPlatformModalProps {
isOpen: boolean;
onClose: () => void;
platform?: PaymentPlatform | null;
onSuccess: () => void;
}
/**
* 支付平台模态框组件
*/
export default function PaymentPlatformModal({ isOpen, onClose, platform, onSuccess }: PaymentPlatformModalProps) {
const params = useParams();
const teamCode = params?.teamCode as string;
const isEditing = !!platform;
// 表单状态
const [formData, setFormData] = useState<Partial<PaymentPlatform>>({
name: '',
order: 0,
description: '',
status: PaymentPlatformStatus.NORMAL
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
/**
* 初始化编辑表单数据
*/
useEffect(() => {
if (platform) {
setFormData({
id: platform.id,
name: platform.name,
order: platform.order,
description: platform.description || '',
status: platform.status
});
} else {
// 重置表单
setFormData({
name: '',
order: 0,
description: '',
status: PaymentPlatformStatus.NORMAL
});
}
setError(null);
}, [platform, isOpen]);
/**
* 处理表单输入变化
*/
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target;
// 处理数字类型字段
if (name === 'order') {
setFormData(prev => ({
...prev,
[name]: value === '' ? 0 : parseInt(value, 10)
}));
return;
}
// 处理状态选择
if (name === 'status') {
setFormData(prev => ({
...prev,
[name]: parseInt(value, 10)
}));
return;
}
setFormData(prev => ({
...prev,
[name]: value
}));
};
/**
* 提交表单
*/
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
// 基本验证
if (!formData.name) {
setError('平台名称为必填项');
return;
}
if (formData.order === undefined || formData.order < 0) {
setError('显示顺序必须为非负整数');
return;
}
setIsSubmitting(true);
setError(null);
try {
let response;
if (isEditing && platform) {
// 更新支付平台
response = await fetch(`/api/team/${teamCode}/payment-platforms/${platform.id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
} else {
// 创建支付平台
response = await fetch(`/api/team/${teamCode}/payment-platforms`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
}
// 处理响应
const result = await response.json();
if (!response.ok) {
throw new Error(result.error || '操作失败');
}
// 成功处理
onSuccess();
onClose();
} catch (err) {
console.error('提交支付平台数据失败:', err);
setError(err instanceof Error ? err.message : '未知错误');
} finally {
setIsSubmitting(false);
}
};
return (
<Modal
isOpen={isOpen}
onClose={onClose}
title={isEditing ? '编辑支付平台' : '添加支付平台'}
>
<form onSubmit={handleSubmit} className="space-y-4">
{/* 错误提示 */}
{error && (
<div className="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4">
<p>{error}</p>
</div>
)}
{/* 平台名称 */}
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
<span className="text-red-500">*</span>
</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white"
required
/>
</div>
{/* 显示顺序 */}
<div>
<label htmlFor="order" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
<span className="text-red-500">*</span>
</label>
<input
type="number"
id="order"
name="order"
value={formData.order}
onChange={handleChange}
min="0"
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white"
required
/>
<p className="mt-1 text-sm text-gray-500 dark:text-gray-400"></p>
</div>
{/* 平台状态 */}
<div>
<label htmlFor="status" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
</label>
<select
id="status"
name="status"
value={formData.status}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white"
>
<option value={PaymentPlatformStatus.NORMAL}></option>
<option value={PaymentPlatformStatus.DISABLED}></option>
<option value={PaymentPlatformStatus.BACKUP}></option>
<option value={PaymentPlatformStatus.OTHER}></option>
</select>
</div>
{/* 平台描述 */}
<div>
<label htmlFor="description" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
</label>
<textarea
id="description"
name="description"
value={formData.description || ''}
onChange={handleChange}
rows={3}
className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white"
/>
</div>
{/* 表单按钮 */}
<div className="flex justify-end space-x-3 pt-3">
<button
type="button"
onClick={onClose}
className="px-4 py-2 text-sm font-medium text-gray-700 bg-white dark:bg-gray-700 dark:text-gray-300 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none"
>
</button>
<button
type="submit"
disabled={isSubmitting}
className={`px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-md shadow-sm hover:bg-blue-700 focus:outline-none ${
isSubmitting ? 'opacity-70 cursor-not-allowed' : ''
}`}
>
{isSubmitting ? (
<span className="flex items-center">
<svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
...
</span>
) : (
isEditing ? '保存' : '创建'
)}
</button>
</div>
</form>
</Modal>
);
}