feat: Provider 异步删除、可配置密码策略、Hub 超时优化及多项改进

- 新增 Provider 异步删除任务系统,后台分阶段删除子资源并清理残留引用
- 新增可配置密码策略等级(weak/medium/strong),支持系统设置面板调整
- aether-hub 升级至 0.1.4,idle timeout 支持禁用(设为 0),worker 默认超时调整为 120s
- OAuth 手动续期增加 Redis 分布式锁,防止并发刷新冲突
- ProxyNode 心跳检测改为 asyncio.to_thread,避免阻塞事件循环
- 删除 ModelMultiSelect 和 useInvalidModels,MultiSelect 组件通用化
- 明确 allowed_providers/allowed_api_formats 的 NULL 与空数组语义
- 前端 StandaloneKeyFormDialog、UserFormDialog 等多处 UI 优化
- 新增 Alembic 迁移脚本清理 Provider 删除后的残留引用
- 补充相关测试用例
This commit is contained in:
fawney19
2026-03-12 01:11:35 +08:00
parent 0d770d1c4d
commit 6e51a3f45d
55 changed files with 3219 additions and 862 deletions
@@ -54,6 +54,40 @@
</p>
</div>
<div>
<Label
for="password-policy-level"
class="block text-sm font-medium mb-2"
>
密码策略
</Label>
<Select
:model-value="passwordPolicyLevel"
@update:model-value="$emit('update:passwordPolicyLevel', $event)"
>
<SelectTrigger
id="password-policy-level"
class="mt-1"
>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="weak">
弱密码 - 至少 6 个字符
</SelectItem>
<SelectItem value="medium">
中等密码 - 至少 8 位,含字母和数字
</SelectItem>
<SelectItem value="strong">
强密码 - 至少 8 位,含大小写字母、数字和特殊字符
</SelectItem>
</SelectContent>
</Select>
<p class="mt-1 text-xs text-muted-foreground">
影响注册、创建用户、重置/修改密码的校验规则
</p>
</div>
<div class="flex items-center h-full">
<div class="flex items-center space-x-2">
<Checkbox
@@ -125,12 +159,18 @@ import Button from '@/components/ui/button.vue'
import Input from '@/components/ui/input.vue'
import Label from '@/components/ui/label.vue'
import Checkbox from '@/components/ui/checkbox.vue'
import Select from '@/components/ui/select.vue'
import SelectTrigger from '@/components/ui/select-trigger.vue'
import SelectValue from '@/components/ui/select-value.vue'
import SelectContent from '@/components/ui/select-content.vue'
import SelectItem from '@/components/ui/select-item.vue'
import { CardSection } from '@/components/layout'
defineProps<{
defaultUserInitialGiftUsd: number
rateLimitPerMinute: number
enableRegistration: boolean
passwordPolicyLevel: string
autoDeleteExpiredKeys: boolean
enableFormatConversion: boolean
loading: boolean
@@ -142,6 +182,7 @@ defineEmits<{
'update:defaultUserInitialGiftUsd': [value: number]
'update:rateLimitPerMinute': [value: number]
'update:enableRegistration': [value: boolean]
'update:passwordPolicyLevel': [value: string]
'update:autoDeleteExpiredKeys': [value: boolean]
'update:enableFormatConversion': [value: boolean]
}>()
@@ -14,6 +14,7 @@ export interface SystemConfig {
default_user_initial_gift_usd: number
rate_limit_per_minute: number
enable_registration: boolean
password_policy_level: string
// 独立余额 Key 过期管理
auto_delete_expired_keys: boolean
// 格式转换
@@ -47,6 +48,7 @@ const CONFIG_KEYS = [
'default_user_initial_gift_usd',
'rate_limit_per_minute',
'enable_registration',
'password_policy_level',
// 独立余额 Key 过期管理
'auto_delete_expired_keys',
// 格式转换
@@ -81,6 +83,7 @@ function createDefaultConfig(): SystemConfig {
default_user_initial_gift_usd: 10.0,
rate_limit_per_minute: 0,
enable_registration: false,
password_policy_level: 'weak',
// 独立余额 Key 过期管理
auto_delete_expired_keys: false,
// 格式转换
@@ -140,6 +143,7 @@ export function useSystemConfig() {
systemConfig.value.default_user_initial_gift_usd !== originalConfig.value.default_user_initial_gift_usd ||
systemConfig.value.rate_limit_per_minute !== originalConfig.value.rate_limit_per_minute ||
systemConfig.value.enable_registration !== originalConfig.value.enable_registration ||
systemConfig.value.password_policy_level !== originalConfig.value.password_policy_level ||
systemConfig.value.auto_delete_expired_keys !== originalConfig.value.auto_delete_expired_keys ||
systemConfig.value.enable_format_conversion !== originalConfig.value.enable_format_conversion
)
@@ -296,6 +300,11 @@ export function useSystemConfig() {
value: systemConfig.value.enable_registration,
description: '是否开放用户注册',
},
{
key: 'password_policy_level',
value: systemConfig.value.password_policy_level,
description: '密码策略等级',
},
{
key: 'auto_delete_expired_keys',
value: systemConfig.value.auto_delete_expired_keys,
@@ -317,6 +326,7 @@ export function useSystemConfig() {
originalConfig.value.default_user_initial_gift_usd = systemConfig.value.default_user_initial_gift_usd
originalConfig.value.rate_limit_per_minute = systemConfig.value.rate_limit_per_minute
originalConfig.value.enable_registration = systemConfig.value.enable_registration
originalConfig.value.password_policy_level = systemConfig.value.password_policy_level
originalConfig.value.auto_delete_expired_keys =
systemConfig.value.auto_delete_expired_keys
originalConfig.value.enable_format_conversion =