diff --git a/src/components/composer/ComposerCard.vue b/src/components/composer/ComposerCard.vue index b756bd1..db84674 100644 --- a/src/components/composer/ComposerCard.vue +++ b/src/components/composer/ComposerCard.vue @@ -6,108 +6,48 @@ > -
- -
- -
- -
-
{{ command.label }}
- - - -
- - -
- - - -
- {{ - saveOutputLocal - ? "当前命令的输出将保存到变量中" - : "点击将此命令的输出保存为变量以供后续使用" - }} -
-
- {{ - saveOutputLocal - ? "点击取消输出到变量" - : "保存后可在其他命令中使用此变量" - }} -
-
-
- - - - 单独运行此命令并打印输出 - - - - 移除此命令 - -
- - -
- + + + + + + + + + +
+ +
@@ -119,12 +59,14 @@ import { defineComponent, inject, defineAsyncComponent } from "vue"; import { validateVariableName } from "js/common/variableValidator"; import VariableInput from "components/composer/ui/VariableInput.vue"; import MultiParamInput from "components/composer/ui/MultiParamInput.vue"; +import CommandHead from "components/composer/card/CommandHead.vue"; export default defineComponent({ name: "ComposerCard", components: { VariableInput, MultiParamInput, + CommandHead, KeyEditor: defineAsyncComponent(() => import("components/composer/ui/KeyEditor.vue") ), @@ -173,7 +115,14 @@ export default defineComponent({ showKeyRecorder: false, }; }, - emits: ["remove", "toggle-output", "update:argv", "update:command", "run"], + emits: [ + "remove", + "toggle-output", + "update:argv", + "update:command", + "run", + "addBranch", + ], computed: { saveOutputLocal: { get() { @@ -315,12 +264,6 @@ export default defineComponent({ this.$emit("run", tempCommand); }, }, - mounted() { - this.$el.classList.add("composer-card-enter-from"); - requestAnimationFrame(() => { - this.$el.classList.remove("composer-card-enter-from"); - }); - }, }); @@ -341,7 +284,6 @@ export default defineComponent({ .command-item:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - transition: all 0.3s ease; } /* 拖拽和放置样式 */ @@ -354,96 +296,6 @@ export default defineComponent({ border: 2px dashed var(--q-primary); } -.drag-handle { - display: flex; - align-items: center; - padding: 0 4px; -} - -.drag-handle:hover { - color: var(--q-primary); -} - -/* 输出部分样式 */ -.output-section { - max-width: 120px; - margin-right: 4px; -} - -.output-section :deep(.q-field) { - border-radius: 4px; -} - -.output-section :deep(.q-field__control) { - height: 28px; - min-height: 28px; - padding: 0 4px; -} - -.output-section :deep(.q-field__marginal) { - height: 28px; - width: 24px; - min-width: 24px; -} - -.output-section :deep(.q-field__native) { - padding: 0; - font-size: 12px; - min-height: 28px; - text-align: center; -} - -/* 按钮样式 */ -.output-btn, -.run-btn, -.remove-btn { - font-size: 12px; - border-radius: 4px; - min-height: 28px; - padding: 0 8px; - opacity: 0.6; - transition: all 0.3s ease; -} - -.output-btn:hover, -.run-btn:hover, -.remove-btn:hover { - opacity: 1; - transform: scale(1.05); -} - -.run-btn:hover { - color: var(--q-positive); -} - -.remove-btn:hover { - color: var(--q-negative); -} - -.output-btn.q-btn--active { - color: var(--q-primary); -} - -/* 动画效果 */ -.composer-card-enter-active { - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); -} - -.composer-card-enter-from { - opacity: 0; - transform: translateY(20px) scale(0.95); -} - -.composer-card-leave-active { - transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); - position: absolute; -} - -.composer-card-leave-to { - opacity: 0; - transform: translateY(-20px) scale(0.95); -} - /* 暗色模式适配 */ .body--dark .command-item { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); @@ -457,19 +309,8 @@ export default defineComponent({ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); } -.body--dark .output-section :deep(.q-field) { - background: rgba(255, 255, 255, 0.03); -} - -.body--dark .output-section :deep(.q-field--focused) { - background: #1d1d1d; -} - -.body--dark .output-btn { - border-color: rgba(255, 255, 255, 0.1); -} - -.body--dark .output-btn:hover { - background: rgba(255, 255, 255, 0.05); +/* 调整控制流程组件的样式 */ +.command-item :deep(.condition-type-btn) { + margin-left: -8px; } diff --git a/src/components/composer/ComposerFlow.vue b/src/components/composer/ComposerFlow.vue index 296f98c..335bc90 100644 --- a/src/components/composer/ComposerFlow.vue +++ b/src/components/composer/ComposerFlow.vue @@ -47,6 +47,7 @@ @update:argv="(val) => handleArgvChange(index, val)" @update:command="(val) => updateCommand(index, val)" @run="handleRunCommand" + @add-branch="() => addBranch(index)" />
@@ -162,16 +163,11 @@ export default defineComponent({ onDrop(event) { try { - // 尝试获取拖拽数据 const actionData = event.dataTransfer.getData("action"); + if (!actionData) return; - // 如果没有action数据,说明是内部排序,直接返回 - if (!actionData) { - return; - } - - // 解析外部拖入的新命令数据 const parsedAction = JSON.parse(actionData); + const isControlFlow = parsedAction.isControlFlow; const newCommand = { ...parsedAction, @@ -185,20 +181,37 @@ export default defineComponent({ }; const newCommands = [...this.commands]; - if (this.dragIndex >= 0) { - newCommands.splice(this.dragIndex, 0, newCommand); + + // 如果是控制流程命令,添加start和end两个卡片 + if (isControlFlow) { + const startCommand = { + ...newCommand, + id: Date.now(), + controlFlowType: "start", + }; + + const endCommand = { + ...newCommand, + id: Date.now() + 1, + controlFlowType: "end", + }; + + if (this.dragIndex >= 0) { + newCommands.splice(this.dragIndex, 0, startCommand, endCommand); + } else { + newCommands.push(startCommand, endCommand); + } } else { - newCommands.push(newCommand); + if (this.dragIndex >= 0) { + newCommands.splice(this.dragIndex, 0, newCommand); + } else { + newCommands.push(newCommand); + } } this.$emit("update:modelValue", newCommands); this.dragIndex = -1; - - document.querySelectorAll(".dragging").forEach((el) => { - el.classList.remove("dragging"); - }); } catch (error) { - // 忽略内部拖动排序的错误 console.debug("Internal drag & drop reorder", error); } }, @@ -255,6 +268,30 @@ export default defineComponent({ // 触发运行事件 this.$emit("action", "run", tempFlow); }, + addBranch(index) { + const newCommands = [...this.commands]; + const midCommand = { + ...newCommands[index], + id: Date.now(), + controlFlowType: "mid", + argv: "", + }; + + // 找到对应的end位置 + let endIndex = index + 1; + let depth = 1; + while (endIndex < newCommands.length && depth > 0) { + if (newCommands[endIndex].controlFlowType === "start") depth++; + if (newCommands[endIndex].controlFlowType === "end") depth--; + endIndex++; + } + + // 在end之前插入新的分支 + if (endIndex > index + 1) { + newCommands.splice(endIndex - 1, 0, midCommand); + this.$emit("update:modelValue", newCommands); + } + }, }, }); diff --git a/src/components/composer/card/CommandButtons.vue b/src/components/composer/card/CommandButtons.vue new file mode 100644 index 0000000..cbe48ca --- /dev/null +++ b/src/components/composer/card/CommandButtons.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/src/components/composer/card/CommandHead.vue b/src/components/composer/card/CommandHead.vue new file mode 100644 index 0000000..ba01a26 --- /dev/null +++ b/src/components/composer/card/CommandHead.vue @@ -0,0 +1,95 @@ + + + + + diff --git a/src/components/composer/control/ConditionalJudgment.vue b/src/components/composer/control/ConditionalJudgment.vue index 8f98486..062d5b8 100644 --- a/src/components/composer/control/ConditionalJudgment.vue +++ b/src/components/composer/control/ConditionalJudgment.vue @@ -1,83 +1,54 @@