mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 09:38:02 +00:00
refactor: standardize code formatting and linting configuration
- Replace .eslintrc.js with .eslintrc.cjs for better ES module compatibility - Add .prettierrc configuration for consistent code formatting - Update package.json with new lint and format scripts - Add nodemon.json for development hot reloading configuration - Standardize code formatting across all JavaScript and Vue files - Update web admin SPA with improved linting rules and formatting - Add prettier configuration to web admin SPA 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,122 +1,131 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div class="fixed inset-0 modal z-50 flex items-center justify-center p-4">
|
||||
<div class="modal-content w-full max-w-2xl p-8 mx-auto max-h-[90vh] overflow-y-auto custom-scrollbar">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div class="modal fixed inset-0 z-50 flex items-center justify-center p-4">
|
||||
<div
|
||||
class="modal-content custom-scrollbar mx-auto max-h-[90vh] w-full max-w-2xl overflow-y-auto p-8"
|
||||
>
|
||||
<div class="mb-6 flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-12 h-12 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center">
|
||||
<i class="fas fa-layer-group text-white text-lg" />
|
||||
<div
|
||||
class="flex h-12 w-12 items-center justify-center rounded-xl bg-gradient-to-br from-green-500 to-green-600"
|
||||
>
|
||||
<i class="fas fa-layer-group text-lg text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-bold text-gray-900">
|
||||
批量创建成功
|
||||
</h3>
|
||||
<p class="text-sm text-gray-600">
|
||||
成功创建 {{ apiKeys.length }} 个 API Key
|
||||
</p>
|
||||
<h3 class="text-xl font-bold text-gray-900">批量创建成功</h3>
|
||||
<p class="text-sm text-gray-600">成功创建 {{ apiKeys.length }} 个 API Key</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="text-gray-400 hover:text-gray-600 transition-colors"
|
||||
<button
|
||||
class="text-gray-400 transition-colors hover:text-gray-600"
|
||||
title="直接关闭(不推荐)"
|
||||
@click="handleDirectClose"
|
||||
>
|
||||
<i class="fas fa-times text-xl" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 警告提示 -->
|
||||
<div class="bg-amber-50 border-l-4 border-amber-400 p-4 mb-6">
|
||||
<div class="mb-6 border-l-4 border-amber-400 bg-amber-50 p-4">
|
||||
<div class="flex items-start">
|
||||
<div class="w-6 h-6 bg-amber-400 rounded-lg flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||
<i class="fas fa-exclamation-triangle text-white text-sm" />
|
||||
<div
|
||||
class="mt-0.5 flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-lg bg-amber-400"
|
||||
>
|
||||
<i class="fas fa-exclamation-triangle text-sm text-white" />
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h5 class="font-semibold text-amber-900 mb-1">
|
||||
重要提醒
|
||||
</h5>
|
||||
<h5 class="mb-1 font-semibold text-amber-900">重要提醒</h5>
|
||||
<p class="text-sm text-amber-800">
|
||||
这是您唯一能看到所有 API Key 的机会。关闭此窗口后,系统将不再显示完整的 API Key。请立即下载并妥善保存。
|
||||
这是您唯一能看到所有 API Key 的机会。关闭此窗口后,系统将不再显示完整的 API
|
||||
Key。请立即下载并妥善保存。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 统计信息 -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||
<div class="bg-gradient-to-br from-blue-50 to-blue-100 rounded-lg p-4 border border-blue-200">
|
||||
<div class="mb-6 grid grid-cols-2 gap-4 md:grid-cols-4">
|
||||
<div
|
||||
class="rounded-lg border border-blue-200 bg-gradient-to-br from-blue-50 to-blue-100 p-4"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-blue-600 font-medium">
|
||||
创建数量
|
||||
</p>
|
||||
<p class="text-2xl font-bold text-blue-900 mt-1">
|
||||
<p class="text-xs font-medium text-blue-600">创建数量</p>
|
||||
<p class="mt-1 text-2xl font-bold text-blue-900">
|
||||
{{ apiKeys.length }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-blue-500 bg-opacity-20 rounded-lg flex items-center justify-center">
|
||||
<div
|
||||
class="flex h-10 w-10 items-center justify-center rounded-lg bg-blue-500 bg-opacity-20"
|
||||
>
|
||||
<i class="fas fa-key text-blue-600" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-br from-green-50 to-green-100 rounded-lg p-4 border border-green-200">
|
||||
|
||||
<div
|
||||
class="rounded-lg border border-green-200 bg-gradient-to-br from-green-50 to-green-100 p-4"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-green-600 font-medium">
|
||||
基础名称
|
||||
</p>
|
||||
<p class="text-lg font-bold text-green-900 mt-1 truncate">
|
||||
<p class="text-xs font-medium text-green-600">基础名称</p>
|
||||
<p class="mt-1 truncate text-lg font-bold text-green-900">
|
||||
{{ baseName }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-green-500 bg-opacity-20 rounded-lg flex items-center justify-center">
|
||||
<div
|
||||
class="flex h-10 w-10 items-center justify-center rounded-lg bg-green-500 bg-opacity-20"
|
||||
>
|
||||
<i class="fas fa-tag text-green-600" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-br from-purple-50 to-purple-100 rounded-lg p-4 border border-purple-200">
|
||||
|
||||
<div
|
||||
class="rounded-lg border border-purple-200 bg-gradient-to-br from-purple-50 to-purple-100 p-4"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-purple-600 font-medium">
|
||||
权限范围
|
||||
</p>
|
||||
<p class="text-lg font-bold text-purple-900 mt-1">
|
||||
<p class="text-xs font-medium text-purple-600">权限范围</p>
|
||||
<p class="mt-1 text-lg font-bold text-purple-900">
|
||||
{{ getPermissionText() }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-purple-500 bg-opacity-20 rounded-lg flex items-center justify-center">
|
||||
<div
|
||||
class="flex h-10 w-10 items-center justify-center rounded-lg bg-purple-500 bg-opacity-20"
|
||||
>
|
||||
<i class="fas fa-shield-alt text-purple-600" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-br from-orange-50 to-orange-100 rounded-lg p-4 border border-orange-200">
|
||||
|
||||
<div
|
||||
class="rounded-lg border border-orange-200 bg-gradient-to-br from-orange-50 to-orange-100 p-4"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-xs text-orange-600 font-medium">
|
||||
过期时间
|
||||
</p>
|
||||
<p class="text-lg font-bold text-orange-900 mt-1">
|
||||
<p class="text-xs font-medium text-orange-600">过期时间</p>
|
||||
<p class="mt-1 text-lg font-bold text-orange-900">
|
||||
{{ getExpiryText() }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-10 h-10 bg-orange-500 bg-opacity-20 rounded-lg flex items-center justify-center">
|
||||
<div
|
||||
class="flex h-10 w-10 items-center justify-center rounded-lg bg-orange-500 bg-opacity-20"
|
||||
>
|
||||
<i class="fas fa-clock text-orange-600" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- API Keys 预览 -->
|
||||
<div class="mb-6">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="text-sm font-semibold text-gray-700">API Keys 预览</label>
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
<button
|
||||
class="flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800"
|
||||
type="button"
|
||||
class="text-xs text-blue-600 hover:text-blue-800 flex items-center gap-1"
|
||||
@click="togglePreview"
|
||||
>
|
||||
<i :class="['fas', showPreview ? 'fa-eye-slash' : 'fa-eye']" />
|
||||
@@ -125,35 +134,35 @@
|
||||
<span class="text-xs text-gray-500">(最多显示前10个)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div
|
||||
v-if="showPreview"
|
||||
class="bg-gray-900 rounded-lg p-4 max-h-48 overflow-y-auto custom-scrollbar"
|
||||
class="custom-scrollbar max-h-48 overflow-y-auto rounded-lg bg-gray-900 p-4"
|
||||
>
|
||||
<pre class="text-xs text-gray-300 font-mono">{{ getPreviewText() }}</pre>
|
||||
<pre class="font-mono text-xs text-gray-300">{{ getPreviewText() }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="flex gap-3">
|
||||
<button
|
||||
class="flex-1 btn btn-primary py-3 px-6 font-semibold flex items-center justify-center gap-2"
|
||||
<button
|
||||
class="btn btn-primary flex flex-1 items-center justify-center gap-2 px-6 py-3 font-semibold"
|
||||
@click="downloadApiKeys"
|
||||
>
|
||||
<i class="fas fa-download" />
|
||||
下载所有 API Keys
|
||||
</button>
|
||||
<button
|
||||
class="px-6 py-3 bg-gray-200 text-gray-800 rounded-xl font-semibold hover:bg-gray-300 transition-colors border border-gray-300"
|
||||
<button
|
||||
class="rounded-xl border border-gray-300 bg-gray-200 px-6 py-3 font-semibold text-gray-800 transition-colors hover:bg-gray-300"
|
||||
@click="handleClose"
|
||||
>
|
||||
我已保存
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 额外提示 -->
|
||||
<div class="mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200">
|
||||
<p class="text-xs text-blue-700 flex items-start">
|
||||
<div class="mt-4 rounded-lg border border-blue-200 bg-blue-50 p-3">
|
||||
<p class="flex items-start text-xs text-blue-700">
|
||||
<i class="fas fa-info-circle mr-2 mt-0.5 flex-shrink-0" />
|
||||
<span>
|
||||
下载的文件格式为文本文件(.txt),每行包含一个 API Key。
|
||||
@@ -197,9 +206,9 @@ const getPermissionText = () => {
|
||||
if (props.apiKeys.length === 0) return '未知'
|
||||
const permissions = props.apiKeys[0].permissions
|
||||
const permissionMap = {
|
||||
'all': '全部服务',
|
||||
'claude': '仅 Claude',
|
||||
'gemini': '仅 Gemini'
|
||||
all: '全部服务',
|
||||
claude: '仅 Claude',
|
||||
gemini: '仅 Gemini'
|
||||
}
|
||||
return permissionMap[permissions] || permissions
|
||||
}
|
||||
@@ -209,11 +218,11 @@ const getExpiryText = () => {
|
||||
if (props.apiKeys.length === 0) return '未知'
|
||||
const expiresAt = props.apiKeys[0].expiresAt
|
||||
if (!expiresAt) return '永不过期'
|
||||
|
||||
|
||||
const expiryDate = new Date(expiresAt)
|
||||
const now = new Date()
|
||||
const diffDays = Math.ceil((expiryDate - now) / (1000 * 60 * 60 * 24))
|
||||
|
||||
|
||||
if (diffDays <= 7) return `${diffDays}天`
|
||||
if (diffDays <= 30) return `${Math.ceil(diffDays / 7)}周`
|
||||
if (diffDays <= 365) return `${Math.ceil(diffDays / 30)}个月`
|
||||
@@ -228,44 +237,46 @@ const togglePreview = () => {
|
||||
// 获取预览文本
|
||||
const getPreviewText = () => {
|
||||
const previewKeys = props.apiKeys.slice(0, 10)
|
||||
const lines = previewKeys.map((key, index) => {
|
||||
const lines = previewKeys.map((key) => {
|
||||
return `${key.name}: ${key.apiKey || key.key || ''}`
|
||||
})
|
||||
|
||||
|
||||
if (props.apiKeys.length > 10) {
|
||||
lines.push(`... 还有 ${props.apiKeys.length - 10} 个 API Key`)
|
||||
}
|
||||
|
||||
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
// 下载 API Keys
|
||||
const downloadApiKeys = () => {
|
||||
// 生成文件内容
|
||||
const content = props.apiKeys.map(key => {
|
||||
return `${key.name}: ${key.apiKey || key.key || ''}`
|
||||
}).join('\n')
|
||||
|
||||
const content = props.apiKeys
|
||||
.map((key) => {
|
||||
return `${key.name}: ${key.apiKey || key.key || ''}`
|
||||
})
|
||||
.join('\n')
|
||||
|
||||
// 创建 Blob 对象
|
||||
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' })
|
||||
|
||||
|
||||
// 创建下载链接
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
|
||||
|
||||
// 生成文件名(包含时间戳)
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)
|
||||
link.download = `api-keys-${baseName.value}-${timestamp}.txt`
|
||||
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
|
||||
|
||||
// 释放 URL 对象
|
||||
URL.revokeObjectURL(url)
|
||||
|
||||
|
||||
showToast('API Keys 文件已下载', 'success')
|
||||
}
|
||||
|
||||
@@ -306,9 +317,7 @@ const handleDirectClose = async () => {
|
||||
}
|
||||
} else {
|
||||
// 降级方案
|
||||
const confirmed = confirm(
|
||||
'您还没有下载 API Keys,关闭后将无法再次查看。\n\n确定要关闭吗?'
|
||||
)
|
||||
const confirmed = confirm('您还没有下载 API Keys,关闭后将无法再次查看。\n\n确定要关闭吗?')
|
||||
if (confirmed) {
|
||||
emit('close')
|
||||
}
|
||||
@@ -321,4 +330,4 @@ pre {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user