分销商后端: - 分销商注册/审核/CRUD API - 分站用户注册/登录/登出 (session cookie auth) - 分站 Token CRUD、充值兑换、套餐订阅 - 分站域名/子域名自动识别中间件 (DistIdentify) - 分销商收益异步记账 + markup 加价计费 - 模型价格快照、渠道路由配置 - 管理员审核/管理分销商 主站前端 (web/): - 分销商注册申请、设置、客户管理(分页)、套餐管理(含速率限制) - 收益管理(含汇总卡片+分页列表)、模型管理 - 管理员分销商审核面板 - DistributorLayout 标签页布局 + 路由 分站前端模板 (dist-site/): - React + Vite + Tailwind 暗色主题 glassmorphism 设计 - react-bits 动画组件 (GradientText, BlurText, CountUp, SpotlightCard 等) - Session cookie 认证 + New-Api-User header - 首页/登录/注册/Dashboard/API Keys/定价/套餐 7 个页面 - Token 创建后一次性密钥展示、余额检查订阅确认 Bug 修复: - 修复 DistUserRegister 密码双重哈希导致用户无法登录 - 修复 401 响应不清除 React user 状态 - 修复订阅确认弹窗不显示余额且提前关闭 - 修复 Home 页 Subscribe 按钮跳转错误 (/dashboard → /packages) - 修复 Login/Register 组件卸载后 setState 警告 - 修复 DistributorEarnings 引用不存在的 username 字段 - 修复 DistributorCustomers 引用不存在的 created_at 字段 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
1.6 KiB
JavaScript
54 lines
1.6 KiB
JavaScript
/** @type {import('tailwindcss').Config} */
|
|
export default {
|
|
content: ['./index.html', './src/**/*.{js,jsx}'],
|
|
darkMode: 'class',
|
|
theme: {
|
|
extend: {
|
|
fontFamily: {
|
|
sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
|
|
heading: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
|
|
mono: ['JetBrains Mono', 'Fira Code', 'monospace'],
|
|
},
|
|
colors: {
|
|
brand: {
|
|
50: '#eef2ff',
|
|
100: '#e0e7ff',
|
|
200: '#c7d2fe',
|
|
300: '#a5b4fc',
|
|
400: '#818cf8',
|
|
500: '#6366f1',
|
|
600: '#4f46e5',
|
|
700: '#4338ca',
|
|
800: '#3730a3',
|
|
900: '#312e81',
|
|
},
|
|
},
|
|
animation: {
|
|
'star-movement-bottom': 'star-movement-bottom linear infinite alternate',
|
|
'star-movement-top': 'star-movement-top linear infinite alternate',
|
|
'fade-in': 'fade-in 0.5s ease-out',
|
|
'slide-up': 'slide-up 0.5s ease-out',
|
|
},
|
|
keyframes: {
|
|
'star-movement-bottom': {
|
|
'0%': { transform: 'translate(0%, 0%)', opacity: '1' },
|
|
'100%': { transform: 'translate(-100%, 0%)', opacity: '0' },
|
|
},
|
|
'star-movement-top': {
|
|
'0%': { transform: 'translate(0%, 0%)', opacity: '1' },
|
|
'100%': { transform: 'translate(100%, 0%)', opacity: '0' },
|
|
},
|
|
'fade-in': {
|
|
'0%': { opacity: '0' },
|
|
'100%': { opacity: '1' },
|
|
},
|
|
'slide-up': {
|
|
'0%': { opacity: '0', transform: 'translateY(20px)' },
|
|
'100%': { opacity: '1', transform: 'translateY(0)' },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
plugins: [],
|
|
};
|