Merge branch 'main' of http://43.140.215.244:7040/wangyukun/PRA-only-demo
这个提交包含在:
当前提交
b59d906161
3 个文件已更改
+30
-3
没有与搜索条件相匹配的文件
@@ -111,9 +111,29 @@ register("StrUtil_InStr", (_ctx, _node, args) => {
|
|||||||
});
|
});
|
||||||
register("StrUtil_Replace", (_ctx, _node, args) => {
|
register("StrUtil_Replace", (_ctx, _node, args) => {
|
||||||
const text = str(first(args, ["string"]));
|
const text = str(first(args, ["string"]));
|
||||||
const search = str(first(args, ["search", "Config"]));
|
// catalog 契约:search 为下拉枚举("0"内容/"1"数字/"2"手机号/"3"邮箱/"4"身份证/"5"自定义正则),查找目标在 Config
|
||||||
|
// 旧实现直接把枚举值 "0" 当字面文本分割,导致按内容替换永远不生效(W26 系枚举映射 bug 同族)
|
||||||
|
const modeRaw = first(args, ["search"]);
|
||||||
|
const mode = str(modeRaw === undefined ? "0" : modeRaw);
|
||||||
|
const config = str(first(args, ["Config"]));
|
||||||
const replacement = str(first(args, ["replace"]));
|
const replacement = str(first(args, ["replace"]));
|
||||||
return text.split(search).join(replacement);
|
const presets: Record<string, RegExp> = {
|
||||||
|
"1": /\d+/g,
|
||||||
|
"2": /1[3-9]\d{9}/g,
|
||||||
|
"3": /[\w.+-]+@[\w-]+(?:\.[\w-]+)+/g,
|
||||||
|
"4": /\d{17}[\dXx]/g
|
||||||
|
};
|
||||||
|
if (presets[mode]) return text.replace(presets[mode], replacement);
|
||||||
|
if (mode === "5") {
|
||||||
|
try {
|
||||||
|
return text.replace(new RegExp(config, "g"), replacement);
|
||||||
|
} catch {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// "0" = 指定内容;兼容旧契约:Config 为空时退回把 search 当字面文本
|
||||||
|
const target = config || mode;
|
||||||
|
return text.split(target).join(replacement);
|
||||||
});
|
});
|
||||||
register(["StrUtil_LowerCase"], (_ctx, _node, args) => str(first(args, ["string"])).toLowerCase());
|
register(["StrUtil_LowerCase"], (_ctx, _node, args) => str(first(args, ["string"])).toLowerCase());
|
||||||
register(["StrUtil_UpperCase"], (_ctx, _node, args) => str(first(args, ["string"])).toUpperCase());
|
register(["StrUtil_UpperCase"], (_ctx, _node, args) => str(first(args, ["string"])).toUpperCase());
|
||||||
|
|||||||
@@ -154,7 +154,10 @@ const notice: CapabilityHandler = async (_ctx, _node, args) => {
|
|||||||
// MessageBox 阻塞等用户点确定,同样不能吃 powershell() 默认 30s 超时;且 MB_TOPMOST 保证弹窗不被主窗口盖住
|
// MessageBox 阻塞等用户点确定,同样不能吃 powershell() 默认 30s 超时;且 MB_TOPMOST 保证弹窗不被主窗口盖住
|
||||||
const waitSeconds = number(args, ["wait_time", "waitTime", "timeout"], 600);
|
const waitSeconds = number(args, ["wait_time", "waitTime", "timeout"], 600);
|
||||||
const timeoutMs = Math.max(10000, Math.round(waitSeconds * 1000));
|
const timeoutMs = Math.max(10000, Math.round(waitSeconds * 1000));
|
||||||
await powershell(`Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show(${psString(content)},${psString(title)},'OK','Information','Button1','HelpButton',1) | Out-Null`, timeoutMs);
|
// 置顶方案: MB_TOPMOST/262144 是 Win32 老接口标志, .NET MessageBoxOptions 枚举里没有(只有 RightAlign/RtlReading/ServiceNotification 等),
|
||||||
|
// 传 262144 会被 PS 枚举转换拒绝。正确做法是传一个 TopMost 的隐形属主窗体;
|
||||||
|
// 属主窗体万一失败则 catch 降级为普通 Show, 保证弹窗一定出现不阻塞流程。
|
||||||
|
await powershell(`Add-Type -AssemblyName System.Windows.Forms; $f = New-Object System.Windows.Forms.Form; $f.TopMost = $true; try { [System.Windows.Forms.MessageBox]::Show($f,${psString(content)},${psString(title)},'OK','Information') | Out-Null } catch { [System.Windows.Forms.MessageBox]::Show(${psString(content)},${psString(title)},'OK','Information') | Out-Null }; $f.Dispose()`, timeoutMs);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -246,6 +246,10 @@ register("File_CompressFile", async (_ctx, node, args) => {
|
|||||||
|
|
||||||
register("File_DecompressFile", async (_ctx, node, args) => {
|
register("File_DecompressFile", async (_ctx, node, args) => {
|
||||||
const source = requirePath(pick(args, ["folder_path", "path", "zip_path"]), "压缩包路径", node.id, node.componentId);
|
const source = requirePath(pick(args, ["folder_path", "path", "zip_path"]), "压缩包路径", node.id, node.componentId);
|
||||||
|
// adm-zip 对不存在的文件抛 "ADM-ZIP: Invalid filename",极具误导性;先显式检查文件存在性
|
||||||
|
await fs.access(source).catch(() => {
|
||||||
|
throw new RuntimeError("file_not_found", `压缩包不存在:${source}`, { nodeId: node.id, componentId: node.componentId, recommendation: "确认压缩包实际产物路径(压缩组件默认在原文件名后追加 .zip,如 a.txt 会压成 a.txt.zip),或用压缩节点的输出变量传入" });
|
||||||
|
});
|
||||||
const saveToSourceDir = String(args.direct_type ?? "1") !== "0";
|
const saveToSourceDir = String(args.direct_type ?? "1") !== "0";
|
||||||
const target = saveToSourceDir
|
const target = saveToSourceDir
|
||||||
? path.dirname(source)
|
? path.dirname(source)
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户