diff --git a/.gitattributes b/.gitattributes
index 8bf40a14f..63328aaf1 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -35,5 +35,4 @@
# GitHub Linguist - Language Detection
# ============================================
# Mark web frontend as vendored so GitHub recognizes this as a Go project
-web/** linguist-vendored
electron/** linguist-vendored
diff --git a/web/src/components/common/examples/ChannelKeyViewExample.jsx b/web/src/components/common/examples/ChannelKeyViewExample.jsx
deleted file mode 100644
index 1bb2998b2..000000000
--- a/web/src/components/common/examples/ChannelKeyViewExample.jsx
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-Copyright (C) 2025 QuantumNous
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-For commercial licensing, please contact support@quantumnous.com
-*/
-
-import React, { useState } from 'react';
-import { useTranslation } from 'react-i18next';
-import { Button, Modal } from '@douyinfe/semi-ui';
-import { useSecureVerification } from '../../../hooks/common/useSecureVerification';
-import { createApiCalls } from '../../../services/secureVerification';
-import SecureVerificationModal from '../modals/SecureVerificationModal';
-import ChannelKeyDisplay from '../ui/ChannelKeyDisplay';
-
-/**
- * 渠道密钥查看组件使用示例
- * 展示如何使用通用安全验证系统
- */
-const ChannelKeyViewExample = ({ channelId }) => {
- const { t } = useTranslation();
- const [keyData, setKeyData] = useState('');
- const [showKeyModal, setShowKeyModal] = useState(false);
-
- // 使用通用安全验证 Hook
- const {
- isModalVisible,
- verificationMethods,
- verificationState,
- startVerification,
- executeVerification,
- cancelVerification,
- setVerificationCode,
- switchVerificationMethod,
- } = useSecureVerification({
- onSuccess: (result) => {
- // 验证成功后处理结果
- if (result.success && result.data?.key) {
- setKeyData(result.data.key);
- setShowKeyModal(true);
- }
- },
- successMessage: t('密钥获取成功'),
- });
-
- // 开始查看密钥流程
- const handleViewKey = async () => {
- const apiCall = createApiCalls.viewChannelKey(channelId);
-
- await startVerification(apiCall, {
- title: t('查看渠道密钥'),
- description: t('为了保护账户安全,请验证您的身份。'),
- preferredMethod: 'passkey', // 可以指定首选验证方式
- });
- };
-
- return (
- <>
- {/* 查看密钥按钮 */}
-
-
- {/* 安全验证模态框 */}
-
-
- {/* 密钥显示模态框 */}
- setShowKeyModal(false)}
- footer={
-
- }
- width={700}
- style={{ maxWidth: '90vw' }}
- >
-
-
- >
- );
-};
-
-export default ChannelKeyViewExample;
diff --git a/web/src/components/common/modals/TwoFactorAuthModal.jsx b/web/src/components/common/modals/TwoFactorAuthModal.jsx
deleted file mode 100644
index 082e63d79..000000000
--- a/web/src/components/common/modals/TwoFactorAuthModal.jsx
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-Copyright (C) 2025 QuantumNous
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-For commercial licensing, please contact support@quantumnous.com
-*/
-
-import React from 'react';
-import { useTranslation } from 'react-i18next';
-import { Modal, Button, Input, Typography } from '@douyinfe/semi-ui';
-
-/**
- * 可复用的两步验证模态框组件
- * @param {Object} props
- * @param {boolean} props.visible - 是否显示模态框
- * @param {string} props.code - 验证码值
- * @param {boolean} props.loading - 是否正在验证
- * @param {Function} props.onCodeChange - 验证码变化回调
- * @param {Function} props.onVerify - 验证回调
- * @param {Function} props.onCancel - 取消回调
- * @param {string} props.title - 模态框标题
- * @param {string} props.description - 验证描述文本
- * @param {string} props.placeholder - 输入框占位文本
- */
-const TwoFactorAuthModal = ({
- visible,
- code,
- loading,
- onCodeChange,
- onVerify,
- onCancel,
- title,
- description,
- placeholder,
-}) => {
- const { t } = useTranslation();
-
- const handleKeyDown = (e) => {
- if (e.key === 'Enter' && code && !loading) {
- onVerify();
- }
- };
-
- return (
-
-
-
- );
-};
-
-export default TwoFactorAuthModal;
diff --git a/web/src/components/playground/index.js b/web/src/components/playground/index.js
deleted file mode 100644
index 8c470351b..000000000
--- a/web/src/components/playground/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright (C) 2025 QuantumNous
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-For commercial licensing, please contact support@quantumnous.com
-*/
-
-export { default as SettingsPanel } from './SettingsPanel';
-export { default as ChatArea } from './ChatArea';
-export { default as DebugPanel } from './DebugPanel';
-export { default as MessageContent } from './MessageContent';
-export { default as MessageActions } from './MessageActions';
-export { default as CustomInputRender } from './CustomInputRender';
-export { default as SSEViewer } from './SSEViewer';
-export { default as ParameterControl } from './ParameterControl';
-export { default as ImageUrlInput } from './ImageUrlInput';
-export { default as FloatingButtons } from './FloatingButtons';
-export { default as ConfigManager } from './ConfigManager';
-
-export {
- saveConfig,
- loadConfig,
- clearConfig,
- hasStoredConfig,
- getConfigTimestamp,
- exportConfig,
- importConfig,
-} from './configStorage';
diff --git a/web/src/components/settings/personal/cards/ModelsList.jsx b/web/src/components/settings/personal/cards/ModelsList.jsx
deleted file mode 100644
index 3f374fd44..000000000
--- a/web/src/components/settings/personal/cards/ModelsList.jsx
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
-Copyright (C) 2025 QuantumNous
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-For commercial licensing, please contact support@quantumnous.com
-*/
-
-import React, { useState, useEffect } from 'react';
-import {
- Empty,
- Skeleton,
- Space,
- Tag,
- Collapsible,
- Tabs,
- TabPane,
- Typography,
- Avatar,
-} from '@douyinfe/semi-ui';
-import {
- IllustrationNoContent,
- IllustrationNoContentDark,
-} from '@douyinfe/semi-illustrations';
-import { IconChevronDown, IconChevronUp } from '@douyinfe/semi-icons';
-import { Settings } from 'lucide-react';
-import { renderModelTag, getModelCategories } from '../../../../helpers';
-
-const ModelsList = ({ t, models, modelsLoading, copyText }) => {
- const [isModelsExpanded, setIsModelsExpanded] = useState(() => {
- // Initialize from localStorage if available
- const savedState = localStorage.getItem('modelsExpanded');
- return savedState ? JSON.parse(savedState) : false;
- });
- const [activeModelCategory, setActiveModelCategory] = useState('all');
- const MODELS_DISPLAY_COUNT = 25; // 默认显示的模型数量
-
- // Save models expanded state to localStorage whenever it changes
- useEffect(() => {
- localStorage.setItem('modelsExpanded', JSON.stringify(isModelsExpanded));
- }, [isModelsExpanded]);
-
- return (
-
- );
-};
-
-export default ModelsList;
diff --git a/web/src/components/table/models/ModelsDescription.jsx b/web/src/components/table/models/ModelsDescription.jsx
deleted file mode 100644
index a99abd350..000000000
--- a/web/src/components/table/models/ModelsDescription.jsx
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Copyright (C) 2025 QuantumNous
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-For commercial licensing, please contact support@quantumnous.com
-*/
-
-import React from 'react';
-import { Typography } from '@douyinfe/semi-ui';
-import { Layers } from 'lucide-react';
-import CompactModeToggle from '../../common/ui/CompactModeToggle';
-
-const { Text } = Typography;
-
-const ModelsDescription = ({ compactMode, setCompactMode, t }) => {
- return (
-
-
-
- {t('模型管理')}
-
-
-
-
- );
-};
-
-export default ModelsDescription;
diff --git a/web/src/components/table/users/modals/BindSubscriptionModal.jsx b/web/src/components/table/users/modals/BindSubscriptionModal.jsx
deleted file mode 100644
index baa71d1fb..000000000
--- a/web/src/components/table/users/modals/BindSubscriptionModal.jsx
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Copyright (C) 2025 QuantumNous
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-For commercial licensing, please contact support@quantumnous.com
-*/
-
-import React, { useEffect, useMemo, useState } from 'react';
-import { Modal, Select, Space, Typography } from '@douyinfe/semi-ui';
-import { API, showError, showSuccess } from '../../../../helpers';
-
-const { Text } = Typography;
-
-const BindSubscriptionModal = ({ visible, onCancel, user, t, onSuccess }) => {
- const [loading, setLoading] = useState(false);
- const [plans, setPlans] = useState([]);
- const [selectedPlanId, setSelectedPlanId] = useState(null);
-
- const loadPlans = async () => {
- setLoading(true);
- try {
- const res = await API.get('/api/subscription/admin/plans');
- if (res.data?.success) {
- setPlans(res.data.data || []);
- } else {
- showError(res.data?.message || t('加载失败'));
- }
- } catch (e) {
- showError(t('请求失败'));
- } finally {
- setLoading(false);
- }
- };
-
- useEffect(() => {
- if (visible) {
- setSelectedPlanId(null);
- loadPlans();
- }
- }, [visible]);
-
- const planOptions = useMemo(() => {
- return (plans || []).map((p) => ({
- label: `${p?.plan?.title || ''} (${p?.plan?.currency || 'USD'} ${Number(p?.plan?.price_amount || 0)})`,
- value: p?.plan?.id,
- }));
- }, [plans]);
-
- const bind = async () => {
- if (!user?.id) {
- showError(t('用户信息缺失'));
- return;
- }
- if (!selectedPlanId) {
- showError(t('请选择订阅套餐'));
- return;
- }
- setLoading(true);
- try {
- const res = await API.post('/api/subscription/admin/bind', {
- user_id: user.id,
- plan_id: selectedPlanId,
- });
- if (res.data?.success) {
- showSuccess(t('绑定成功'));
- onSuccess?.();
- onCancel?.();
- } else {
- showError(res.data?.message || t('绑定失败'));
- }
- } catch (e) {
- showError(t('请求失败'));
- } finally {
- setLoading(false);
- }
- };
-
- return (
-
-
-