feat: 拾取策略矩阵——桌面/视觉/窗口能力按类型显示拾取按钮(桌面拾取/屏幕框选/窗口列表)

This commit is contained in:
yu 2026-10-29 15:42:21 +08:00
parent b40fcbdd35
commit 8870050aaa

View File

@ -443,6 +443,8 @@ function FieldControl({
}) {
const raw = node.values[field.key] ?? field.defaultValue;
const [picking, setPicking] = useState(false);
const isVisionTarget = /^(OcrOffline_|CV_)/.test(node.componentId);
const isWindowTarget = /^(Window_|System_ConnectRemoteDesktop)/.test(node.componentId);
const insertVariable = (expression: string) => {
const current = textOf(raw).trim();
@ -489,6 +491,40 @@ function FieldControl({
setPicking(false);
}
};
const pickRegionToField = async () => {
setPicking(true);
try {
const region = await window.rpa.desktop.pickRegion();
onChange(field.key, region.imagePath);
onToast("已框选并截图:" + region.width + "×" + region.height);
} catch (error) {
onToast(error instanceof Error ? error.message : String(error), "error");
} finally {
setPicking(false);
}
};
const pickWindowToField = async () => {
setPicking(true);
try {
const list = await window.rpa.desktop.pickWindowList();
if (!list.length) {
onToast("未找到可见窗口", "error");
return;
}
const numbered = list.map((w: { title: string }, i: number) => (i + 1) + ". " + w.title).join("\n");
const choice = prompt("选择窗口(输入编号):\n" + numbered);
const idx = Number(choice) - 1;
if (Number.isInteger(idx) && list[idx]) {
onChange(field.key, list[idx].title);
onToast("已选择窗口:" + list[idx].title);
}
} catch (error) {
onToast(error instanceof Error ? error.message : String(error), "error");
} finally {
setPicking(false);
}
};
if (field.widget === "boolean") {
return (
@ -549,6 +585,16 @@ function FieldControl({
<VarMenu variables={variables} onPick={insertVariable} />
<button type="button" className="mini-btn" onClick={() => void pickPath(field.widget === "folder")} title="浏览">
<FolderOpen className="icon" style={{ width: 13, height: 13 }} />
{isVisionTarget && /image/i.test(field.key) && (
<button type="button" className="mini-btn" disabled={picking} onClick={() => void pickRegionToField()} title="屏幕框选区域并截图">
{picking ? "框选中" : "屏幕框选"}
</button>
)}
{isWindowTarget && /title/i.test(field.key) && (
<button type="button" className="mini-btn" disabled={picking} onClick={() => void pickWindowToField()} title="选择窗口">
{picking ? "选择中" : "选窗口"}
</button>
)}
</button>
</div>
) : field.widget === "element" ? (