refactor: 清理IndexedDB相关代码,统一使用后端ZIP存储
- 移除前端废弃的loadZipFile/saveZipFile函数 - ProjectDetail使用scanStoredZipFile替代loadZipFile - RecycleBin移除手动删除ZIP文件逻辑 - 后端permanently_delete_project自动清理ZIP文件
This commit is contained in:
parent
f640bfbaba
commit
c54212a8c9
|
|
@ -294,6 +294,14 @@ async def permanently_delete_project(
|
|||
if project.owner_id != current_user.id:
|
||||
raise HTTPException(status_code=403, detail="无权永久删除此项目")
|
||||
|
||||
# 如果是ZIP类型项目,删除关联的ZIP文件和元数据
|
||||
if project.source_type == "zip":
|
||||
try:
|
||||
await delete_project_zip(id)
|
||||
print(f"[Project] 已删除项目 {id} 的ZIP文件")
|
||||
except Exception as e:
|
||||
print(f"[Warning] 删除ZIP文件失败: {e}")
|
||||
|
||||
await db.delete(project)
|
||||
await db.commit()
|
||||
return {"message": "项目已永久删除"}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ import {
|
|||
GitBranch
|
||||
} from "lucide-react";
|
||||
import { api } from "@/shared/config/database";
|
||||
import { runRepositoryAudit, scanZipFile } from "@/features/projects/services";
|
||||
import { runRepositoryAudit, scanStoredZipFile } from "@/features/projects/services";
|
||||
import type { Project, AuditTask, CreateProjectForm } from "@/shared/types";
|
||||
import { loadZipFile } from "@/shared/utils/zipStorage";
|
||||
import { hasZipFile } from "@/shared/utils/zipStorage";
|
||||
import { isRepositoryProject, getSourceTypeLabel } from "@/shared/utils/projectUtils";
|
||||
import { toast } from "sonner";
|
||||
import CreateTaskDialog from "@/components/audit/CreateTaskDialog";
|
||||
|
|
@ -173,18 +173,17 @@ export default function ProjectDetail() {
|
|||
setScanning(false);
|
||||
}
|
||||
} else {
|
||||
// 没有仓库地址,尝试从IndexedDB加载保存的ZIP文件
|
||||
// 没有仓库地址,尝试使用后端存储的ZIP文件
|
||||
try {
|
||||
setScanning(true);
|
||||
const file = await loadZipFile(id);
|
||||
const hasFile = await hasZipFile(id);
|
||||
|
||||
if (file) {
|
||||
console.log('找到保存的ZIP文件,开始启动审计...');
|
||||
if (hasFile) {
|
||||
console.log('找到后端存储的ZIP文件,开始启动审计...');
|
||||
try {
|
||||
// 启动ZIP文件审计
|
||||
const taskId = await scanZipFile({
|
||||
// 使用后端存储的ZIP文件启动审计
|
||||
const taskId = await scanStoredZipFile({
|
||||
projectId: id,
|
||||
zipFile: file,
|
||||
excludePatterns: ['node_modules/**', '.git/**', 'dist/**', 'build/**'],
|
||||
createdBy: 'local-user'
|
||||
});
|
||||
|
|
@ -206,7 +205,6 @@ export default function ProjectDetail() {
|
|||
} else {
|
||||
setScanning(false);
|
||||
toast.warning('此项目未配置仓库地址,也未上传ZIP文件。请先在项目设置中配置仓库地址,或通过"新建任务"上传ZIP文件。');
|
||||
// 不自动打开对话框,让用户自己选择
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('启动审计失败:', error);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ import {
|
|||
import { api } from "@/shared/config/database";
|
||||
import type { Project } from "@/shared/types";
|
||||
import { toast } from "sonner";
|
||||
import { deleteZipFile } from "@/shared/utils/zipStorage";
|
||||
import { isRepositoryProject, getSourceTypeBadge } from "@/shared/utils/projectUtils";
|
||||
|
||||
export default function RecycleBin() {
|
||||
|
|
@ -75,16 +74,9 @@ export default function RecycleBin() {
|
|||
if (!selectedProject) return;
|
||||
|
||||
try {
|
||||
// 删除项目数据
|
||||
// 删除项目数据(后端会同时删除关联的ZIP文件)
|
||||
await api.permanentlyDeleteProject(selectedProject.id);
|
||||
|
||||
// 删除保存的ZIP文件(如果有)
|
||||
try {
|
||||
await deleteZipFile(selectedProject.id);
|
||||
} catch (error) {
|
||||
console.error('删除ZIP文件失败:', error);
|
||||
}
|
||||
|
||||
toast.success(`项目 "${selectedProject.name}" 已永久删除`);
|
||||
setShowPermanentDeleteDialog(false);
|
||||
setSelectedProject(null);
|
||||
|
|
|
|||
|
|
@ -91,29 +91,4 @@ export function formatFileSize(bytes: number): string {
|
|||
return `${bytes} B`;
|
||||
}
|
||||
|
||||
// ============ 兼容旧API(已废弃,保留以避免编译错误) ============
|
||||
|
||||
/**
|
||||
* @deprecated 使用 uploadZipFile 代替
|
||||
*/
|
||||
export async function saveZipFile(projectId: string, file: File): Promise<void> {
|
||||
const result = await uploadZipFile(projectId, file);
|
||||
if (!result.success) {
|
||||
throw new Error(result.message || '保存ZIP文件失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 使用 getZipFileInfo 代替
|
||||
*/
|
||||
export async function loadZipFile(projectId: string): Promise<File | null> {
|
||||
// 后端不再返回文件内容,只返回元数据
|
||||
// 如果需要文件,应该在创建任务时直接使用后端存储的文件
|
||||
const info = await getZipFileInfo(projectId);
|
||||
if (info.has_file && info.original_filename) {
|
||||
// 返回一个虚拟的File对象,仅包含元数据
|
||||
const blob = new Blob([], { type: 'application/zip' });
|
||||
return new File([blob], info.original_filename, { type: 'application/zip' });
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue