mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-28 03:42:51 +08:00
可视化编排的命令卡片支持禁用,复制,快速打印
This commit is contained in:
parent
b026b484f7
commit
7a224be9f4
@ -123,7 +123,7 @@ export default defineComponent({
|
||||
const flow = window.lodashM.cloneDeep(this.commandFlow);
|
||||
const uselessProps = [
|
||||
"config",
|
||||
"argvs",
|
||||
"code",
|
||||
"label",
|
||||
"component",
|
||||
"subCommands",
|
||||
|
@ -6,6 +6,25 @@
|
||||
}"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<!-- 禁用遮罩层 -->
|
||||
<div
|
||||
v-if="localCommand.disabled"
|
||||
class="disabled-overlay"
|
||||
:class="{
|
||||
showToggleBtn: canToggleDisable,
|
||||
}"
|
||||
@click.stop="handleToggleDisable"
|
||||
>
|
||||
<div
|
||||
class="enable-btn-wrapper row items-center text-primary"
|
||||
:style="{
|
||||
fontSize: localCommand.isCollapsed ? '12px' : '16px',
|
||||
}"
|
||||
>
|
||||
<q-icon name="layers" class="q-mr-sm" />
|
||||
<div>点击启用</div>
|
||||
</div>
|
||||
</div>
|
||||
<q-card class="command-item">
|
||||
<q-card-section
|
||||
class="card-section"
|
||||
@ -20,6 +39,9 @@
|
||||
@toggle-collapse="handleToggleCollapse"
|
||||
@run="runCommand"
|
||||
@remove="$emit('remove')"
|
||||
@copy="handleCopy"
|
||||
@toggle-disable="handleToggleDisable"
|
||||
@add-print="handleAddPrint"
|
||||
>
|
||||
<!-- 控制流程组件,直接把组件放在head中 -->
|
||||
<template v-if="localCommand.isControlFlow">
|
||||
@ -74,6 +96,7 @@ import MultiParams from "components/composer/MultiParams.vue";
|
||||
import CommandHead from "components/composer/card/CommandHead.vue";
|
||||
import * as CardComponents from "js/composer/cardComponents";
|
||||
import { processVariable } from "js/composer/variableManager";
|
||||
import { newVarInputVal } from "js/composer/varInputValManager";
|
||||
import ControlCommand from "components/composer/control/ControlCommand.vue";
|
||||
|
||||
export default defineComponent({
|
||||
@ -95,7 +118,15 @@ export default defineComponent({
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
emits: ["remove", "run", "addBranch", "toggle-collapse", "update:modelValue"],
|
||||
emits: [
|
||||
"remove",
|
||||
"run",
|
||||
"addBranch",
|
||||
"toggle-collapse",
|
||||
"update:modelValue",
|
||||
"add-command",
|
||||
"toggle-disable",
|
||||
],
|
||||
computed: {
|
||||
localCommand: {
|
||||
get() {
|
||||
@ -105,18 +136,15 @@ export default defineComponent({
|
||||
this.$emit("update:modelValue", value);
|
||||
},
|
||||
},
|
||||
showRunBtn() {
|
||||
return !this.command.isControlFlow;
|
||||
},
|
||||
showOutputBtn() {
|
||||
return !this.command.isControlFlow;
|
||||
},
|
||||
isLastCommandInChain() {
|
||||
if (!this.command.commandChain) return false;
|
||||
isFirstCommandInChain() {
|
||||
if (!this.localCommand.commandChain) return false;
|
||||
return (
|
||||
this.command.commandType === this.command.commandChain?.slice(-1)[0]
|
||||
this.localCommand.commandType === this.localCommand.commandChain?.[0]
|
||||
);
|
||||
},
|
||||
canToggleDisable() {
|
||||
return !this.localCommand.isControlFlow || this.isFirstCommandInChain;
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const getCurrentVariables = inject("getCurrentVariables");
|
||||
@ -171,6 +199,68 @@ export default defineComponent({
|
||||
this.localCommand.isCollapsed = !this.localCommand.isCollapsed;
|
||||
}
|
||||
},
|
||||
handleCopy() {
|
||||
if (this.localCommand.isControlFlow && this.localCommand.chainId) {
|
||||
// 如果是控制流程命令,通知父组件复制整个链
|
||||
this.$emit("add-command", {
|
||||
command: this.localCommand,
|
||||
type: "chain",
|
||||
});
|
||||
} else {
|
||||
// 非控制流程命令的复制逻辑保持不变
|
||||
const copiedCommand = window.lodashM.cloneDeep(this.localCommand);
|
||||
delete copiedCommand.id;
|
||||
delete copiedCommand.chainId;
|
||||
delete copiedCommand.commandType;
|
||||
this.$emit("add-command", {
|
||||
command: copiedCommand,
|
||||
type: "single",
|
||||
});
|
||||
}
|
||||
},
|
||||
handleToggleDisable() {
|
||||
if (!this.canToggleDisable) return;
|
||||
if (this.localCommand.isControlFlow && this.localCommand.chainId) {
|
||||
console.log(
|
||||
"handleToggleDisable card",
|
||||
this.localCommand.isControlFlow,
|
||||
this.localCommand.chainId
|
||||
);
|
||||
// 如果是控制流程命令,通知父组件切换整个链的禁用状态
|
||||
this.$emit("toggle-disable", {
|
||||
chainId: this.localCommand.chainId,
|
||||
disabled: !this.localCommand.disabled,
|
||||
});
|
||||
} else {
|
||||
// 非控制流程命令的禁用逻辑保持不变
|
||||
this.localCommand.disabled = !this.localCommand.disabled;
|
||||
}
|
||||
},
|
||||
handleAddPrint() {
|
||||
// 创建一个打印命令
|
||||
if (!this.localCommand.outputVariable) {
|
||||
this.localCommand.outputVariable = `temp_${parseInt(
|
||||
new Date().getTime() / 1000
|
||||
)}`;
|
||||
this.localCommand.saveOutput = true;
|
||||
}
|
||||
const printCommand = {
|
||||
value: "console.log",
|
||||
label: "显示消息",
|
||||
config: [
|
||||
{
|
||||
label: "要打印的消息文本",
|
||||
component: "VariableInput",
|
||||
icon: "info",
|
||||
},
|
||||
],
|
||||
argvs: [newVarInputVal("var", this.localCommand.outputVariable)],
|
||||
};
|
||||
this.$emit("add-command", {
|
||||
command: printCommand,
|
||||
type: "single",
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -268,4 +358,71 @@ export default defineComponent({
|
||||
.command-item :deep(.condition-type-btn) {
|
||||
margin-left: -8px;
|
||||
}
|
||||
|
||||
/* 禁用状态样式 */
|
||||
.composer-card.disabled {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 禁用遮罩层 */
|
||||
.disabled-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(1px);
|
||||
border: 1px dashed rgba(0, 0, 0, 0.2);
|
||||
z-index: 10;
|
||||
border-radius: inherit;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.body--dark .disabled-overlay {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
/* 斜纹背景 */
|
||||
.disabled-overlay::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: repeating-linear-gradient(
|
||||
-45deg,
|
||||
rgba(0, 0, 0, 0.02),
|
||||
rgba(0, 0, 0, 0.02) 10px,
|
||||
rgba(0, 0, 0, 0.04) 10px,
|
||||
rgba(0, 0, 0, 0.04) 20px
|
||||
);
|
||||
border-radius: inherit;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.enable-btn-wrapper {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
user-select: none;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.disabled-overlay.showToggleBtn:hover .enable-btn-wrapper {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.disabled-overlay.showToggleBtn:hover {
|
||||
backdrop-filter: blur(0.5px);
|
||||
border-color: transparent;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
</style>
|
||||
|
@ -55,6 +55,8 @@
|
||||
@run="handleRunCommand"
|
||||
@add-branch="addBranch"
|
||||
@toggle-collapse="(event) => handleControlFlowCollapse(event)"
|
||||
@add-command="(event) => handleAddCommand(event, index)"
|
||||
@toggle-disable="handleToggleDisable"
|
||||
/>
|
||||
</div>
|
||||
</transition>
|
||||
@ -435,6 +437,62 @@ export default defineComponent({
|
||||
this.$emit("action", action, payload);
|
||||
}
|
||||
},
|
||||
getChainCommands(chainId) {
|
||||
const startIndex = this.commands.findIndex(
|
||||
(cmd) => cmd.chainId === chainId
|
||||
);
|
||||
const endIndex = this.commands.findLastIndex(
|
||||
(cmd) => cmd.chainId === chainId
|
||||
);
|
||||
return {
|
||||
chainCommands: this.commands.slice(startIndex, endIndex + 1),
|
||||
startIndex,
|
||||
endIndex,
|
||||
};
|
||||
},
|
||||
copyChainCommands(chainCommands) {
|
||||
// 生成新的chainId
|
||||
const newChainId = this.$root.getUniqueId();
|
||||
// 复制并修改每个命令
|
||||
const newChainCommands = [];
|
||||
chainCommands.forEach((cmd) => {
|
||||
const copiedCommand = window.lodashM.cloneDeep(cmd);
|
||||
copiedCommand.id = this.$root.getUniqueId();
|
||||
if (copiedCommand.chainId) copiedCommand.chainId = newChainId;
|
||||
newChainCommands.push(copiedCommand);
|
||||
});
|
||||
return newChainCommands;
|
||||
},
|
||||
handleAddCommand({ command, type }, index) {
|
||||
if (type === "chain") {
|
||||
// 如果是复制链式命令
|
||||
const { chainCommands, endIndex } = this.getChainCommands(
|
||||
command.chainId
|
||||
);
|
||||
const newChainCommands = this.copyChainCommands(chainCommands);
|
||||
const newCommands = [...this.commands];
|
||||
newCommands.splice(endIndex + 1, 0, ...newChainCommands);
|
||||
this.$emit("update:modelValue", newCommands);
|
||||
} else {
|
||||
// 单个命令的复制逻辑
|
||||
const newCommand = {
|
||||
...command,
|
||||
id: this.$root.getUniqueId(),
|
||||
};
|
||||
const newCommands = [...this.commands];
|
||||
newCommands.splice(index + 1, 0, newCommand);
|
||||
this.$emit("update:modelValue", newCommands);
|
||||
}
|
||||
},
|
||||
handleToggleDisable({ chainId, disabled }) {
|
||||
console.log("handleToggleDisable", chainId, disabled);
|
||||
const { chainCommands } = this.getChainCommands(chainId);
|
||||
// 更新所有相关命令的禁用状态
|
||||
const newCommands = chainCommands.map((cmd) => {
|
||||
return { ...cmd, disabled };
|
||||
});
|
||||
this.$emit("update:modelValue", newCommands);
|
||||
},
|
||||
collapseAll() {
|
||||
const newCommands = this.commands.map((cmd) => ({
|
||||
...cmd,
|
||||
|
@ -199,8 +199,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.funcName, this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(this.funcName, argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -54,6 +54,50 @@
|
||||
<q-tooltip>单独运行此命令并打印输出</q-tooltip>
|
||||
</q-icon>
|
||||
|
||||
<!-- 更多操作按钮 -->
|
||||
<q-icon
|
||||
name="more_vert"
|
||||
class="more-btn"
|
||||
v-if="!isControlFlow || isFirstCommandInChain"
|
||||
>
|
||||
<q-menu>
|
||||
<q-list style="min-width: 150px">
|
||||
<q-item clickable v-close-popup @click="$emit('copy')">
|
||||
<q-item-section avatar>
|
||||
<q-icon name="content_copy" />
|
||||
</q-item-section>
|
||||
<q-item-section>复制命令</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="$emit('toggle-disable')"
|
||||
x
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon :name="command.disabled ? 'check_circle' : 'block'" />
|
||||
</q-item-section>
|
||||
<q-item-section>{{
|
||||
command.disabled ? "启用命令" : "禁用命令"
|
||||
}}</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="$emit('add-print')"
|
||||
v-if="!isControlFlow"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="chat" />
|
||||
</q-item-section>
|
||||
<q-item-section>打印输出</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-icon>
|
||||
|
||||
<q-icon
|
||||
name="close"
|
||||
@click="$emit('remove')"
|
||||
@ -109,6 +153,9 @@ export default {
|
||||
"run",
|
||||
"remove",
|
||||
"toggle-collapse",
|
||||
"copy",
|
||||
"toggle-disable",
|
||||
"add-print",
|
||||
],
|
||||
methods: {
|
||||
handleBlur() {
|
||||
@ -167,7 +214,8 @@ export default {
|
||||
/* 按钮样式 */
|
||||
.output-btn,
|
||||
.run-btn,
|
||||
.remove-btn {
|
||||
.remove-btn,
|
||||
.more-btn {
|
||||
font-size: 18px;
|
||||
min-height: 25px;
|
||||
cursor: pointer;
|
||||
@ -178,7 +226,8 @@ export default {
|
||||
|
||||
.output-btn:hover,
|
||||
.run-btn:hover,
|
||||
.remove-btn:hover {
|
||||
.remove-btn:hover,
|
||||
.more-btn:hover {
|
||||
opacity: 1;
|
||||
transform: scale(1.1) translateY(-1px);
|
||||
transition: all 0.3s ease;
|
||||
|
@ -317,9 +317,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// 只在没有 argvs 和 code 的情况下生成默认代码
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -350,8 +350,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -300,8 +300,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -274,8 +274,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -675,8 +675,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -493,8 +493,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -249,8 +249,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -705,11 +705,12 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.code && !this.modelValue.argvs) {
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.$emit("update:modelValue", {
|
||||
...this.modelValue,
|
||||
argvs: this.defaultArgvs,
|
||||
code: this.generateCode(this.defaultArgvs),
|
||||
argvs,
|
||||
code: this.generateCode(argvs),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -678,8 +678,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.code && !this.modelValue.argvs) {
|
||||
this.updateValue();
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -271,8 +271,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -388,8 +388,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
this.updateModelValue(this.defaultArgvs);
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.updateModelValue(argvs);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -104,7 +104,6 @@ export const imageCommands = {
|
||||
width: 6,
|
||||
min: 1,
|
||||
step: 10,
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
label: "高度(像素)",
|
||||
@ -113,7 +112,6 @@ export const imageCommands = {
|
||||
width: 6,
|
||||
min: 1,
|
||||
step: 10,
|
||||
defaultValue: "",
|
||||
},
|
||||
{
|
||||
label: "保持宽高比",
|
||||
|
@ -172,11 +172,12 @@ const customComponentGuide = {
|
||||
description: "组件初始化时的处理",
|
||||
implementation: `
|
||||
// 如果没有 argvs 和 code,使用默认值初始化
|
||||
if (!this.modelValue.argvs && !this.modelValue.code) {
|
||||
const argvs = this.modelValue.argvs || this.defaultArgvs;
|
||||
if (!this.modelValue.code) {
|
||||
this.$emit("update:modelValue", {
|
||||
...this.modelValue,
|
||||
argvs: this.defaultArgvs,
|
||||
code: this.generateCode(this.defaultArgvs)
|
||||
argvs,
|
||||
code: this.generateCode(argvs),
|
||||
});
|
||||
}
|
||||
`,
|
||||
|
@ -6,6 +6,8 @@ export function generateCode(commandFlow) {
|
||||
const indent = hasAsyncFunction ? " " : "";
|
||||
|
||||
commandFlow.forEach((cmd) => {
|
||||
// 跳过禁用的命令
|
||||
if (cmd.disabled) return;
|
||||
if (!cmd.code) return;
|
||||
let line = indent;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user