chore: 同步本地到 main 和 Gitea
Made-with: Cursor
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getMongoClient } from '@/lib/mongodb'
|
||||
|
||||
// API密钥接口
|
||||
interface APIKey {
|
||||
@@ -100,40 +101,13 @@ const DEFAULT_FIELD_PERMISSIONS: FieldPermission[] = [
|
||||
},
|
||||
]
|
||||
|
||||
// 内存存储(生产环境应使用MongoDB)
|
||||
let apiKeys: APIKey[] = [
|
||||
{
|
||||
id: 'key_1',
|
||||
name: '存客宝-生产环境',
|
||||
key: 'sk-archer-ckb-prod-a1b2c3d4e5f6',
|
||||
secret: 'sec-ckb-x9y8z7w6v5u4',
|
||||
status: 'active',
|
||||
createdAt: '2026-01-15',
|
||||
expiresAt: null,
|
||||
lastUsed: '2026-01-31 14:32:15',
|
||||
permissions: JSON.parse(JSON.stringify(DEFAULT_FIELD_PERMISSIONS)),
|
||||
rateLimit: { requestsPerDay: 5000, requestsPerMonth: 150000 },
|
||||
billing: { plan: 'pro', usedCredits: 12580, totalCredits: 50000 },
|
||||
callStats: { today: 342, thisMonth: 8956, total: 45678 }
|
||||
},
|
||||
{
|
||||
id: 'key_2',
|
||||
name: '点了码-测试环境',
|
||||
key: 'sk-archer-dlm-test-g7h8i9j0k1l2',
|
||||
secret: 'sec-dlm-m3n4o5p6q7r8',
|
||||
status: 'active',
|
||||
createdAt: '2026-01-20',
|
||||
expiresAt: '2026-04-20',
|
||||
lastUsed: '2026-01-30 09:15:42',
|
||||
permissions: JSON.parse(JSON.stringify(DEFAULT_FIELD_PERMISSIONS)).map((g: FieldPermission) => ({
|
||||
...g,
|
||||
fields: g.fields.map(f => ({ ...f, enabled: f.price <= 2 }))
|
||||
})),
|
||||
rateLimit: { requestsPerDay: 1000, requestsPerMonth: 30000 },
|
||||
billing: { plan: 'basic', usedCredits: 2340, totalCredits: 10000 },
|
||||
callStats: { today: 56, thisMonth: 1234, total: 5678 }
|
||||
},
|
||||
]
|
||||
const COLLECTION = 'api_keys'
|
||||
const DB_NAME = 'KR'
|
||||
|
||||
async function getCollection() {
|
||||
const client = await getMongoClient()
|
||||
return client.db(DB_NAME).collection<APIKey & { _id?: any }>(COLLECTION)
|
||||
}
|
||||
|
||||
// 生成随机密钥
|
||||
function generateKey(prefix: string): string {
|
||||
@@ -152,12 +126,14 @@ export async function GET(request: NextRequest) {
|
||||
const action = searchParams.get('action')
|
||||
const keyId = searchParams.get('id')
|
||||
|
||||
const col = await getCollection()
|
||||
|
||||
// 验证单个密钥
|
||||
if (action === 'validate') {
|
||||
const apiKey = searchParams.get('key')
|
||||
const apiSecret = searchParams.get('secret')
|
||||
|
||||
const key = apiKeys.find(k => k.key === apiKey && k.secret === apiSecret)
|
||||
const key = await col.findOne({ key: apiKey, secret: apiSecret })
|
||||
|
||||
if (!key) {
|
||||
return NextResponse.json({
|
||||
@@ -173,7 +149,6 @@ export async function GET(request: NextRequest) {
|
||||
}, { status: 403 })
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
if (key.expiresAt && new Date(key.expiresAt) < new Date()) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
@@ -196,7 +171,7 @@ export async function GET(request: NextRequest) {
|
||||
|
||||
// 获取单个密钥详情
|
||||
if (keyId) {
|
||||
const key = apiKeys.find(k => k.id === keyId)
|
||||
const key = await col.findOne({ id: keyId })
|
||||
if (!key) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
@@ -210,14 +185,15 @@ export async function GET(request: NextRequest) {
|
||||
}
|
||||
|
||||
// 获取所有密钥列表
|
||||
const keys = await col.find({}).sort({ createdAt: -1 }).toArray()
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: apiKeys.map(k => ({
|
||||
data: keys.map(k => ({
|
||||
...k,
|
||||
key: k.key.substring(0, 12) + '••••••••••••', // 脱敏显示
|
||||
key: k.key.substring(0, 12) + '••••••••••••',
|
||||
secret: '••••••••••••••••'
|
||||
})),
|
||||
total: apiKeys.length
|
||||
total: keys.length
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
@@ -266,7 +242,8 @@ export async function POST(request: NextRequest) {
|
||||
callStats: { today: 0, thisMonth: 0, total: 0 }
|
||||
}
|
||||
|
||||
apiKeys.push(newKey)
|
||||
const col = await getCollection()
|
||||
await col.insertOne(newKey)
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
@@ -289,53 +266,57 @@ export async function PUT(request: NextRequest) {
|
||||
const body = await request.json()
|
||||
const { id, action, permissions, status } = body
|
||||
|
||||
const keyIndex = apiKeys.findIndex(k => k.id === id)
|
||||
if (keyIndex === -1) {
|
||||
const col = await getCollection()
|
||||
const key = await col.findOne({ id })
|
||||
|
||||
if (!key) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '密钥不存在'
|
||||
}, { status: 404 })
|
||||
}
|
||||
|
||||
// 更新权限
|
||||
if (action === 'updatePermissions' && permissions) {
|
||||
apiKeys[keyIndex].permissions = permissions
|
||||
await col.updateOne({ id }, { $set: { permissions } })
|
||||
const updated = await col.findOne({ id })
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: apiKeys[keyIndex],
|
||||
data: updated,
|
||||
message: '权限更新成功'
|
||||
})
|
||||
}
|
||||
|
||||
// 切换状态
|
||||
if (action === 'toggleStatus') {
|
||||
apiKeys[keyIndex].status = apiKeys[keyIndex].status === 'active' ? 'disabled' : 'active'
|
||||
const newStatus = key.status === 'active' ? 'disabled' : 'active'
|
||||
await col.updateOne({ id }, { $set: { status: newStatus } })
|
||||
const updated = await col.findOne({ id })
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: apiKeys[keyIndex],
|
||||
message: `密钥已${apiKeys[keyIndex].status === 'active' ? '启用' : '禁用'}`
|
||||
data: updated,
|
||||
message: `密钥已${newStatus === 'active' ? '启用' : '禁用'}`
|
||||
})
|
||||
}
|
||||
|
||||
// 重新生成密钥
|
||||
if (action === 'regenerate') {
|
||||
apiKeys[keyIndex].key = generateKey('sk-archer-')
|
||||
apiKeys[keyIndex].secret = generateKey('sec-')
|
||||
const newKey = generateKey('sk-archer-')
|
||||
const newSecret = generateKey('sec-')
|
||||
await col.updateOne({ id }, { $set: { key: newKey, secret: newSecret } })
|
||||
const updated = await col.findOne({ id })
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: apiKeys[keyIndex],
|
||||
data: updated,
|
||||
message: '密钥已重新生成'
|
||||
})
|
||||
}
|
||||
|
||||
// 常规更新
|
||||
if (status) {
|
||||
apiKeys[keyIndex].status = status
|
||||
await col.updateOne({ id }, { $set: { status } })
|
||||
}
|
||||
|
||||
const updated = await col.findOne({ id })
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: apiKeys[keyIndex],
|
||||
data: updated,
|
||||
message: '更新成功'
|
||||
})
|
||||
|
||||
@@ -361,19 +342,19 @@ export async function DELETE(request: NextRequest) {
|
||||
}, { status: 400 })
|
||||
}
|
||||
|
||||
const keyIndex = apiKeys.findIndex(k => k.id === id)
|
||||
if (keyIndex === -1) {
|
||||
const col = await getCollection()
|
||||
const result = await col.findOneAndDelete({ id })
|
||||
|
||||
if (!result) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: '密钥不存在'
|
||||
}, { status: 404 })
|
||||
}
|
||||
|
||||
const deletedKey = apiKeys.splice(keyIndex, 1)[0]
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
data: { id: deletedKey.id, name: deletedKey.name },
|
||||
data: { id: result.id, name: result.name },
|
||||
message: '密钥已删除'
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user