This commit is contained in:
yinsx
2026-01-15 11:03:06 +08:00
parent 943bf4bbd4
commit 53a044f19e
3 changed files with 71 additions and 64 deletions

View File

@ -4,7 +4,7 @@
"glb2": 3 "glb2": 3
}, },
"image_operation": { "image_operation": {
"compress": 8, "compress": 9,
"resize": 1 "resize": 1
} }
} }

View File

@ -15,75 +15,77 @@ const OPERATIONS = [
const run = async () => { const run = async () => {
try { try {
while (true) { // 强制清理并重新初始化键盘
// 强制清理并重新初始化键盘 stopKeypress();
stopKeypress(); await new Promise(resolve => setTimeout(resolve, 100));
await new Promise(resolve => setTimeout(resolve, 100));
const steps = getSteps(); const steps = getSteps();
const ui = createStepUI({ title, getSteps: () => steps }); const ui = createStepUI({
const result = await ui.runInteractive(); title,
getSteps: () => steps,
if (!result) { validate: (results) => {
stopKeypress(); // 验证是否有文件选择且至少有一个操作未跳过
return "back"; const files = results[0] || [];
const hasOperation = OPERATIONS.some(op => results[op.stepIndex] !== "skip");
return files.length > 0 && hasOperation;
} }
});
const files = result.results[0] || []; const result = await ui.runInteractive();
const selectedOp = OPERATIONS.find(op => result.results[op.stepIndex] !== "skip");
stopKeypress(); if (!result) {
// 如果没有选择文件或所有操作都跳过,重新开始
if (!selectedOp || !files.length) {
continue;
}
// 有效的选择,继续处理
const params = buildProcessParams(selectedOp.id, result.results[selectedOp.stepIndex]);
ui.showSummary([
"源文件: " + files.join(", "),
"操作: " + selectedOp.name,
getParamLabel(selectedOp.id, params)
]);
const total = files.length;
let success = 0;
const failed = [];
console.log(color.cyan(`开始处理 ${total} 个文件...\\n`));
for (let i = 0; i < files.length; i++) {
const file = files[i];
const progress = `[${i + 1}/${total}]`;
console.log(color.dim(`${progress} 处理中: ${file}`));
try {
const outputs = await processImage(file, selectedOp.id, params);
success++;
record("image_operation", selectedOp.id);
const outputNames = Array.isArray(outputs)
? outputs.map(o => path.relative(process.cwd(), o)).join(", ")
: path.relative(process.cwd(), outputs);
console.log(color.green(`${progress}${file}${outputNames}`));
} catch (err) {
failed.push({ file, reason: err?.message || String(err) });
console.log(color.red(`${progress} ✖ 失败: ${file}`));
console.log(color.dim(" " + String(err?.message || err)));
}
}
console.log("\\n" + color.bgGreen(color.black(" 处理完成 ")));
console.log(color.green(`成功: ${success}`));
if (failed.length) console.log(color.yellow(`失败: ${failed.length}`));
console.log(color.cyan(`输出目录: ${selectedOp.folder}/`));
await waitForKey(color.dim("按 Esc 返回"), key => key?.name === "escape" || (key?.ctrl && key?.name === "c"));
stopKeypress(); stopKeypress();
return "back"; return "back";
} }
const files = result.results[0] || [];
const selectedOp = OPERATIONS.find(op => result.results[op.stepIndex] !== "skip");
stopKeypress();
const params = buildProcessParams(selectedOp.id, result.results[selectedOp.stepIndex]);
ui.showSummary([
"源文件: " + files.join(", "),
"操作: " + selectedOp.name,
getParamLabel(selectedOp.id, params)
]);
const total = files.length;
let success = 0;
const failed = [];
console.log(color.cyan(`开始处理 ${total} 个文件...\\n`));
for (let i = 0; i < files.length; i++) {
const file = files[i];
const progress = `[${i + 1}/${total}]`;
console.log(color.dim(`${progress} 处理中: ${file}`));
try {
const outputs = await processImage(file, selectedOp.id, params);
success++;
record("image_operation", selectedOp.id);
const outputNames = Array.isArray(outputs)
? outputs.map(o => path.relative(process.cwd(), o)).join(", ")
: path.relative(process.cwd(), outputs);
console.log(color.green(`${progress}${file}${outputNames}`));
} catch (err) {
failed.push({ file, reason: err?.message || String(err) });
console.log(color.red(`${progress} ✖ 失败: ${file}`));
console.log(color.dim(" " + String(err?.message || err)));
}
}
console.log("\\n" + color.bgGreen(color.black(" 处理完成 ")));
console.log(color.green(`成功: ${success}`));
if (failed.length) console.log(color.yellow(`失败: ${failed.length}`));
console.log(color.cyan(`输出目录: ${selectedOp.folder}/`));
await waitForKey(color.dim("按 Esc 返回"), key => key?.name === "escape" || (key?.ctrl && key?.name === "c"));
stopKeypress();
return "back";
} catch (err) { } catch (err) {
stopKeypress(); stopKeypress();
console.error(color.red("发生错误:"), err); console.error(color.red("发生错误:"), err);

View File

@ -3,7 +3,7 @@ import { initKeypress, onKey, stopKeypress } from "../keyboard.js";
import { clearScreen } from "./terminal.js"; import { clearScreen } from "./terminal.js";
export function createStepUI(options) { export function createStepUI(options) {
const { title, getSteps, onStepChange } = options; const { title, getSteps, onStepChange, validate } = options;
let steps = []; let steps = [];
let results = []; let results = [];
@ -171,6 +171,11 @@ export function createStepUI(options) {
} }
break; break;
case "tab": case "tab":
// 如果提供了验证函数,先验证
if (validate && !validate(results)) {
// 验证失败,忽略此次提交
break;
}
resolved = true; resolved = true;
stopKeypress(); stopKeypress();
setImmediate(() => resolve({ steps, results })); setImmediate(() => resolve({ steps, results }));