From fbf8079cca74c31c4c2eacc844204850424eca26 Mon Sep 17 00:00:00 2001 From: Yukino_fox Date: Sun, 5 Jul 2026 10:47:39 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=96=B0=E5=A2=9E=E6=B8=85=E7=90=86?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=B9=B6=E4=BC=98=E5=8C=96=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增clean脚本用于清理项目构建产物和缓存 2. 更新.gitignore忽略eslint缓存和src-tauri的target目录 3. 在package.json中添加clean命令 4. 格式化StudentManager组件的回调函数代码 --- .gitignore | 4 + package.json | 1 + scripts/clean.cjs | 144 ++++++++++++++++++++++++++++++ src/components/StudentManager.tsx | 94 ++++++++++--------- 4 files changed, 202 insertions(+), 41 deletions(-) create mode 100644 scripts/clean.cjs diff --git a/.gitignore b/.gitignore index fef7ef4..f33bb77 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ node_modules/ dist/ build/ target/ +src-tauri/target/ # Logs *.log @@ -24,6 +25,9 @@ yarn-error.log* *.swo *.tmp +# Lint cache +.eslintcache + # Python __pycache__/ *.pyc diff --git a/package.json b/package.json index ba3b585..d9f6c78 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "tauri:dev": "node scripts/tauri-dev.cjs", "tauri:build": "tauri build", "ios:sim": "node scripts/ios-sim.js", + "clean": "node scripts/clean.cjs", "format": "prettier --write .", "lint": "eslint --cache .", "lint:fix": "eslint --cache . --fix", diff --git a/scripts/clean.cjs b/scripts/clean.cjs new file mode 100644 index 0000000..c9e6b9e --- /dev/null +++ b/scripts/clean.cjs @@ -0,0 +1,144 @@ +/** + * Clean script - Similar to `flutter clean` + * Cleans all build artifacts and caches for the Tauri project + */ + +const fs = require("fs") +const path = require("path") + +// ANSI color codes for console output +const colors = { + red: "\x1b[31m", + green: "\x1b[32m", + yellow: "\x1b[33m", + blue: "\x1b[34m", + reset: "\x1b[0m", +} + +/** + * Delete a directory recursively + * @param {string} dirPath - Path to directory to delete + */ +function deleteDirectory(dirPath) { + const fullPath = path.resolve(dirPath) + + if (!fs.existsSync(fullPath)) { + console.log(`${colors.yellow}⊘${colors.reset} Not found: ${dirPath}`) + return false + } + + try { + fs.rmSync(fullPath, { recursive: true, force: true }) + console.log(`${colors.green}✓${colors.reset} Deleted: ${dirPath}`) + return true + } catch (error) { + console.error(`${colors.red}✗${colors.reset} Failed to delete ${dirPath}: ${error.message}`) + return false + } +} + +/** + * Delete a file + * @param {string} filePath - Path to file to delete + */ +function deleteFile(filePath) { + const fullPath = path.resolve(filePath) + + if (!fs.existsSync(fullPath)) { + console.log(`${colors.yellow}⊘${colors.reset} Not found: ${filePath}`) + return false + } + + try { + fs.unlinkSync(fullPath) + console.log(`${colors.green}✓${colors.reset} Deleted: ${filePath}`) + return true + } catch (error) { + console.error(`${colors.red}✗${colors.reset} Failed to delete ${filePath}: ${error.message}`) + return false + } +} + +/** + * Main clean function + */ +function clean() { + console.log(`\n${colors.blue}════════════════════════════════════════${colors.reset}`) + console.log(`${colors.blue} SecScore Clean - Removing build artifacts${colors.reset}`) + console.log(`${colors.blue}════════════════════════════════════════${colors.reset}\n`) + + // Get project root directory + const rootDir = path.resolve(__dirname, "..") + + // Directories to clean + const dirsToClean = [ + // Node.js / Frontend + "node_modules", + "dist", + ".vite", + + // Rust / Tauri + "src-tauri/target", + + // Test coverage + "coverage", + + // Cache directories + ".eslintcache", + "node_modules/.cache", + ] + + // Files to clean + const filesToClean = [ + // Lock files + "pnpm-lock.yaml", + ] + + let deletedCount = 0 + let failedCount = 0 + + // Clean directories + console.log(`${colors.blue}Cleaning directories:${colors.reset}`) + for (const dir of dirsToClean) { + const dirPath = path.join(rootDir, dir) + if (deleteDirectory(dirPath)) { + deletedCount++ + } else if (fs.existsSync(dirPath)) { + failedCount++ + } + } + + // Clean files + if (filesToClean.length > 0) { + console.log(`\n${colors.blue}Cleaning files:${colors.reset}`) + for (const file of filesToClean) { + const filePath = path.join(rootDir, file) + if (deleteFile(filePath)) { + deletedCount++ + } else if (fs.existsSync(filePath)) { + failedCount++ + } + } + } + + // Summary + console.log(`\n${colors.blue}════════════════════════════════════════${colors.reset}`) + console.log(`${colors.green}✓ Deleted: ${deletedCount}${colors.reset}`) + if (failedCount > 0) { + console.log(`${colors.red}✗ Failed: ${failedCount}${colors.reset}`) + } + console.log(`${colors.blue}════════════════════════════════════════${colors.reset}`) + + if (failedCount > 0) { + console.log( + `\n${colors.yellow}⚠ Some items could not be deleted. Try closing any running processes and try again.${colors.reset}\n` + ) + process.exit(1) + } + + console.log(`\n${colors.green}✓ Clean completed successfully!${colors.reset}`) + console.log(`${colors.yellow}ℹ Run 'pnpm install' to reinstall dependencies.${colors.reset}\n`) +} + +// Run clean +clean() diff --git a/src/components/StudentManager.tsx b/src/components/StudentManager.tsx index 4da31ab..a2b3ad6 100644 --- a/src/components/StudentManager.tsx +++ b/src/components/StudentManager.tsx @@ -289,50 +289,62 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => { } } - const handleDelete = useCallback(async (id: number) => { - if (!(window as any).api) return - if (!canEdit) { - messageApi.error(t("common.readOnly")) - return - } - const res = await (window as any).api.deleteStudent(id) - if (res.success) { - messageApi.success(t("students.deleteSuccess")) - fetchStudents() - emitDataUpdated("students") - } else { - messageApi.error(res.message || t("students.deleteFailed")) - } - }, [canEdit, messageApi, t, fetchStudents]) + const handleDelete = useCallback( + async (id: number) => { + if (!(window as any).api) return + if (!canEdit) { + messageApi.error(t("common.readOnly")) + return + } + const res = await (window as any).api.deleteStudent(id) + if (res.success) { + messageApi.success(t("students.deleteSuccess")) + fetchStudents() + emitDataUpdated("students") + } else { + messageApi.error(res.message || t("students.deleteFailed")) + } + }, + [canEdit, messageApi, t, fetchStudents] + ) - const handleOpenTagEditor = useCallback((student: student) => { - if (!canEdit) { - messageApi.error(t("common.readOnly")) - return - } - setEditingStudent(student) - setTagEditVisible(true) - }, [canEdit, messageApi, t]) + const handleOpenTagEditor = useCallback( + (student: student) => { + if (!canEdit) { + messageApi.error(t("common.readOnly")) + return + } + setEditingStudent(student) + setTagEditVisible(true) + }, + [canEdit, messageApi, t] + ) - const handleOpenAvatarEditor = useCallback((student: student) => { - if (!canEdit) { - messageApi.error(t("common.readOnly")) - return - } - setAvatarStudent(student) - setAvatarValue(student.avatarUrl || null) - setAvatarVisible(true) - }, [canEdit, messageApi, t]) + const handleOpenAvatarEditor = useCallback( + (student: student) => { + if (!canEdit) { + messageApi.error(t("common.readOnly")) + return + } + setAvatarStudent(student) + setAvatarValue(student.avatarUrl || null) + setAvatarVisible(true) + }, + [canEdit, messageApi, t] + ) - const handleOpenGroupEditor = useCallback((student: student) => { - if (!canEdit) { - messageApi.error(t("common.readOnly")) - return - } - setGroupEditStudent(student) - groupForm.setFieldsValue({ group_name: student.group_name || "" }) - setGroupEditVisible(true) - }, [canEdit, messageApi, t, groupForm]) + const handleOpenGroupEditor = useCallback( + (student: student) => { + if (!canEdit) { + messageApi.error(t("common.readOnly")) + return + } + setGroupEditStudent(student) + groupForm.setFieldsValue({ group_name: student.group_name || "" }) + setGroupEditVisible(true) + }, + [canEdit, messageApi, t, groupForm] + ) const handleSaveGroup = async () => { if (!(window as any).api || !groupEditStudent) return