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:
千羽
2025-08-07 18:19:31 +09:00
parent 4a0eba117c
commit 8a74bf5afe
124 changed files with 20878 additions and 18757 deletions

View File

@@ -2,66 +2,55 @@
<div class="space-y-6">
<!-- Claude OAuth流程 -->
<div v-if="platform === 'claude'">
<div class="bg-blue-50 p-6 rounded-lg border border-blue-200">
<div class="rounded-lg border border-blue-200 bg-blue-50 p-6">
<div class="flex items-start gap-4">
<div class="w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center flex-shrink-0">
<div
class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-blue-500"
>
<i class="fas fa-link text-white" />
</div>
<div class="flex-1">
<h4 class="font-semibold text-blue-900 mb-3">
Claude 账户授权
</h4>
<p class="text-sm text-blue-800 mb-4">
请按照以下步骤完成 Claude 账户的授权
</p>
<h4 class="mb-3 font-semibold text-blue-900">Claude 账户授权</h4>
<p class="mb-4 text-sm text-blue-800">请按照以下步骤完成 Claude 账户授权</p>
<div class="space-y-4">
<!-- 步骤1: 生成授权链接 -->
<div class="bg-white/80 rounded-lg p-4 border border-blue-300">
<div class="rounded-lg border border-blue-300 bg-white/80 p-4">
<div class="flex items-start gap-3">
<div class="w-6 h-6 bg-blue-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
<div
class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-blue-600 text-xs font-bold text-white"
>
1
</div>
<div class="flex-1">
<p class="font-medium text-blue-900 mb-2">
点击下方按钮生成授权链接
</p>
<button
<p class="mb-2 font-medium text-blue-900">点击下方按钮生成授权链接</p>
<button
v-if="!authUrl"
:disabled="loading"
class="btn btn-primary px-4 py-2 text-sm"
:disabled="loading"
@click="generateAuthUrl"
>
<i
v-if="!loading"
class="fas fa-link mr-2"
/>
<div
v-else
class="loading-spinner mr-2"
/>
<i v-if="!loading" class="fas fa-link mr-2" />
<div v-else class="loading-spinner mr-2" />
{{ loading ? '生成中...' : '生成授权链接' }}
</button>
<div
v-else
class="space-y-3"
>
<div v-else class="space-y-3">
<div class="flex items-center gap-2">
<input
type="text"
:value="authUrl"
<input
class="form-input flex-1 bg-gray-50 font-mono text-xs"
readonly
class="form-input flex-1 text-xs font-mono bg-gray-50"
>
<button
class="px-3 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
type="text"
:value="authUrl"
/>
<button
class="rounded-lg bg-gray-100 px-3 py-2 transition-colors hover:bg-gray-200"
title="复制链接"
@click="copyAuthUrl"
>
<i :class="copied ? 'fas fa-check text-green-500' : 'fas fa-copy'" />
</button>
</div>
<button
<button
class="text-xs text-blue-600 hover:text-blue-700"
@click="regenerateAuthUrl"
>
@@ -71,56 +60,58 @@
</div>
</div>
</div>
<!-- 步骤2: 访问链接并授权 -->
<div class="bg-white/80 rounded-lg p-4 border border-blue-300">
<div class="rounded-lg border border-blue-300 bg-white/80 p-4">
<div class="flex items-start gap-3">
<div class="w-6 h-6 bg-blue-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
<div
class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-blue-600 text-xs font-bold text-white"
>
2
</div>
<div class="flex-1">
<p class="font-medium text-blue-900 mb-2">
在浏览器中打开链接并完成授权
</p>
<p class="text-sm text-blue-700 mb-2">
<p class="mb-2 font-medium text-blue-900">在浏览器中打开链接并完成授权</p>
<p class="mb-2 text-sm text-blue-700">
请在新标签页中打开授权链接登录您的 Claude 账户并授权
</p>
<div class="bg-yellow-50 p-3 rounded border border-yellow-300">
<div class="rounded border border-yellow-300 bg-yellow-50 p-3">
<p class="text-xs text-yellow-800">
<i class="fas fa-exclamation-triangle mr-1" />
<strong>注意</strong>如果您设置了代理请确保浏览器也使用相同的代理访问授权页面
<strong>注意</strong
>如果您设置了代理请确保浏览器也使用相同的代理访问授权页面
</p>
</div>
</div>
</div>
</div>
<!-- 步骤3: 输入授权码 -->
<div class="bg-white/80 rounded-lg p-4 border border-blue-300">
<div class="rounded-lg border border-blue-300 bg-white/80 p-4">
<div class="flex items-start gap-3">
<div class="w-6 h-6 bg-blue-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
<div
class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-blue-600 text-xs font-bold text-white"
>
3
</div>
<div class="flex-1">
<p class="font-medium text-blue-900 mb-2">
输入 Authorization Code
</p>
<p class="text-sm text-blue-700 mb-3">
授权完成后页面会显示一个 <strong>Authorization Code</strong>请将其复制并粘贴到下方输入框
<p class="mb-2 font-medium text-blue-900">输入 Authorization Code</p>
<p class="mb-3 text-sm text-blue-700">
授权完成后页面会显示一个
<strong>Authorization Code</strong>请将其复制并粘贴到下方输入框
</p>
<div class="space-y-3">
<div>
<label class="block text-sm font-semibold text-gray-700 mb-2">
<i class="fas fa-key text-blue-500 mr-2" />Authorization Code
<label class="mb-2 block text-sm font-semibold text-gray-700">
<i class="fas fa-key mr-2 text-blue-500" />Authorization Code
</label>
<textarea
v-model="authCode"
rows="3"
<textarea
v-model="authCode"
class="form-input w-full resize-none font-mono text-sm"
placeholder="粘贴从Claude页面获取的Authorization Code..."
rows="3"
/>
</div>
<p class="text-xs text-gray-500 mt-2">
<p class="mt-2 text-xs text-gray-500">
<i class="fas fa-info-circle mr-1" />
请粘贴从Claude页面复制的Authorization Code
</p>
@@ -133,69 +124,58 @@
</div>
</div>
</div>
<!-- Gemini OAuth流程 -->
<div v-else-if="platform === 'gemini'">
<div class="bg-green-50 p-6 rounded-lg border border-green-200">
<div class="rounded-lg border border-green-200 bg-green-50 p-6">
<div class="flex items-start gap-4">
<div class="w-10 h-10 bg-green-500 rounded-lg flex items-center justify-center flex-shrink-0">
<div
class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-green-500"
>
<i class="fas fa-robot text-white" />
</div>
<div class="flex-1">
<h4 class="font-semibold text-green-900 mb-3">
Gemini 账户授权
</h4>
<p class="text-sm text-green-800 mb-4">
请按照以下步骤完成 Gemini 账户的授权
</p>
<h4 class="mb-3 font-semibold text-green-900">Gemini 账户授权</h4>
<p class="mb-4 text-sm text-green-800">请按照以下步骤完成 Gemini 账户授权</p>
<div class="space-y-4">
<!-- 步骤1: 生成授权链接 -->
<div class="bg-white/80 rounded-lg p-4 border border-green-300">
<div class="rounded-lg border border-green-300 bg-white/80 p-4">
<div class="flex items-start gap-3">
<div class="w-6 h-6 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
<div
class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-green-600 text-xs font-bold text-white"
>
1
</div>
<div class="flex-1">
<p class="font-medium text-green-900 mb-2">
点击下方按钮生成授权链接
</p>
<button
<p class="mb-2 font-medium text-green-900">点击下方按钮生成授权链接</p>
<button
v-if="!authUrl"
:disabled="loading"
class="btn btn-primary px-4 py-2 text-sm"
:disabled="loading"
@click="generateAuthUrl"
>
<i
v-if="!loading"
class="fas fa-link mr-2"
/>
<div
v-else
class="loading-spinner mr-2"
/>
<i v-if="!loading" class="fas fa-link mr-2" />
<div v-else class="loading-spinner mr-2" />
{{ loading ? '生成中...' : '生成授权链接' }}
</button>
<div
v-else
class="space-y-3"
>
<div v-else class="space-y-3">
<div class="flex items-center gap-2">
<input
type="text"
:value="authUrl"
<input
class="form-input flex-1 bg-gray-50 font-mono text-xs"
readonly
class="form-input flex-1 text-xs font-mono bg-gray-50"
>
<button
class="px-3 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors"
type="text"
:value="authUrl"
/>
<button
class="rounded-lg bg-gray-100 px-3 py-2 transition-colors hover:bg-gray-200"
title="复制链接"
@click="copyAuthUrl"
>
<i :class="copied ? 'fas fa-check text-green-500' : 'fas fa-copy'" />
</button>
</div>
<button
<button
class="text-xs text-green-600 hover:text-green-700"
@click="regenerateAuthUrl"
>
@@ -205,59 +185,60 @@
</div>
</div>
</div>
<!-- 步骤2: 操作说明 -->
<div class="bg-white/80 rounded-lg p-4 border border-green-300">
<div class="rounded-lg border border-green-300 bg-white/80 p-4">
<div class="flex items-start gap-3">
<div class="w-6 h-6 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
<div
class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-green-600 text-xs font-bold text-white"
>
2
</div>
<div class="flex-1">
<p class="font-medium text-blue-900 mb-2">
在浏览器中打开链接并完成授权
</p>
<p class="text-sm text-blue-700 mb-2">
<p class="mb-2 font-medium text-blue-900">在浏览器中打开链接并完成授权</p>
<p class="mb-2 text-sm text-blue-700">
请在新标签页中打开授权链接登录您的 Gemini 账户并授权
</p>
<div class="bg-yellow-50 p-3 rounded border border-yellow-300">
<div class="rounded border border-yellow-300 bg-yellow-50 p-3">
<p class="text-xs text-yellow-800">
<i class="fas fa-exclamation-triangle mr-1" />
<strong>注意</strong>如果您设置了代理请确保浏览器也使用相同的代理访问授权页面
<strong>注意</strong
>如果您设置了代理请确保浏览器也使用相同的代理访问授权页面
</p>
</div>
</div>
</div>
</div>
<!-- 步骤3: 输入授权码 -->
<div class="bg-white/80 rounded-lg p-4 border border-green-300">
<div class="rounded-lg border border-green-300 bg-white/80 p-4">
<div class="flex items-start gap-3">
<div class="w-6 h-6 bg-green-600 text-white rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0">
<div
class="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-green-600 text-xs font-bold text-white"
>
3
</div>
<div class="flex-1">
<p class="font-medium text-green-900 mb-2">
输入 Authorization Code
</p>
<p class="text-sm text-green-700 mb-3">
<p class="mb-2 font-medium text-green-900">输入 Authorization Code</p>
<p class="mb-3 text-sm text-green-700">
授权完成后页面会显示一个 Authorization Code请将其复制并粘贴到下方输入框
</p>
<div class="space-y-3">
<div>
<label class="block text-sm font-semibold text-gray-700 mb-2">
<i class="fas fa-key text-green-500 mr-2" />Authorization Code
<label class="mb-2 block text-sm font-semibold text-gray-700">
<i class="fas fa-key mr-2 text-green-500" />Authorization Code
</label>
<textarea
v-model="authCode"
rows="3"
<textarea
v-model="authCode"
class="form-input w-full resize-none font-mono text-sm"
placeholder="粘贴从Gemini页面获取的Authorization Code..."
rows="3"
/>
</div>
<div class="mt-2 space-y-1">
<p class="text-xs text-gray-600">
<i class="fas fa-check-circle text-green-500 mr-1" />
请粘贴从Gemini页面复制的Authorization Code
<i class="fas fa-check-circle mr-1 text-green-500" />
请粘贴从Gemini页面复制的Authorization Code
</p>
</div>
</div>
@@ -269,25 +250,22 @@
</div>
</div>
</div>
<div class="flex gap-3 pt-4">
<button
type="button"
class="flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-semibold hover:bg-gray-200 transition-colors"
<button
class="flex-1 rounded-xl bg-gray-100 px-6 py-3 font-semibold text-gray-700 transition-colors hover:bg-gray-200"
type="button"
@click="$emit('back')"
>
上一步
</button>
<button
type="button"
<button
class="btn btn-primary flex-1 px-6 py-3 font-semibold"
:disabled="!canExchange || exchanging"
class="btn btn-primary flex-1 py-3 px-6 font-semibold"
type="button"
@click="exchangeCode"
>
<div
v-if="exchanging"
class="loading-spinner mr-2"
/>
<div v-if="exchanging" class="loading-spinner mr-2" />
{{ exchanging ? '验证中...' : '完成授权' }}
</button>
</div>
@@ -330,15 +308,15 @@ const canExchange = computed(() => {
// 监听授权码输入自动提取URL中的code参数
watch(authCode, (newValue) => {
if (!newValue || typeof newValue !== 'string') return
const trimmedValue = newValue.trim()
// 如果内容为空,不处理
if (!trimmedValue) return
// 检查是否是 URL 格式(包含 http:// 或 https://
const isUrl = trimmedValue.startsWith('http://') || trimmedValue.startsWith('https://')
// 如果是 URL 格式
if (isUrl) {
// 检查是否是正确的 localhost:45462 开头的 URL
@@ -346,7 +324,7 @@ watch(authCode, (newValue) => {
try {
const url = new URL(trimmedValue)
const code = url.searchParams.get('code')
if (code) {
// 成功提取授权码
authCode.value = code
@@ -367,7 +345,7 @@ watch(authCode, (newValue) => {
try {
const url = new URL(trimmedValue)
const code = url.searchParams.get('code')
if (code) {
authCode.value = code
showToast('成功提取授权码!', 'success')
@@ -387,16 +365,18 @@ watch(authCode, (newValue) => {
const generateAuthUrl = async () => {
loading.value = true
try {
const proxyConfig = props.proxy?.enabled ? {
proxy: {
type: props.proxy.type,
host: props.proxy.host,
port: parseInt(props.proxy.port),
username: props.proxy.username || null,
password: props.proxy.password || null
}
} : {}
const proxyConfig = props.proxy?.enabled
? {
proxy: {
type: props.proxy.type,
host: props.proxy.host,
port: parseInt(props.proxy.port),
username: props.proxy.username || null,
password: props.proxy.password || null
}
}
: {}
if (props.platform === 'claude') {
const result = await accountsStore.generateClaudeAuthUrl(proxyConfig)
authUrl.value = result.authUrl
@@ -448,11 +428,11 @@ const copyAuthUrl = async () => {
// 交换授权码
const exchangeCode = async () => {
if (!canExchange.value) return
exchanging.value = true
try {
let data = {}
if (props.platform === 'claude') {
// Claude使用sessionId和callbackUrl即授权码
data = {
@@ -466,7 +446,7 @@ const exchangeCode = async () => {
sessionId: sessionId.value
}
}
// 添加代理配置(如果启用)
if (props.proxy?.enabled) {
data.proxy = {
@@ -477,14 +457,14 @@ const exchangeCode = async () => {
password: props.proxy.password || null
}
}
let tokenInfo
if (props.platform === 'claude') {
tokenInfo = await accountsStore.exchangeClaudeCode(data)
} else if (props.platform === 'gemini') {
tokenInfo = await accountsStore.exchangeGeminiCode(data)
}
emit('success', tokenInfo)
} catch (error) {
showToast(error.message || '授权失败,请检查授权码是否正确', 'error')
@@ -492,4 +472,4 @@ const exchangeCode = async () => {
exchanging.value = false
}
}
</script>
</script>