- 新增许可证服务器 (license-server/) - 新增 Agent 部署模块 (flnxi-agent/) - 添加许可证验证和激活页面 - 添加 Harbor 镜像同步脚本 - 更新素材系统支持许可证验证
154 lines
4.6 KiB
TypeScript
154 lines
4.6 KiB
TypeScript
'use client';
|
||
|
||
import { useState } from 'react';
|
||
import { useRouter } from 'next/navigation';
|
||
|
||
export default function ActivatePage() {
|
||
const router = useRouter();
|
||
const [licenseKey, setLicenseKey] = useState('');
|
||
const [loading, setLoading] = useState(false);
|
||
const [error, setError] = useState('');
|
||
|
||
// 格式化许可证密钥输入(自动添加横杠)
|
||
const formatLicenseKey = (value: string) => {
|
||
const cleaned = value.toUpperCase().replace(/[^A-Z0-9]/g, '');
|
||
const parts = [];
|
||
for (let i = 0; i < cleaned.length && i < 16; i += 4) {
|
||
parts.push(cleaned.slice(i, i + 4));
|
||
}
|
||
return parts.join('-');
|
||
};
|
||
|
||
const handleKeyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||
setLicenseKey(formatLicenseKey(e.target.value));
|
||
setError('');
|
||
};
|
||
|
||
// 激活许可证
|
||
const handleActivate = async () => {
|
||
if (!licenseKey || licenseKey.length !== 19) {
|
||
setError('请输入完整的许可证密钥');
|
||
return;
|
||
}
|
||
|
||
setLoading(true);
|
||
setError('');
|
||
|
||
try {
|
||
const res = await fetch('/api/license/activate', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ licenseKey }),
|
||
});
|
||
|
||
const data = await res.json();
|
||
|
||
if (data.success) {
|
||
router.push('/');
|
||
} else {
|
||
setError(data.error || '激活失败,请检查许可证密钥');
|
||
}
|
||
} catch {
|
||
setError('网络错误,请检查网络连接');
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
// 免费试用
|
||
const handleFreeTrial = async () => {
|
||
setLoading(true);
|
||
setError('');
|
||
|
||
try {
|
||
const res = await fetch('/api/license/activate-free', {
|
||
method: 'POST',
|
||
});
|
||
|
||
const data = await res.json();
|
||
|
||
if (data.success) {
|
||
router.push('/');
|
||
} else {
|
||
setError(data.error || '激活失败');
|
||
}
|
||
} catch {
|
||
setError('网络错误,请检查网络连接');
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gray-50 flex items-center justify-center p-4">
|
||
<div className="w-full max-w-md">
|
||
<div className="bg-white rounded-lg shadow-lg p-8">
|
||
{/* Logo */}
|
||
<div className="text-center mb-8">
|
||
<h1 className="text-2xl font-bold text-gray-900">FLNXI 素材系统</h1>
|
||
<p className="text-gray-500 mt-2">请激活您的许可证</p>
|
||
</div>
|
||
|
||
{/* 许可证输入 */}
|
||
<div className="mb-6">
|
||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||
许可证密钥
|
||
</label>
|
||
<input
|
||
type="text"
|
||
value={licenseKey}
|
||
onChange={handleKeyChange}
|
||
placeholder="XXXX-XXXX-XXXX-XXXX"
|
||
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent text-center text-lg tracking-wider font-mono"
|
||
maxLength={19}
|
||
disabled={loading}
|
||
/>
|
||
</div>
|
||
|
||
{/* 错误提示 */}
|
||
{error && (
|
||
<div className="mb-4 p-3 bg-red-50 border border-red-200 rounded-lg text-red-600 text-sm">
|
||
{error}
|
||
</div>
|
||
)}
|
||
|
||
{/* 激活按钮 */}
|
||
<button
|
||
onClick={handleActivate}
|
||
disabled={loading || licenseKey.length !== 19}
|
||
className="w-full py-3 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed transition-colors"
|
||
>
|
||
{loading ? '激活中...' : '激活许可证'}
|
||
</button>
|
||
|
||
{/* 分隔线 */}
|
||
<div className="my-6 flex items-center">
|
||
<div className="flex-1 border-t border-gray-200"></div>
|
||
<span className="px-4 text-sm text-gray-400">或</span>
|
||
<div className="flex-1 border-t border-gray-200"></div>
|
||
</div>
|
||
|
||
{/* 免费试用 */}
|
||
<button
|
||
onClick={handleFreeTrial}
|
||
disabled={loading}
|
||
className="w-full py-3 border border-gray-300 text-gray-700 rounded-lg font-medium hover:bg-gray-50 disabled:cursor-not-allowed transition-colors"
|
||
>
|
||
免费试用
|
||
</button>
|
||
|
||
{/* 免费版说明 */}
|
||
<p className="mt-4 text-center text-xs text-gray-400">
|
||
免费版限制:10 个用户、100 个素材
|
||
</p>
|
||
</div>
|
||
|
||
{/* 联系信息 */}
|
||
<p className="mt-6 text-center text-sm text-gray-500">
|
||
需要购买许可证?请联系我们
|
||
</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|