From 5c46fe648d03c8ca99397d55e540e253c8c43897 Mon Sep 17 00:00:00 2001 From: CI Test Date: Sun, 28 Jun 2026 10:34:00 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E6=B7=B1=E5=BA=A6=E5=81=A5?= =?UTF-8?q?=E5=BA=B7=E6=A3=80=E6=9F=A5=20-=20=E6=B8=85=E7=90=86=E6=AD=BB?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=92=8C=E4=BF=AE=E5=A4=8D=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除未使用的API模块: projects.ts, generation.ts, subscription.ts, projectTitles.ts - 删除未使用的业务组件: InviteMemberModal.tsx, MemberList.tsx, PermissionMatrix.tsx - 删除未引用的布局组件: Sidebar.tsx - 删除未引用的状态管理: uiStore.ts - 修复 business.css 中残留的git合并冲突标记 - 移除 business.css 中重复的注释行 所有删除的文件均经过引用检查,确认无任何页面/组件/hook引用 --- apps/web/src/api/generation.ts | 77 ----------- apps/web/src/api/projectTitles.ts | 28 ---- apps/web/src/api/projects.ts | 27 ---- apps/web/src/api/subscription.ts | 64 --------- .../components/business/InviteMemberModal.tsx | 80 ----------- .../src/components/business/MemberList.tsx | 129 ------------------ .../components/business/PermissionMatrix.tsx | 100 -------------- apps/web/src/components/business/business.css | 10 -- apps/web/src/components/layout/Sidebar.tsx | 107 --------------- apps/web/src/store/uiStore.ts | 32 ----- 10 files changed, 654 deletions(-) delete mode 100644 apps/web/src/api/generation.ts delete mode 100644 apps/web/src/api/projectTitles.ts delete mode 100644 apps/web/src/api/projects.ts delete mode 100644 apps/web/src/api/subscription.ts delete mode 100644 apps/web/src/components/business/InviteMemberModal.tsx delete mode 100644 apps/web/src/components/business/MemberList.tsx delete mode 100644 apps/web/src/components/business/PermissionMatrix.tsx delete mode 100644 apps/web/src/components/layout/Sidebar.tsx delete mode 100644 apps/web/src/store/uiStore.ts diff --git a/apps/web/src/api/generation.ts b/apps/web/src/api/generation.ts deleted file mode 100644 index 536166dda..000000000 --- a/apps/web/src/api/generation.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** - * 视频生成 API - */ -import apiClient from "./client"; -import type { EditingMode } from "./editPlans"; - -export interface GenerationTaskItem { - id: string; - project_id: string; - asset_library_id: string; - strategy_id?: string | null; - voice_library_id?: string | null; - edit_plan_id?: string | null; - editing_mode?: EditingMode; - status: "pending" | "running" | "completed" | "failed" | "cancelled"; - progress: number; - result_count: number; - error_message?: string | null; - created_at?: string; - updated_at?: string; -} - -export interface GeneratedVideoItem { - id: string; - project_id: string; - generation_task_id: string; - name: string; - file_url: string; - file_size: number; - duration: number; - thumbnail_url?: string | null; - width: number; - height: number; - fps: number; - status?: string; - review_status?: "pending_review" | "approved" | "rejected"; - generation_params?: Record; - editing_mode?: EditingMode; -} - -export const createGenerationTask = async (data: { - project_id: string; - asset_library_id: string; - strategy_id?: string; - voice_library_id?: string; - edit_plan_id?: string; - editing_mode?: EditingMode; - created_by_user_id?: string; -}): Promise => { - const response = await apiClient.post("/generation/tasks", data); - return response.data; -}; - -export const getGenerationTask = async (taskId: string): Promise => { - const response = await apiClient.get(`/generation/tasks/${taskId}`); - return response.data; -}; - -export const getGenerationResults = async (taskId: string): Promise => { - const response = await apiClient.get(`/generation/tasks/${taskId}/results`); - return response.data.items; -}; - -export const getGeneratedVideos = async (projectId: string): Promise => { - const response = await apiClient.get("/generated-videos", { params: { project_id: projectId } }); - return response.data.items; -}; - -export const updateGeneratedVideoReviewStatus = async (videoId: string, reviewStatus: "pending_review" | "approved" | "rejected"): Promise => { - const response = await apiClient.patch(`/generated-videos/${videoId}/review`, { review_status: reviewStatus }); - return response.data; -}; - -export const getGeneratedVideoDownloadUrl = async (videoId: string): Promise => { - const response = await apiClient.get(`/generated-videos/${videoId}/download-url`); - return response.data.download_url; -}; diff --git a/apps/web/src/api/projectTitles.ts b/apps/web/src/api/projectTitles.ts deleted file mode 100644 index 753605a63..000000000 --- a/apps/web/src/api/projectTitles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import apiClient from './client'; - -export interface ProjectTitleItem { - id: string; - project_id: string; - text: string; - category: 'default' | 'marketing' | 'tutorial' | 'story' | 'promo'; - favorite: boolean; - usage_count: number; - is_active: boolean; - created_at: string; - updated_at: string; -} - -export const getProjectTitles = async (projectId: string, activeOnly = false): Promise => { - const response = await apiClient.get(`/projects/${projectId}/titles`, { params: { active_only: activeOnly } }); - return response.data.items; -}; - -export const createProjectTitle = async (projectId: string, data: { text: string; category?: ProjectTitleItem['category']; favorite?: boolean }): Promise => { - const response = await apiClient.post(`/projects/${projectId}/titles`, data); - return response.data; -}; - -export const updateProjectTitle = async (titleId: string, data: { text?: string; category?: ProjectTitleItem['category']; favorite?: boolean; is_active?: boolean }): Promise => { - const response = await apiClient.patch(`/project-titles/${titleId}`, data); - return response.data; -}; diff --git a/apps/web/src/api/projects.ts b/apps/web/src/api/projects.ts deleted file mode 100644 index ea1195de2..000000000 --- a/apps/web/src/api/projects.ts +++ /dev/null @@ -1,27 +0,0 @@ -import apiClient from './client'; - -export interface ProjectItem { - id: string; - name: string; - description: string; -} - -export interface CreateProjectRequest { - name: string; - description?: string; -} - -export const getProject = async (projectId: string): Promise => { - const response = await apiClient.get(`/projects/${projectId}`); - return response.data; -}; - -export const getProjects = async (): Promise => { - const response = await apiClient.get('/projects'); - return response.data.items; -}; - -export const createProject = async (data: CreateProjectRequest): Promise => { - const response = await apiClient.post('/projects', data); - return response.data; -}; diff --git a/apps/web/src/api/subscription.ts b/apps/web/src/api/subscription.ts deleted file mode 100644 index 8bab2c8ca..000000000 --- a/apps/web/src/api/subscription.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 订阅相关 API - */ -import apiClient from './client'; - -// 类型定义 -export interface SubscriptionPlan { - name: 'free' | 'pro' | 'enterprise'; - display_name: string; - price: number; - currency: string; - max_projects: number; - max_storage_gb: number; - features: string[]; -} - -export interface QuotaStatus { - projects: { - used: number; - limit: number; - status: 'normal' | 'warning' | 'critical' | 'exceeded'; - }; - storage: { - used_gb: number; - limit_gb: number; - status: 'normal' | 'warning' | 'critical' | 'exceeded'; - }; -} - -// 获取所有订阅计划 -export const getPlans = async (): Promise => { - const response = await apiClient.get('/subscriptions/plans'); - return response.data; -}; - -// 获取当前订阅 -export const getCurrentSubscription = async ( - ): Promise => { - const response = await apiClient.get('/subscription'); - return response.data; -}; - -// 升级订阅 -export const upgradeSubscription = async ( - plan: 'pro' | 'enterprise' -): Promise<{ message: string }> => { - const response = await apiClient.post('/subscription/upgrade', { - plan, - }); - return response.data; -}; - -// 取消订阅 -export const cancelSubscription = async ( - ): Promise<{ message: string }> => { - const response = await apiClient.post('/subscription/cancel'); - return response.data; -}; - -// 获取配额状态 -export const getQuotaStatus = async (): Promise => { - const response = await apiClient.get('/quota'); - return response.data; -}; diff --git a/apps/web/src/components/business/InviteMemberModal.tsx b/apps/web/src/components/business/InviteMemberModal.tsx deleted file mode 100644 index 0b8d98a47..000000000 --- a/apps/web/src/components/business/InviteMemberModal.tsx +++ /dev/null @@ -1,80 +0,0 @@ -/** - * 邀请成员弹窗 - */ -import React from 'react'; -import { Modal, Form, Input, Select, message } from 'antd'; -import { useInviteMember } from '@/hooks/useWorkspace'; - -interface InviteMemberModalProps { - workspaceId: string; - open: boolean; - onClose: () => void; -} - -const InviteMemberModal: React.FC = ({ - workspaceId, - open, - onClose, -}) => { - const [form] = Form.useForm(); - const inviteMutation = useInviteMember(workspaceId); - - const handleOk = async () => { - try { - const values = await form.validateFields(); - await inviteMutation.mutateAsync(values); - message.success('邀请已发送!'); - form.resetFields(); - onClose(); - } catch (error) { - // 验证失败或请求失败 - } - }; - - const handleCancel = () => { - form.resetFields(); - onClose(); - }; - - return ( - -
- - - - - - - updateRoleMutation.mutate({ memberId: record.id, role: newRole }) - } - options={[ - { value: 'admin', label: '管理员' }, - { value: 'member', label: '成员' }, - { value: 'viewer', label: '访客' }, - ]} - /> - ); - }, - }, - { - title: '加入时间', - dataIndex: 'joined_at', - key: 'joined_at', - render: (date: string) => new Date(date).toLocaleDateString(), - }, - { - title: '操作', - key: 'action', - render: (_: any, record: any) => { - if (record.role === 'owner') { - return -; - } - return ( - - removeMutation.mutate(record.id)} - okText="确定" - cancelText="取消" - > - - - - ); - }, - }, - ]; - - return ( - - ); -}; - -export default MemberList; diff --git a/apps/web/src/components/business/PermissionMatrix.tsx b/apps/web/src/components/business/PermissionMatrix.tsx deleted file mode 100644 index 97cad565f..000000000 --- a/apps/web/src/components/business/PermissionMatrix.tsx +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 权限矩阵展示组件 - V21 UI - */ -import React from 'react'; -import { Card, Table } from 'antd'; -import { CheckOutlined, CloseOutlined } from '@ant-design/icons'; -import './business.css'; - -const PermissionMatrix: React.FC = () => { - const permissions = [ - { action: '查看工作空间', owner: true, admin: true, member: true, viewer: true }, - { action: '创建项目', owner: true, admin: true, member: true, viewer: false }, - { action: '编辑项目', owner: true, admin: true, member: true, viewer: false }, - { action: '删除项目', owner: true, admin: true, member: false, viewer: false }, - { action: '邀请成员', owner: true, admin: true, member: false, viewer: false }, - { action: '移除成员', owner: true, admin: true, member: false, viewer: false }, - { action: '修改成员角色', owner: true, admin: true, member: false, viewer: false }, - { action: '升级订阅', owner: true, admin: false, member: false, viewer: false }, - { action: '删除工作空间', owner: true, admin: false, member: false, viewer: false }, - ]; - - const columns = [ - { - title: '操作', - dataIndex: 'action', - key: 'action', - fixed: 'left' as const, - width: 160, - render: (text: string) => {text}, - }, - { - title: '拥有者', - dataIndex: 'owner', - key: 'owner', - align: 'center' as const, - width: 100, - render: (value: boolean) => - value ? ( - - ) : ( - - ), - }, - { - title: '管理员', - dataIndex: 'admin', - key: 'admin', - align: 'center' as const, - width: 100, - render: (value: boolean) => - value ? ( - - ) : ( - - ), - }, - { - title: '成员', - dataIndex: 'member', - key: 'member', - align: 'center' as const, - width: 100, - render: (value: boolean) => - value ? ( - - ) : ( - - ), - }, - { - title: '访客', - dataIndex: 'viewer', - key: 'viewer', - align: 'center' as const, - width: 100, - render: (value: boolean) => - value ? ( - - ) : ( - - ), - }, - ]; - - return ( - -
-
- - - ); -}; - -export default PermissionMatrix; diff --git a/apps/web/src/components/business/business.css b/apps/web/src/components/business/business.css index f29d55f8d..fff1897e2 100644 --- a/apps/web/src/components/business/business.css +++ b/apps/web/src/components/business/business.css @@ -89,7 +89,6 @@ overflow: hidden; } -<<<<<<< HEAD /* 表格包装器 */ .xx-table-wrapper { border-radius: 16px; @@ -223,7 +222,6 @@ box-shadow: 0 8px 24px rgba(79,70,229,0.1); } -<<<<<<< HEAD /* ==================== 进度条 ==================== */ .xx-progress { margin-top: 12px; @@ -231,7 +229,6 @@ /* ==================== Ant Design 覆盖样式 ==================== */ /* Table overrides */ -/* ==================== Ant Design 覆盖样式 ==================== */ .ant-table-wrapper .ant-table-thead > tr > th { background: #f8fafc !important; font-weight: 700 !important; @@ -249,7 +246,6 @@ background: #fafbfc !important; } -<<<<<<< HEAD /* Card overrides */ .ant-card { border-radius: 22px !important; @@ -272,7 +268,6 @@ padding: 20px 24px !important; } -<<<<<<< HEAD /* Modal overrides */ .ant-modal-content { border-radius: 22px !important; @@ -298,7 +293,6 @@ padding: 16px 24px !important; } -<<<<<<< HEAD /* Button overrides */ .ant-btn-primary { background: linear-gradient(135deg, #6366f1, #4f46e5) !important; @@ -316,7 +310,6 @@ transform: translateY(-1px); } -<<<<<<< HEAD /* Tag overrides */ .ant-tag { border-radius: 10px !important; @@ -324,7 +317,6 @@ font-weight: 500 !important; } -<<<<<<< HEAD /* Select overrides */ .ant-select-selector { border-radius: 14px !important; @@ -340,7 +332,6 @@ box-shadow: 0 0 0 3px rgba(79,70,229,0.1) !important; } -<<<<<<< HEAD /* Input overrides */ .ant-input { border-radius: 14px !important; @@ -357,7 +348,6 @@ box-shadow: 0 0 0 3px rgba(79,70,229,0.1) !important; } -<<<<<<< HEAD /* Progress overrides */ .ant-progress-inner { background: #f1f5f9 !important; diff --git a/apps/web/src/components/layout/Sidebar.tsx b/apps/web/src/components/layout/Sidebar.tsx deleted file mode 100644 index 88fd13ca8..000000000 --- a/apps/web/src/components/layout/Sidebar.tsx +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 侧边栏导航 - */ -import React from 'react'; -import { Layout, Menu } from 'antd'; -import { - HomeOutlined, - AppstoreOutlined, - TeamOutlined, - CrownOutlined, - UserOutlined, - DashboardOutlined, -} from '@ant-design/icons'; -import { useNavigate, useLocation } from 'react-router-dom'; -import type { MenuProps } from 'antd'; - -const { Sider } = Layout; - -interface SidebarProps { - collapsed: boolean; -} - -const Sidebar: React.FC = ({ collapsed }) => { - const navigate = useNavigate(); - const location = useLocation(); - - const menuItems: MenuProps['items'] = [ - { - key: '/', - icon: , - label: '首页', - onClick: () => navigate('/'), - }, - { - key: '/projects', - icon: , - label: '项目', - disabled: true, - }, - { - key: '/members', - icon: , - label: '成员管理', - disabled: true, - }, - { - key: '/subscription', - icon: , - label: '订阅管理', - onClick: () => navigate('/subscription'), - }, - { - key: '/admin', - icon: , - label: 'Admin(暂未开放)', - disabled: true, - }, - { - key: '/profile', - icon: , - label: '个人中心', - onClick: () => navigate('/profile'), - }, - ]; - - // 根据当前路径选中菜单项 - const selectedKey = '/' + location.pathname.split('/')[1]; - - return ( - -
- {collapsed ? '🦐' : '小虾 SaaS'} -
- - - ); -}; - -export default Sidebar; diff --git a/apps/web/src/store/uiStore.ts b/apps/web/src/store/uiStore.ts deleted file mode 100644 index b02933d13..000000000 --- a/apps/web/src/store/uiStore.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * UI 状态管理 - * 管理全局 UI 状态(侧边栏、加载状态等) - */ -import { create } from 'zustand'; - -interface UIState { - sidebarCollapsed: boolean; - loading: boolean; - - // Actions - toggleSidebar: () => void; - setSidebarCollapsed: (collapsed: boolean) => void; - setLoading: (loading: boolean) => void; -} - -export const useUIStore = create((set) => ({ - sidebarCollapsed: false, - loading: false, - - toggleSidebar: () => { - set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })); - }, - - setSidebarCollapsed: (collapsed) => { - set({ sidebarCollapsed: collapsed }); - }, - - setLoading: (loading) => { - set({ loading }); - }, -}));