可视化编排添加命令配置功能

This commit is contained in:
fofolee
2025-02-12 23:41:49 +08:00
parent 8c564f8d97
commit 2cb0c6bb32
20 changed files with 1147 additions and 243 deletions

View File

@@ -1,66 +0,0 @@
const winScpt = `Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll", SetLastError=true)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", SetLastError=true)]
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
}
"@
$foregroundWindow = [Win32]::GetForegroundWindow()
$windowRect = New-Object Win32+RECT
$_ = [Win32]::GetWindowRect($foregroundWindow, [ref]$windowRect)
$result = New-Object PSObject
$result | Add-Member -Type NoteProperty -Name Left -Value $windowRect.Left
$result | Add-Member -Type NoteProperty -Name Top -Value $windowRect.Top
$result | Add-Member -Type NoteProperty -Name Right -Value $windowRect.Right
$result | Add-Member -Type NoteProperty -Name Bottom -Value $windowRect.Bottom
$result | ConvertTo-Json`;
const macScpt = `tell application "System Events"
set frontmostProcess to first application process where it is frontmost
set frontmostWindow to first window of frontmostProcess
set {windowLeft, windowTop} to position of frontmostWindow
set {windowWidth, windowHeight} to size of frontmostWindow
set windowRight to windowLeft + windowWidth
set windowBottom to windowTop + windowHeight
end tell
return "{ \\"Left\\": " & windowLeft & ", \\"Top\\": " & windowTop & ", \\"Right\\": " & windowRight & ", \\"Bottom\\": " &windowBottom & " }"`;
const getForegroundWindowPos = async () => {
let foregroundWindowPos;
try {
if (window.utools.isWindows()) {
foregroundWindowPos = await window.quickcommand.runPowerShell(winScpt);
} else if (window.utools.isMacOS()) {
foregroundWindowPos = await window.quickcommand.runAppleScript(macScpt);
}
} catch (error) {
console.log(error);
}
if (!foregroundWindowPos) return;
return JSON.parse(foregroundWindowPos);
};
let autoDetach = async () => {
const foregroundWindowPos = await getForegroundWindowPos();
console.log(foregroundWindowPos);
if (foregroundWindowPos) {
const { Left, Top, Right, Bottom } = foregroundWindowPos;
let { x, y } = window.utools.getCursorScreenPoint();
window.utools.simulateMouseDoubleClick(Left + 200, Top + 30);
window.utools.simulateMouseMove(x, y);
}
};
export default {
autoDetach,
};

View File

@@ -2,6 +2,8 @@ import { reactive } from "vue";
import quickcommandParser from "js/common/quickcommandParser.js";
import importAll from "js/common/importAll.js";
import utoolsFull from "js/utools.js";
import { getUniqueId } from "js/common/uuid.js";
import outputTypes from "js/options/outputTypes.js";
// 默认命令
const defaultCommands = importAll(
@@ -16,6 +18,50 @@ const state = reactive({
activatedQuickPanels: [],
});
const getCmdType = (cmds) => {
const firstCmdType = cmds[0].type || "key";
if (!cmds.find((x) => typeof x !== "string")) return "key";
if (!cmds.find((x) => x.type !== firstCmdType)) return firstCmdType;
return "professional";
};
const getFeatureCode = (cmds) => {
return `${getCmdType(cmds)}_${getUniqueId({ short: true })}`;
};
const getLabeledCmds = (cmds, explain) => {
return cmds.map((cmd) => {
if (typeof cmd === "string") {
return cmd || explain;
}
return {
...cmd,
label: cmd.label || explain,
};
});
};
export const getValidCommand = (command) => {
const { cmds, explain } = command.features;
if (!explain) throw "名称不能为空";
if (!Array.isArray(cmds)) throw "匹配规则格式错误";
// 未配置label或关键字时直接使用名称
command.features.cmds = getLabeledCmds(cmds, explain);
// 不需要显示输入框的输入类型添加mainHide属性
if (outputTypes[command.output].outPlugin) {
command.features.mainHide = true;
}
// 生成唯一code
if (!command.features.code) {
command.features.code = getFeatureCode(cmds);
}
return window.lodashM.cloneDeep(command);
};
// 使用函数工厂模式,确保每个组件获取自己的状态副本
export function useCommandManager() {
// 获取已启用的命令
@@ -59,6 +105,11 @@ export function useCommandManager() {
// 保存命令
const saveCommand = (command) => {
try {
command = getValidCommand(command);
} catch (e) {
return quickcommand.showMessageBox(e.toString(), "error");
}
const code = command.features.code;
state.allQuickCommands[code] = command;
@@ -70,7 +121,7 @@ export function useCommandManager() {
utoolsFull.whole.setFeature(command.features);
if (!isDefaultCommand(code)) {
utoolsFull.putDB(window.lodashM.cloneDeep(command), "qc_" + code);
utoolsFull.putDB(command, "qc_" + code);
}
getAllQuickCommandTags();

View File

@@ -1,7 +1,9 @@
export const getUniqueId = () => {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
export const getUniqueId = (options = {}) => {
const { short = false } = options;
const uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
return short ? uuid.substring(0, 8) : uuid;
};

View File

@@ -133,3 +133,10 @@ export function generateCode(flow) {
return finalCode;
}
export function generateFlowsCode(flows) {
const [mainFlow, ...subFlows] = flows;
return [...subFlows, mainFlow]
.map((flow) => generateCode(flow))
.join("\n\n");
}

View File

@@ -3,7 +3,8 @@
*/
const jsonSample = [
"关键词",
"关键词1",
"关键词2",
{
type: "img",
label: "图片匹配",
@@ -41,12 +42,12 @@ const jsonSample = [
},
];
const commandTypes = {
export default {
key: {
name: "key",
label: "关键词",
icon: "font_download",
color: "teal",
color: "blue",
matchLabel: "关键词",
desc: "直接在主输入框输入对应关键字,最通用的一种模式,关键字可以设置多个",
valueType: "array",
@@ -57,7 +58,7 @@ const commandTypes = {
},
regex: {
name: "regex",
label: "正则/划词",
label: "正则",
icon: "rule",
color: "cyan",
matchLabel: "正则",
@@ -82,7 +83,7 @@ const commandTypes = {
over: {
name: "over",
label: "所有文本",
matchLabel: "无需置",
matchLabel: "无需置",
icon: "emergency",
color: "light-green",
desc: "匹配主输入框的所有文本,但只有在该文本未设置对应的插件或功能时才生效",
@@ -104,7 +105,7 @@ const commandTypes = {
},
window: {
name: "window",
label: "窗口/进程",
label: "窗口",
matchLabel: "进程名",
icon: "widgets",
color: "indigo",
@@ -154,7 +155,7 @@ const commandTypes = {
},
files: {
name: "files",
label: "复制/选中文件",
label: "文件",
matchLabel: "正则",
icon: "description",
color: "light-blue",
@@ -200,5 +201,3 @@ const commandTypes = {
jsonSample: jsonSample,
},
};
export default commandTypes;