feat: 添加 OEM 设置功能并统一 API 统计页面样式

- 添加 OEM 设置管理功能,支持自定义网站名称和图标
- 支持图标文件上传和 Base64 编码存储
- 实现动态更新网站标题和 favicon
- 统一 API 统计页面与管理页面的样式和布局
- 修复文本颜色显示问题,提升可读性
- 优化错误处理和默认值回退机制
- 移除测试文件和冗余代码

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Edric Li
2025-07-27 23:20:44 +08:00
parent 1e51a367b6
commit 9193d64d2a
5 changed files with 587 additions and 37 deletions

View File

@@ -2227,4 +2227,91 @@ function compareVersions(current, latest) {
return currentV.patch - latestV.patch;
}
// 🎨 OEM设置管理
// 获取OEM设置公开接口用于显示
router.get('/oem-settings', async (req, res) => {
try {
const client = redis.getClient();
const oemSettings = await client.get('oem:settings');
// 默认设置
const defaultSettings = {
siteName: 'Claude Relay Service',
siteIcon: '',
siteIconData: '', // Base64编码的图标数据
updatedAt: new Date().toISOString()
};
let settings = defaultSettings;
if (oemSettings) {
try {
settings = { ...defaultSettings, ...JSON.parse(oemSettings) };
} catch (err) {
logger.warn('⚠️ Failed to parse OEM settings, using defaults:', err.message);
}
}
res.json({
success: true,
data: settings
});
} catch (error) {
logger.error('❌ Failed to get OEM settings:', error);
res.status(500).json({ error: 'Failed to get OEM settings', message: error.message });
}
});
// 更新OEM设置
router.put('/oem-settings', authenticateAdmin, async (req, res) => {
try {
const { siteName, siteIcon, siteIconData } = req.body;
// 验证输入
if (!siteName || typeof siteName !== 'string' || siteName.trim().length === 0) {
return res.status(400).json({ error: 'Site name is required' });
}
if (siteName.length > 100) {
return res.status(400).json({ error: 'Site name must be less than 100 characters' });
}
// 验证图标数据大小如果是base64
if (siteIconData && siteIconData.length > 500000) { // 约375KB
return res.status(400).json({ error: 'Icon file must be less than 350KB' });
}
// 验证图标URL如果提供
if (siteIcon && !siteIconData) {
// 简单验证URL格式
try {
new URL(siteIcon);
} catch (err) {
return res.status(400).json({ error: 'Invalid icon URL format' });
}
}
const settings = {
siteName: siteName.trim(),
siteIcon: (siteIcon || '').trim(),
siteIconData: (siteIconData || '').trim(), // Base64数据
updatedAt: new Date().toISOString()
};
const client = redis.getClient();
await client.set('oem:settings', JSON.stringify(settings));
logger.info(`✅ OEM settings updated: ${siteName}`);
res.json({
success: true,
message: 'OEM settings updated successfully',
data: settings
});
} catch (error) {
logger.error('❌ Failed to update OEM settings:', error);
res.status(500).json({ error: 'Failed to update OEM settings', message: error.message });
}
});
module.exports = router;