diff --git a/src/components/composer/CommandComposer.vue b/src/components/composer/CommandComposer.vue
index 5019b27..0689ccc 100644
--- a/src/components/composer/CommandComposer.vue
+++ b/src/components/composer/CommandComposer.vue
@@ -29,6 +29,7 @@ import {
findCommandByValue,
} from "js/composer/composerConfig";
import { generateCode } from "js/composer/generateCode";
+import { parseVariables } from "js/composer/variableManager";
export default defineComponent({
name: "CommandComposer",
@@ -37,37 +38,32 @@ export default defineComponent({
ComposerFlow,
},
setup() {
- const variables = ref([]);
+ const commandFlow = ref([]);
- const addVariable = (name, command) => {
- if (!variables.value.find((v) => v.name === name)) {
- variables.value.push({
- name,
- sourceCommand: command,
- });
+ // 提供获取当前变量的函数,直接返回解析后的变量列表
+ const getCurrentVariables = () => {
+ const variables = [];
+ for (const cmd of commandFlow.value) {
+ if (cmd.saveOutput && cmd.outputVariable) {
+ variables.push(
+ ...parseVariables(cmd.outputVariable).map((variable) => ({
+ name: variable,
+ sourceCommand: cmd,
+ }))
+ );
+ }
}
+ return variables;
};
- const removeVariable = (name) => {
- const index = variables.value.findIndex((v) => v.name === name);
- if (index !== -1) {
- variables.value.splice(index, 1);
- }
- };
-
- provide("composerVariables", variables);
- provide("addVariable", addVariable);
- provide("removeVariable", removeVariable);
+ provide("getCurrentVariables", getCurrentVariables);
return {
- variables,
- addVariable,
- removeVariable,
+ commandFlow,
};
},
data() {
return {
- commandFlow: [],
availableCommands,
};
},
diff --git a/src/components/composer/ComposerCard.vue b/src/components/composer/ComposerCard.vue
index 48f88c6..ccb2144 100644
--- a/src/components/composer/ComposerCard.vue
+++ b/src/components/composer/ComposerCard.vue
@@ -66,11 +66,11 @@
@@ -115,7 +138,7 @@ export default {
}
.variable-input {
- width: 100px;
+ width: 120px;
}
.output-section :deep(.q-field) {
diff --git a/src/components/composer/common/VariableInput.vue b/src/components/composer/common/VariableInput.vue
index ac379d5..f1d396f 100644
--- a/src/components/composer/common/VariableInput.vue
+++ b/src/components/composer/common/VariableInput.vue
@@ -79,7 +79,7 @@
}"
class="variable-dropdown prepend-btn"
size="sm"
- v-if="variables.length"
+ @click="variables = getCurrentVariables()"
>
@@ -108,6 +108,15 @@
+
+
+
+ 无可用变量,请先点击命令卡片输出变量按钮设置变量
+
+
+
@@ -176,13 +185,14 @@ export default defineComponent({
emits: ["update:modelValue"],
setup() {
- const variables = inject("composerVariables", []);
- return { variables };
+ const getCurrentVariables = inject("getCurrentVariables");
+ return { getCurrentVariables };
},
data() {
return {
selectedVariable: null,
+ variables: [],
};
},
diff --git a/src/components/composer/ubrowser/UBrowserOperations.vue b/src/components/composer/ubrowser/UBrowserOperations.vue
index 602ab1f..082af2d 100644
--- a/src/components/composer/ubrowser/UBrowserOperations.vue
+++ b/src/components/composer/ubrowser/UBrowserOperations.vue
@@ -136,7 +136,6 @@ export default defineComponent({
id: this.$root.getUniqueId(),
argv: "",
saveOutput: false,
- useOutput: null,
cmd: action.value || action.cmd,
value: action.value || action.cmd,
};
diff --git a/src/js/common/variableValidator.js b/src/js/common/variableValidator.js
index 227ee4d..2170219 100644
--- a/src/js/common/variableValidator.js
+++ b/src/js/common/variableValidator.js
@@ -117,6 +117,9 @@ const reservedWords = [
* @returns {object} - 包含验证结果和错误信息的对象
*/
export function validateVariableName(name) {
+ // 去除空格
+ name = name.trim();
+
// 检查是否为空
if (!name) {
return {
diff --git a/src/js/composer/commands/uiCommand.js b/src/js/composer/commands/uiCommand.js
index 1445361..56a88a5 100644
--- a/src/js/composer/commands/uiCommand.js
+++ b/src/js/composer/commands/uiCommand.js
@@ -7,6 +7,8 @@ export const uiCommands = {
value: "quickcommand.showButtonBox",
label: "按钮组弹窗",
isAsync: true,
+ outputVariable: "{id,text}",
+ saveOutput: true,
config: [
{
label: "按钮组",
diff --git a/src/js/composer/variableManager.js b/src/js/composer/variableManager.js
new file mode 100644
index 0000000..fc42889
--- /dev/null
+++ b/src/js/composer/variableManager.js
@@ -0,0 +1,177 @@
+import { validateVariableName } from "js/common/variableValidator";
+
+/**
+ * 生成随机后缀
+ * @param {number} varCount - 当前变量数量
+ * @returns {string} 随机后缀
+ */
+function generateRandomSuffix(varCount) {
+ // 根据变量数量决定后缀长度
+ let length = 1; // 默认1位
+ if (varCount >= 100) {
+ length = 3;
+ } else if (varCount >= 10) {
+ length = 2;
+ }
+
+ return (
+ "_" +
+ Math.random()
+ .toString(36)
+ .substring(2, 2 + length)
+ );
+}
+
+/**
+ * 解析变量名
+ * @param {string} value - 变量表达式
+ * @returns {string[]} 解析出的所有变量名
+ */
+export function parseVariables(value) {
+ if (!value) return [];
+
+ const destructured = extractDestructuredVars(value);
+ if (!destructured) {
+ return [value.trim()];
+ }
+
+ // 处理解构变量
+ return destructured.vars.map((name) => {
+ // 处理重命名格式 (key:value)
+ const parts = name.split(":").map((p) => p.trim());
+ return parts[parts.length - 1]; // 返回实际的变量名
+ });
+}
+
+/**
+ * 生成有效的变量名
+ * @param {string} baseName - 基础变量名
+ * @param {string[]} existingVars - 已存在的变量列表
+ * @param {string} [currentName] - 当前的变量名(如果有)
+ * @returns {string} 有效的变量名
+ */
+function generateValidVarName(baseName, existingVars, currentName = null) {
+ // 如果当前名称有效且不重复,直接返回
+ if (
+ currentName &&
+ validateVariableName(currentName).isValid &&
+ !existingVars.includes(currentName)
+ ) {
+ return currentName;
+ }
+
+ // 如果变量名无效,生成一个随机变量名
+ if (!validateVariableName(baseName).isValid) {
+ baseName = "var" + generateRandomSuffix(existingVars.length);
+ }
+
+ // 如果变量名重复,添加随机后缀直到不重复
+ let finalName = baseName;
+ while (existingVars.includes(finalName)) {
+ let suffix;
+ do {
+ suffix = generateRandomSuffix(existingVars.length);
+ } while (existingVars.includes(baseName + suffix));
+ finalName = baseName + suffix;
+ }
+
+ return finalName;
+}
+
+/**
+ * 处理变量更新
+ * @param {Object} params - 参数对象
+ * @param {string} params.value - 新的变量名
+ * @param {string[]} params.existingVars - 当前已存在的变量列表
+ * @returns {Object} - 处理结果
+ */
+export function processVariable({ value, existingVars }) {
+ if (!value) {
+ return { isValid: true, processedValue: value };
+ }
+
+ const destructured = extractDestructuredVars(value);
+
+ if (!destructured) {
+ // 处理单个变量
+ const processedVar = generateValidVarName(value, existingVars);
+ return {
+ isValid: true,
+ processedValue: processedVar,
+ warning:
+ processedVar !== value ? `变量名已被修改为: ${processedVar}` : null,
+ };
+ }
+
+ // 处理解构变量
+ const processedVars = destructured.vars.map((name) => {
+ const parts = name.split(":").map((p) => p.trim());
+ const key = parts.length > 1 ? parts[0] : parts[0];
+ const varName = parts[parts.length - 1];
+ const processedName = generateValidVarName(varName, existingVars, varName);
+
+ return {
+ key,
+ processedName,
+ needsRename: processedName !== varName,
+ };
+ });
+
+ // 如果有变量需要重命名,使用对象解构格式
+ if (processedVars.some((v) => v.needsRename)) {
+ const pairs = processedVars.map((v) =>
+ v.needsRename ? `${v.key}:${v.processedName}` : v.key
+ );
+ const format = `{${pairs.join(", ")}}`;
+ return {
+ isValid: true,
+ processedValue: format,
+ warning: `变量名已被修改为: ${format}`,
+ };
+ }
+
+ // 保持原始格式
+ const format =
+ destructured.format === "array"
+ ? `[${processedVars.map((v) => v.key).join(", ")}]`
+ : `{${processedVars.map((v) => v.key).join(", ")}}`;
+
+ return {
+ isValid: true,
+ processedValue: format,
+ };
+}
+
+/**
+ * 提取解构变量
+ * @param {string} value - 输入的变量名
+ * @returns {Object|null} - 解构的变量数组和格式,如果不是解构模式则返回null
+ */
+export function extractDestructuredVars(value) {
+ if (!value) return null;
+ value = value.trim();
+
+ // 检查是否是数组解构模式 [a, b, c]
+ if (value.startsWith("[") && value.endsWith("]")) {
+ return {
+ vars: value
+ .slice(1, -1)
+ .split(",")
+ .map((v) => v.trim()),
+ format: "array",
+ };
+ }
+
+ // 检查是否是对象解构模式 {a, b, c}
+ if (value.startsWith("{") && value.endsWith("}")) {
+ return {
+ vars: value
+ .slice(1, -1)
+ .split(",")
+ .map((v) => v.trim()),
+ format: "object",
+ };
+ }
+
+ return null;
+}