@arronqzy/vue-blueprint 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "@arronqzy/i18n/vue";
2
3
  import { computed } from "vue";
3
4
  import { Checkbox, Input } from "ant-design-vue";
4
5
  import type { ClockNodeConfig } from "@arronqzy/blueprint-dsl";
@@ -6,6 +7,8 @@ import type { ClockNodeConfig } from "@arronqzy/blueprint-dsl";
6
7
  import type { BlueprintGraphNode } from "../graph/document";
7
8
  import { resolveNodeClockConfig } from "../graph/document";
8
9
 
10
+ const { t } = useI18n();
11
+
9
12
  export type ClockNodeConfigPanelProps = {
10
13
  node: BlueprintGraphNode;
11
14
  onUpdateNode: (
@@ -57,15 +60,11 @@ function handleEmitImmediatelyChange(checked: boolean) {
57
60
 
58
61
  <template>
59
62
  <div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
60
- <div class="font-medium text-foreground">时钟节点</div>
61
- <p class="text-[11px] text-muted-foreground">
62
- 收到<strong>真信号</strong>后才开始计时输出;每次输出向下游发出
63
- <strong>真信号</strong>,值包含当前时间(formatted / timestamp / isoTime)。
64
- 假信号会原样向下游传递。
65
- </p>
63
+ <div class="font-medium text-foreground">{{ t("blueprint.config.clockTitle") }}</div>
64
+ <p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.clockHint") }}</p>
66
65
 
67
66
  <label class="block space-y-1">
68
- <span class="text-muted-foreground">时钟信号间隔(秒)</span>
67
+ <span class="text-muted-foreground">{{ t("blueprint.config.clockIntervalSeconds") }}</span>
69
68
  <Input
70
69
  type="number"
71
70
  :min="0"
@@ -75,12 +74,12 @@ function handleEmitImmediatelyChange(checked: boolean) {
75
74
  @update:value="handleIntervalChange"
76
75
  />
77
76
  <p class="text-[11px] text-muted-foreground">
78
- 两次输出之间的间隔 n 秒;多次输出或未开启「立即发送」时须大于 0。
77
+ {{ t("blueprint.config.clockIntervalHint") }}
79
78
  </p>
80
79
  </label>
81
80
 
82
81
  <label class="block space-y-1">
83
- <span class="text-muted-foreground">输出次数</span>
82
+ <span class="text-muted-foreground">{{ t("blueprint.config.outputCount") }}</span>
84
83
  <Input
85
84
  type="number"
86
85
  :min="1"
@@ -90,7 +89,7 @@ function handleEmitImmediatelyChange(checked: boolean) {
90
89
  @update:value="handleOutputCountChange"
91
90
  />
92
91
  <p class="text-[11px] text-muted-foreground">
93
- 收到真信号后总共输出的次数,默认 1。
92
+ {{ t("blueprint.config.outputCountHint") }}
94
93
  </p>
95
94
  </label>
96
95
 
@@ -101,13 +100,12 @@ function handleEmitImmediatelyChange(checked: boolean) {
101
100
  @update:checked="handleEmitImmediatelyChange"
102
101
  />
103
102
  <span class="text-[11px] leading-relaxed text-muted-foreground">
104
- 收到信号立即发送:开启且输出次数大于 1 时,会立刻执行第 1 次,剩余次数按间隔 m
105
- 秒依次执行;仅输出 1 次时也会立刻执行。关闭则每次(含首次)都先等待 m 秒。
103
+ {{ t("blueprint.config.emitImmediately") }}
106
104
  </span>
107
105
  </label>
108
106
 
109
107
  <label class="block space-y-1">
110
- <span class="text-muted-foreground">时间格式</span>
108
+ <span class="text-muted-foreground">{{ t("blueprint.config.timeFormat") }}</span>
111
109
  <Input
112
110
  size="small"
113
111
  :value="clockConfig.timeFormat"
@@ -117,7 +115,7 @@ function handleEmitImmediatelyChange(checked: boolean) {
117
115
  @input="handleFormatChange"
118
116
  />
119
117
  <p class="text-[11px] text-muted-foreground">
120
- 支持 YYYY、MM、DD、HH、mm、ss,默认 YYYY-MM-DD HH:mm:ss。
118
+ {{ t("blueprint.config.timeFormatHint") }}
121
119
  </p>
122
120
  </label>
123
121
  </div>
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "@arronqzy/i18n/vue";
2
3
  import { computed, ref } from "vue";
3
4
  import { Button, Input, Select } from "ant-design-vue";
4
5
  import type {
@@ -28,6 +29,8 @@ import {
28
29
  } from "../fetch-config-task-store";
29
30
  import FetchUrlAutocomplete from "./FetchUrlAutocomplete.vue";
30
31
 
32
+ const { t } = useI18n();
33
+
31
34
  export type FetchNodeConfigPanelProps = {
32
35
  node: BlueprintGraphNode;
33
36
  onUpdateNode: (
@@ -74,7 +77,7 @@ function setUrlInputMode(mode: "swagger" | "manual") {
74
77
  function handleLoadSwagger() {
75
78
  const docsUrl = fetchConfig.value.swaggerDocsUrl?.trim();
76
79
  if (!docsUrl) {
77
- validationError.value = "请先填写 Swagger 文档 URL";
80
+ validationError.value = t("blueprint.config.fillSwaggerUrlFirst");
78
81
  return;
79
82
  }
80
83
 
@@ -104,7 +107,7 @@ function handleAbortSwagger() {
104
107
  function handleSendFetchDebug() {
105
108
  const url = fetchConfig.value.url?.trim();
106
109
  if (!url) {
107
- fetchValidationError.value = "请先填写请求 URL";
110
+ fetchValidationError.value = t("blueprint.config.fillRequestUrlFirst");
108
111
  return;
109
112
  }
110
113
 
@@ -160,14 +163,13 @@ function handleHeadersBlur(event: Event) {
160
163
 
161
164
  <template>
162
165
  <div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
163
- <div class="font-medium text-foreground">数据源获取 (Fetch)</div>
166
+ <div class="font-medium text-foreground">{{ t("blueprint.config.fetchTitle") }}</div>
164
167
  <p class="text-[11px] text-muted-foreground">
165
- 收到<strong>真信号</strong>后发起 HTTP 请求;可导入 Swagger 文档后从接口列表联想选择
166
- URL。
168
+ {{ t("blueprint.config.fetchHint") }}
167
169
  </p>
168
170
 
169
171
  <label class="block space-y-1">
170
- <span class="text-muted-foreground">Swagger 文档 URL(可选)</span>
172
+ <span class="text-muted-foreground">{{ t("blueprint.config.swaggerUrlOptional") }}</span>
171
173
  <div class="flex gap-1.5">
172
174
  <Input
173
175
  size="small"
@@ -184,8 +186,8 @@ function handleHeadersBlur(event: Event) {
184
186
  v-if="loadingSwagger"
185
187
  size="small"
186
188
  class="h-8 w-8 shrink-0 text-destructive"
187
- title="中止解析"
188
- aria-label="中止 Swagger 解析"
189
+ :title="t('blueprint.config.abortParse')"
190
+ :aria-label="t('blueprint.config.abortSwaggerAria')"
189
191
  @click="handleAbortSwagger"
190
192
  >
191
193
  ■
@@ -194,24 +196,24 @@ function handleHeadersBlur(event: Event) {
194
196
  v-else
195
197
  size="small"
196
198
  class="h-8 w-8 shrink-0"
197
- title="解析 Swagger 文档"
199
+ :title="t('blueprint.config.parseSwagger')"
198
200
  @click="handleLoadSwagger"
199
201
  >
200
202
  ➤
201
203
  </Button>
202
204
  </div>
203
205
  <p v-if="loadingSwagger" class="text-[11px] text-muted-foreground">
204
- 正在解析 Swagger 文档,点击右侧按钮可中止…
206
+ {{ t("blueprint.config.parsingSwagger") }}
205
207
  </p>
206
208
  <p v-if="swaggerError" class="text-[11px] text-destructive">{{ swaggerError }}</p>
207
209
  <p v-if="endpoints.length > 0" class="text-[11px] text-muted-foreground">
208
- 已解析 {{ endpoints.length }} 个接口
210
+ {{ t("blueprint.config.parsedEndpoints", { count: endpoints.length }) }}
209
211
  </p>
210
212
  </label>
211
213
 
212
214
  <label class="block space-y-1">
213
215
  <div class="flex items-center justify-between gap-2">
214
- <span class="text-muted-foreground">请求 URL</span>
216
+ <span class="text-muted-foreground">{{ t("blueprint.config.requestUrl") }}</span>
215
217
  <div v-if="hasSwaggerEndpoints" class="flex rounded-md border border-border p-0.5">
216
218
  <button
217
219
  type="button"
@@ -224,7 +226,7 @@ function handleHeadersBlur(event: Event) {
224
226
  "
225
227
  @click="setUrlInputMode('swagger')"
226
228
  >
227
- 接口联想
229
+ {{ t("blueprint.config.suggestApi") }}
228
230
  </button>
229
231
  <button
230
232
  type="button"
@@ -237,7 +239,7 @@ function handleHeadersBlur(event: Event) {
237
239
  "
238
240
  @click="setUrlInputMode('manual')"
239
241
  >
240
- 手动输入
242
+ {{ t("blueprint.config.manualInput") }}
241
243
  </button>
242
244
  </div>
243
245
  </div>
@@ -248,7 +250,7 @@ function handleHeadersBlur(event: Event) {
248
250
  :class="loadingSwagger && 'pointer-events-none opacity-60'"
249
251
  >
250
252
  <label class="block space-y-1">
251
- <span class="text-muted-foreground">API 主机 / Base URL</span>
253
+ <span class="text-muted-foreground">{{ t("blueprint.config.apiHostBaseUrl") }}</span>
252
254
  <Input
253
255
  size="small"
254
256
  :value="fetchConfig.apiBaseUrl ?? ''"
@@ -260,7 +262,7 @@ function handleHeadersBlur(event: Event) {
260
262
  />
261
263
  </label>
262
264
  <label class="block space-y-1">
263
- <span class="text-muted-foreground">选择接口</span>
265
+ <span class="text-muted-foreground">{{ t("blueprint.config.selectEndpoint") }}</span>
264
266
  <div class="flex gap-1.5">
265
267
  <div class="min-w-0 flex-1">
266
268
  <FetchUrlAutocomplete
@@ -268,7 +270,7 @@ function handleHeadersBlur(event: Event) {
268
270
  :api-base-url="fetchConfig.apiBaseUrl ?? ''"
269
271
  :endpoints="endpoints"
270
272
  select-only
271
- placeholder="点击选择或搜索接口"
273
+ :placeholder="t('blueprint.config.selectOrSearchEndpoint')"
272
274
  @change="
273
275
  (url) => onUpdateNode(node.id, patchFetchConfig(node, { url }))
274
276
  "
@@ -288,7 +290,7 @@ function handleHeadersBlur(event: Event) {
288
290
  v-if="loadingFetchDebug"
289
291
  size="small"
290
292
  class="h-8 w-8 shrink-0"
291
- title="中止请求"
293
+ :title="t('blueprint.config.abortRequest')"
292
294
  @click="handleAbortFetchDebug"
293
295
  >
294
296
  ■
@@ -298,7 +300,7 @@ function handleHeadersBlur(event: Event) {
298
300
  size="small"
299
301
  class="h-8 w-8 shrink-0"
300
302
  :disabled="loadingSwagger"
301
- title="发送调试请求"
303
+ :title="t('blueprint.config.sendDebugRequest')"
302
304
  @click="handleSendFetchDebug"
303
305
  >
304
306
  ➤
@@ -319,7 +321,7 @@ function handleHeadersBlur(event: Event) {
319
321
  v-if="loadingFetchDebug"
320
322
  size="small"
321
323
  class="h-8 w-8 shrink-0"
322
- title="中止请求"
324
+ :title="t('blueprint.config.abortRequest')"
323
325
  @click="handleAbortFetchDebug"
324
326
  >
325
327
  ■
@@ -329,7 +331,7 @@ function handleHeadersBlur(event: Event) {
329
331
  size="small"
330
332
  class="h-8 w-8 shrink-0"
331
333
  :disabled="loadingSwagger"
332
- title="发送调试请求"
334
+ :title="t('blueprint.config.sendDebugRequest')"
333
335
  @click="handleSendFetchDebug"
334
336
  >
335
337
  ➤
@@ -337,7 +339,7 @@ function handleHeadersBlur(event: Event) {
337
339
  </div>
338
340
 
339
341
  <p v-if="loadingFetchDebug" class="text-[11px] text-muted-foreground">
340
- 正在发送调试请求,点击右侧按钮可中止…
342
+ {{ t("blueprint.config.sendingDebug") }}
341
343
  </p>
342
344
  <p v-if="fetchValidationError" class="text-[11px] text-destructive">
343
345
  {{ fetchValidationError }}
@@ -348,7 +350,7 @@ function handleHeadersBlur(event: Event) {
348
350
  class="rounded-md border border-destructive/40 bg-destructive/5 p-2"
349
351
  >
350
352
  <p class="text-[11px] text-destructive">
351
- {{ fetchDebugTask.error ?? "请求失败" }}
353
+ {{ fetchDebugTask.error ?? t("blueprint.config.requestFailed") }}
352
354
  </p>
353
355
  </div>
354
356
  <div
@@ -366,7 +368,7 @@ function handleHeadersBlur(event: Event) {
366
368
  >
367
369
  ▼
368
370
  </span>
369
- <span class="text-[11px] font-medium text-foreground">调试响应</span>
371
+ <span class="text-[11px] font-medium text-foreground">{{ t("blueprint.config.debugResponse") }}</span>
370
372
  <span
371
373
  class="rounded px-1.5 py-0.5 font-mono text-[10px]"
372
374
  :class="
@@ -396,7 +398,7 @@ function handleHeadersBlur(event: Event) {
396
398
  </label>
397
399
 
398
400
  <label class="block space-y-1">
399
- <span class="text-muted-foreground">请求方法</span>
401
+ <span class="text-muted-foreground">{{ t("blueprint.config.requestMethod") }}</span>
400
402
  <Select
401
403
  size="small"
402
404
  class="w-full"
@@ -416,7 +418,7 @@ function handleHeadersBlur(event: Event) {
416
418
  </label>
417
419
 
418
420
  <label class="block space-y-1">
419
- <span class="text-muted-foreground">请求头 (JSON)</span>
421
+ <span class="text-muted-foreground">{{ t("blueprint.config.requestHeadersJson") }}</span>
420
422
  <textarea
421
423
  :key="`${node.id}-headers-${JSON.stringify(fetchConfig.headers)}`"
422
424
  :value="JSON.stringify(fetchConfig.headers ?? {}, null, 2)"
@@ -428,7 +430,7 @@ function handleHeadersBlur(event: Event) {
428
430
  </label>
429
431
 
430
432
  <label class="block space-y-1">
431
- <span class="text-muted-foreground">请求体</span>
433
+ <span class="text-muted-foreground">{{ t("blueprint.config.requestBody") }}</span>
432
434
  <textarea
433
435
  :value="fetchConfig.body ?? ''"
434
436
  rows="4"
@@ -519,7 +521,7 @@ function handleHeadersBlur(event: Event) {
519
521
 
520
522
  <div class="grid grid-cols-2 gap-2">
521
523
  <label class="block space-y-1">
522
- <span class="text-muted-foreground">响应解析</span>
524
+ <span class="text-muted-foreground">{{ t("blueprint.config.responseParse") }}</span>
523
525
  <Select
524
526
  size="small"
525
527
  class="w-full"
@@ -538,7 +540,7 @@ function handleHeadersBlur(event: Event) {
538
540
  </Select>
539
541
  </label>
540
542
  <label class="block space-y-1">
541
- <span class="text-muted-foreground">超时 (ms)</span>
543
+ <span class="text-muted-foreground">{{ t("blueprint.config.timeoutMs") }}</span>
542
544
  <Input
543
545
  type="number"
544
546
  size="small"
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "@arronqzy/i18n/vue";
2
3
  import { computed, onUnmounted, ref, watch } from "vue";
3
4
  import {
4
5
  buildEndpointSuggestions,
@@ -8,6 +9,8 @@ import {
8
9
 
9
10
  import { cn } from "../utils/cn";
10
11
 
12
+ const { t } = useI18n();
13
+
11
14
  const props = withDefaults(
12
15
  defineProps<{
13
16
  value: string;
@@ -155,7 +158,7 @@ function handleKeyDown(event: KeyboardEvent) {
155
158
  v-if="filtered.length === 0"
156
159
  class="px-2 py-1.5 text-[11px] text-muted-foreground"
157
160
  >
158
- 无匹配接口
161
+ {{ t("blueprint.config.noMatchingEndpoint") }}
159
162
  </div>
160
163
  <button
161
164
  v-for="(item, index) in filtered"
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "@arronqzy/i18n/vue";
2
3
  import { computed, ref } from "vue";
3
4
  import { validateJsonString } from "@arronqzy/blueprint-dsl";
4
5
  import type { JsonNodeConfig } from "@arronqzy/blueprint-dsl";
@@ -6,6 +7,8 @@ import type { JsonNodeConfig } from "@arronqzy/blueprint-dsl";
6
7
  import type { BlueprintGraphNode } from "../graph/document";
7
8
  import { resolveNodeJsonConfig } from "../graph/document";
8
9
 
10
+ const { t } = useI18n();
11
+
9
12
  export type JsonNodeConfigPanelProps = {
10
13
  node: BlueprintGraphNode;
11
14
  onUpdateNode: (
@@ -45,15 +48,11 @@ function handleChange(event: Event) {
45
48
 
46
49
  <template>
47
50
  <div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
48
- <div class="font-medium text-foreground">JSON 节点</div>
49
- <p class="text-[11px] text-muted-foreground">
50
- 收到<strong>真信号</strong>后,将下方 JSON 解析为 JavaScript object(或
51
- array)并从输出口发出<strong>真信号</strong>;解析失败则发出
52
- <strong>假信号</strong>。
53
- </p>
51
+ <div class="font-medium text-foreground">{{ t("blueprint.config.jsonTitle") }}</div>
52
+ <p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.jsonHint") }}</p>
54
53
 
55
54
  <label class="block space-y-1">
56
- <span class="text-muted-foreground">JSON 内容</span>
55
+ <span class="text-muted-foreground">{{ t("blueprint.config.jsonContent") }}</span>
57
56
  <textarea
58
57
  :value="jsonConfig.jsonString"
59
58
  rows="12"
@@ -65,9 +64,9 @@ function handleChange(event: Event) {
65
64
  @input="handleChange"
66
65
  />
67
66
  <p v-if="parseError" class="text-[11px] text-destructive">
68
- JSON 格式错误:{{ parseError }}
67
+ {{ t("blueprint.config.jsonFormatError", { error: parseError }) }}
69
68
  </p>
70
- <p v-else class="text-[11px] text-muted-foreground">JSON 格式正确</p>
69
+ <p v-else class="text-[11px] text-muted-foreground">{{ t("blueprint.config.jsonFormatOk") }}</p>
71
70
  </label>
72
71
  </div>
73
72
  </template>
@@ -1,4 +1,5 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "@arronqzy/i18n/vue";
2
3
  import { computed, ref } from "vue";
3
4
  import { validateLogicSourceCode } from "@arronqzy/blueprint-dsl";
4
5
  import type { LogicNodeConfig } from "@arronqzy/blueprint-dsl";
@@ -6,6 +7,8 @@ import type { LogicNodeConfig } from "@arronqzy/blueprint-dsl";
6
7
  import type { BlueprintGraphNode } from "../graph/document";
7
8
  import { resolveNodeLogicConfig } from "../graph/document";
8
9
 
10
+ const { t } = useI18n();
11
+
9
12
  export type LogicNodeConfigPanelProps = {
10
13
  node: BlueprintGraphNode;
11
14
  onUpdateNode: (
@@ -45,15 +48,11 @@ function handleChange(event: Event) {
45
48
 
46
49
  <template>
47
50
  <div class="space-y-2 rounded-md border border-border/70 bg-muted/20 p-2.5">
48
- <div class="font-medium text-foreground">逻辑节点</div>
49
- <p class="text-[11px] text-muted-foreground">
50
- 收到<strong>真信号</strong>后,将输入数据传入下方 <code>update</code>
51
- 函数并执行;返回值作为<strong>真信号</strong>输出。代码语法错误或运行时报错则发出
52
- <strong>假信号</strong>(错误信息为输出值)。
53
- </p>
51
+ <div class="font-medium text-foreground">{{ t("blueprint.config.logicTitle") }}</div>
52
+ <p class="text-[11px] text-muted-foreground">{{ t("blueprint.config.logicHint") }}</p>
54
53
 
55
54
  <label class="block space-y-1">
56
- <span class="text-muted-foreground">JavaScript 代码</span>
55
+ <span class="text-muted-foreground">{{ t("blueprint.config.jsCode") }}</span>
57
56
  <textarea
58
57
  :value="logicConfig.sourceCode"
59
58
  rows="14"
@@ -65,9 +64,9 @@ function handleChange(event: Event) {
65
64
  @input="handleChange"
66
65
  />
67
66
  <p v-if="parseError" class="text-[11px] text-destructive">
68
- JavaScript 错误:{{ parseError }}
67
+ {{ t("blueprint.config.jsError", { error: parseError }) }}
69
68
  </p>
70
- <p v-else class="text-[11px] text-muted-foreground">JavaScript 语法正确</p>
69
+ <p v-else class="text-[11px] text-muted-foreground">{{ t("blueprint.config.jsSyntaxOk") }}</p>
71
70
  </label>
72
71
  </div>
73
72
  </template>
@@ -1,7 +1,10 @@
1
1
  <script setup lang="ts">
2
+ import { useI18n } from "@arronqzy/i18n/vue";
2
3
  import { computed } from "vue";
3
4
  import { Select } from "ant-design-vue";
4
5
 
6
+ const { t } = useI18n();
7
+
5
8
  export type ViewElementMultiSelectOption = {
6
9
  id: string;
7
10
  label: string;
@@ -15,7 +18,7 @@ const props = withDefaults(
15
18
  disabled?: boolean;
16
19
  }>(),
17
20
  {
18
- placeholder: "选择视图节点",
21
+ placeholder: undefined,
19
22
  disabled: false,
20
23
  }
21
24
  );
@@ -37,7 +40,7 @@ const emptyOptions = computed(() => props.options.length === 0);
37
40
  show-search
38
41
  :value="value"
39
42
  :disabled="disabled || emptyOptions"
40
- :placeholder="emptyOptions ? '视图画布暂无节点' : placeholder"
43
+ :placeholder="emptyOptions ? t('blueprint.config.noViewOnCanvas') : (placeholder ?? t('blueprint.config.selectViewNode'))"
41
44
  :options="selectOptions"
42
45
  :filter-option="
43
46
  (input, option) =>
@@ -241,4 +241,31 @@ export function useBlueprintPageLifecycle(options: UseBlueprintPageLifecycleOpti
241
241
  onUnmounted(() => {
242
242
  teardownBoot();
243
243
  });
244
+
245
+ async function triggerBlueprintNode(nodeId: string, inputValue?: unknown) {
246
+ const id = nodeId.trim();
247
+ if (!id) return;
248
+ const opts = runnerOptionsRef.value;
249
+ const libraryNameById = toValue(opts.libraryNameById);
250
+ const rootLibraryBlueprintId = toValue(opts.rootLibraryBlueprintId ?? null);
251
+ if (opts.resolveLibraryBlueprint) {
252
+ const result = await detectBlueprintReferenceCycle({
253
+ rootGraph: documentToRunnableGraph(graphRef.value.document, {
254
+ libraryNameById,
255
+ }),
256
+ rootLibraryBlueprintId,
257
+ resolveLibraryBlueprint: opts.resolveLibraryBlueprint,
258
+ resolveBlueprintName: (libId) =>
259
+ resolveBlueprintName(libraryNameById, libId),
260
+ });
261
+ if (!result.ok) {
262
+ opts.onExecutionBlocked?.(result.message);
263
+ return;
264
+ }
265
+ }
266
+ const runner = createRunner(graphRef.value, opts);
267
+ await runner.triggerNode(id, inputValue);
268
+ }
269
+
270
+ return { triggerBlueprintNode };
244
271
  }
@@ -5,6 +5,7 @@ import type {
5
5
  ParsedSwaggerDocument,
6
6
  } from "@arronqzy/blueprint-dsl";
7
7
  import { executeFetch } from "@arronqzy/blueprint-dsl";
8
+ import { resolveLocale, tForLocale } from "@arronqzy/i18n";
8
9
 
9
10
  import { loadSwaggerDocument } from "./library/swagger-docs";
10
11
 
@@ -152,7 +153,9 @@ export function startSwaggerLoadTask(params: {
152
153
  }
153
154
 
154
155
  const message =
155
- error instanceof Error ? error.message : "Swagger 文档解析失败";
156
+ error instanceof Error
157
+ ? error.message
158
+ : tForLocale(resolveLocale())("blueprint.config.swaggerParseFailed");
156
159
  swaggerTasks.set(params.nodeId, {
157
160
  record: { status: "error", error: message },
158
161
  abortController,
@@ -195,7 +198,10 @@ export function startFetchDebugTask(params: {
195
198
  return;
196
199
  }
197
200
 
198
- const message = error instanceof Error ? error.message : "请求失败";
201
+ const message =
202
+ error instanceof Error
203
+ ? error.message
204
+ : tForLocale(resolveLocale())("blueprint.config.requestFailed");
199
205
  fetchDebugTasks.set(params.nodeId, {
200
206
  record: { status: "error", error: message },
201
207
  abortController,
@@ -133,35 +133,72 @@ export function resolveRunnableNodeType(
133
133
  }
134
134
  }
135
135
 
136
- /** 画布节点顶部(拖拽区)展示的配置类型文案 */
137
- export const BLUEPRINT_CONFIG_TYPE_LABELS: Record<
136
+ import type { TranslateFn } from "@arronqzy/i18n";
137
+ import { resolveLocale, tForLocale } from "@arronqzy/i18n";
138
+
139
+ /** 画布节点顶部(拖拽区)配置类型对应的 i18n key */
140
+ export const BLUEPRINT_CONFIG_TYPE_LABEL_KEYS: Record<
138
141
  BlueprintConfigSource,
139
142
  string
140
143
  > = {
141
- blueprint: "蓝图",
142
- logic: "逻辑",
143
- and: "并运算",
144
- lifecycle: "生命周期",
145
- view: "视图",
146
- fetch: "数据源获取",
147
- json: "JSON 节点",
148
- clock: "时钟",
144
+ blueprint: "blueprint.node.typeBlueprint",
145
+ logic: "blueprint.node.typeLogic",
146
+ and: "blueprint.node.typeAnd",
147
+ lifecycle: "blueprint.node.typeLifecycle",
148
+ view: "blueprint.node.typeView",
149
+ fetch: "blueprint.node.typeFetch",
150
+ json: "blueprint.node.typeJson",
151
+ clock: "blueprint.node.typeClock",
149
152
  };
150
153
 
154
+ export const BLUEPRINT_LIFECYCLE_PHASE_KEYS: Record<PageLifecyclePhase, string> =
155
+ {
156
+ created: "blueprint.node.phaseCreated",
157
+ beforeMount: "blueprint.node.phaseBeforeMount",
158
+ mounted: "blueprint.node.phaseMounted",
159
+ updated: "blueprint.node.phaseUpdated",
160
+ beforeDestroy: "blueprint.node.phaseBeforeDestroy",
161
+ destroy: "blueprint.node.phaseDestroy",
162
+ activated: "blueprint.node.phaseActivated",
163
+ deactivated: "blueprint.node.phaseDeactivated",
164
+ blueprintActivated: "blueprint.node.phaseBlueprintActivated",
165
+ };
166
+
167
+ function defaultTranslate(): TranslateFn {
168
+ return tForLocale(resolveLocale());
169
+ }
170
+
171
+ export function getBlueprintNodeTypeLabel(
172
+ t: TranslateFn,
173
+ type: BlueprintConfigSource
174
+ ): string {
175
+ return t(BLUEPRINT_CONFIG_TYPE_LABEL_KEYS[type]);
176
+ }
177
+
178
+ export function getLifecyclePhaseLabel(
179
+ t: TranslateFn,
180
+ phase: PageLifecyclePhase
181
+ ): string {
182
+ const key = BLUEPRINT_LIFECYCLE_PHASE_KEYS[phase];
183
+ return key ? t(key) : phase;
184
+ }
185
+
151
186
  export function resolveBlueprintNodeTypeLabel(
152
187
  node: Pick<
153
188
  BlueprintGraphNode,
154
189
  "role" | "nodeType" | "configSource" | "viewElementId" | "viewElementIds"
155
- >
190
+ >,
191
+ t: TranslateFn = defaultTranslate()
156
192
  ): string {
157
- return BLUEPRINT_CONFIG_TYPE_LABELS[resolveBlueprintConfigSource(node)];
193
+ return getBlueprintNodeTypeLabel(t, resolveBlueprintConfigSource(node));
158
194
  }
159
195
 
160
196
  /** 新建节点时的默认显示名称(与类型文案一致) */
161
197
  export function defaultBlueprintNodeLabel(
162
- configSource: BlueprintConfigSource
198
+ configSource: BlueprintConfigSource,
199
+ t: TranslateFn = defaultTranslate()
163
200
  ): string {
164
- return BLUEPRINT_CONFIG_TYPE_LABELS[configSource];
201
+ return getBlueprintNodeTypeLabel(t, configSource);
165
202
  }
166
203
 
167
204
  export function resolveNodeFetchConfig(