mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
✨ 新功能 - 支持通过refreshToken新增Codex账号,创建时立即验证token有效性 - API Key新增首次使用自动激活机制,支持activation模式设置有效期 - 前端账号表单增加token验证功能,确保账号创建成功 🐛 修复 - 修复Codex token刷新失败问题,增加分布式锁防止并发刷新 - 优化token刷新错误处理,提供更详细的错误信息和建议 - 修复OpenAI账号token过期检测和自动刷新逻辑 📝 文档更新 - 更新README中Codex使用说明,改为config.toml配置方式 - 优化Cherry Studio等第三方工具接入文档 - 添加详细的配置示例和账号类型说明 🎨 界面优化 - 改进账号创建表单UI,支持手动和OAuth两种模式 - 优化API Key过期时间编辑弹窗,支持激活操作 - 调整教程页面布局,提升移动端响应式体验 💡 代码改进 - 重构token刷新服务,增强错误处理和重试机制 - 优化代理配置处理,确保OAuth请求正确使用代理 - 改进webhook通知,增加token刷新失败告警
72 lines
2.0 KiB
JavaScript
72 lines
2.0 KiB
JavaScript
// Toast 通知管理
|
|
let toastContainer = null
|
|
let toastId = 0
|
|
|
|
export function showToast(message, type = 'info', title = '', duration = 3000) {
|
|
// 创建容器
|
|
if (!toastContainer) {
|
|
toastContainer = document.createElement('div')
|
|
toastContainer.id = 'toast-container'
|
|
toastContainer.style.cssText = 'position: fixed; top: 20px; right: 20px; z-index: 10000;'
|
|
document.body.appendChild(toastContainer)
|
|
}
|
|
|
|
// 创建 toast
|
|
const id = ++toastId
|
|
const toast = document.createElement('div')
|
|
toast.className = `toast rounded-2xl p-4 shadow-2xl backdrop-blur-sm toast-${type}`
|
|
toast.style.cssText = `
|
|
position: relative;
|
|
min-width: 320px;
|
|
max-width: 500px;
|
|
margin-bottom: 16px;
|
|
transform: translateX(100%);
|
|
transition: transform 0.3s ease-in-out;
|
|
`
|
|
|
|
const iconMap = {
|
|
success: 'fas fa-check-circle',
|
|
error: 'fas fa-times-circle',
|
|
warning: 'fas fa-exclamation-triangle',
|
|
info: 'fas fa-info-circle'
|
|
}
|
|
|
|
// 处理消息中的换行符,转换为 HTML 换行
|
|
const formattedMessage = message.replace(/\n/g, '<br>')
|
|
|
|
toast.innerHTML = `
|
|
<div class="flex items-start gap-3">
|
|
<div class="flex-shrink-0 mt-0.5">
|
|
<i class="${iconMap[type]} text-lg"></i>
|
|
</div>
|
|
<div class="flex-1 min-w-0">
|
|
${title ? `<h4 class="font-semibold text-sm mb-1">${title}</h4>` : ''}
|
|
<p class="text-sm opacity-90 leading-relaxed">${formattedMessage}</p>
|
|
</div>
|
|
<button onclick="this.parentElement.parentElement.remove()"
|
|
class="flex-shrink-0 text-white/70 hover:text-white transition-colors ml-2">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
</div>
|
|
`
|
|
|
|
toastContainer.appendChild(toast)
|
|
|
|
// 触发动画
|
|
setTimeout(() => {
|
|
toast.style.transform = 'translateX(0)'
|
|
}, 10)
|
|
|
|
// 自动移除
|
|
if (duration > 0) {
|
|
setTimeout(() => {
|
|
toast.style.transform = 'translateX(100%)'
|
|
setTimeout(() => {
|
|
toast.remove()
|
|
}, 300)
|
|
}, duration)
|
|
}
|
|
|
|
return id
|
|
}
|