From 77cf0c5edc00dad7341c458fc4a89698f2eb6458 Mon Sep 17 00:00:00 2001 From: Megghy Date: Tue, 22 Apr 2025 02:30:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=92=8C=E7=BB=84=E4=BB=B6=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E5=8A=9F=E8=83=BD=E5=92=8C=E7=94=A8=E6=88=B7=E4=BD=93?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 .gitignore 中添加了 .specstory 文件的忽略规则。 - 更新 tsconfig.json,修正了 vue-vine/types/macros 的引用路径。 - 在组件声明中新增了 NInput 组件的类型支持。 - 优化了 EventModel 接口,调整了 guard_level 的类型为 GuardLevel。 - 增加了 Follow 事件类型到 EventDataTypes 枚举中。 - 在 ClientAutoAction.vue 中引入了新的 store 和组件,增强了功能。 - 更新了多个设置组件,添加了关键词匹配类型和过滤模式的支持。 - 改进了模板编辑器和测试器的功能,支持更灵活的模板管理。 - 在弹幕客户端中新增了关注事件的处理逻辑,提升了事件响应能力。 --- .cursorindexingignore | 2 + .gitignore | 1 + src/api/api-models.ts | 5 +- src/client/ClientAutoAction.vue | 766 ++++++--- .../autoaction/AutoActionEditor.vue | 70 +- .../components/autoaction/DataManager.vue | 352 ++++ .../autoaction/SingleTemplateEditor.vue | 40 + .../components/autoaction/TemplateEditor.vue | 863 ++++++---- .../components/autoaction/TemplateTester.vue | 10 +- .../components/autoaction/TimerCountdown.vue | 151 ++ .../autoaction/settings/AdvancedSettings.vue | 106 +- .../autoaction/settings/DanmakuSettings.vue | 60 +- .../autoaction/settings/EnterSettings.vue | 2 +- .../autoaction/settings/GiftSettings.vue | 6 +- .../settings/GlobalScheduledSettings.vue | 85 + .../autoaction/settings/ScheduledSettings.vue | 84 +- .../autoaction/settings/SuperChatSettings.vue | 2 +- .../autoaction/settings/TemplateSettings.vue | 68 +- src/client/store/autoAction/actionUtils.ts | 287 ++++ .../store/autoAction/expressionEvaluator.ts | 190 ++- .../store/autoAction/modules/autoReply.ts | 171 +- .../store/autoAction/modules/entryWelcome.ts | 86 +- .../store/autoAction/modules/followThank.ts | 67 +- .../store/autoAction/modules/giftThank.ts | 202 +-- .../store/autoAction/modules/guardPm.ts | 258 +-- .../autoAction/modules/scheduledDanmaku.ts | 41 +- .../autoAction/modules/superChatThank.ts | 79 + src/client/store/autoAction/types.ts | 107 +- src/client/store/autoAction/utils.ts | 126 +- src/client/store/useAutoAction.ts | 1476 ++++++++++------- src/client/store/useBiliFunction.ts | 44 +- src/components.d.ts | 1 + src/data/DanmakuClients/BaseDanmakuClient.ts | 6 + src/data/DanmakuClients/DirectClient.ts | 74 +- src/store/useDanmakuClient.ts | 2 +- src/views/AboutView.vue | 13 +- src/views/ManageLayout.vue | 2 - src/views/manage/DashboardView.vue | 7 +- tsconfig.json | 2 +- 39 files changed, 3955 insertions(+), 1959 deletions(-) create mode 100644 .cursorindexingignore create mode 100644 src/client/components/autoaction/DataManager.vue create mode 100644 src/client/components/autoaction/SingleTemplateEditor.vue create mode 100644 src/client/components/autoaction/TimerCountdown.vue create mode 100644 src/client/components/autoaction/settings/GlobalScheduledSettings.vue create mode 100644 src/client/store/autoAction/actionUtils.ts create mode 100644 src/client/store/autoAction/modules/superChatThank.ts diff --git a/.cursorindexingignore b/.cursorindexingignore new file mode 100644 index 0000000..68347b3 --- /dev/null +++ b/.cursorindexingignore @@ -0,0 +1,2 @@ +# Don't index SpecStory auto-save files, but allow explicit context inclusion via @ references +.specstory/** diff --git a/.gitignore b/.gitignore index 9805cf2..ac6d2a8 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ pnpm-debug.log* *.sln *.sw? env.d.ts +/.specstory diff --git a/src/api/api-models.ts b/src/api/api-models.ts index 21a0e4d..76b1557 100644 --- a/src/api/api-models.ts +++ b/src/api/api-models.ts @@ -558,7 +558,7 @@ export interface EventModel { time: number num: number price: number - guard_level: number + guard_level: GuardLevel fans_medal_level: number fans_medal_name: string fans_medal_wearing_status: boolean @@ -572,7 +572,8 @@ export enum EventDataTypes { Message, Like, SCDel, - Enter + Enter, + Follow } export interface ResponseQueueModel { id: number diff --git a/src/client/ClientAutoAction.vue b/src/client/ClientAutoAction.vue index dc2b226..f197411 100644 --- a/src/client/ClientAutoAction.vue +++ b/src/client/ClientAutoAction.vue @@ -1,6 +1,8 @@ + + + 部分需要发送弹幕或私信的自动操作(如自动回复、上舰感谢)将无法执行。请前往【设置】- 【账号设置】页面登录。 + + - { :tab="label" > - - {{ typeEnabledStatus[type] ? '启用' : '禁用' }}所有{{ label }} + {{ enabledTriggerTypes[type] ? '启用' : '禁用' }}所有{{ label }} - + + 当前连接模式 (OpenLive) 无法获取用户UID,因此无法执行【发送私信】操作。如需使用私信功能,请考虑切换至直连模式。 + + + + + + {{ `确认模拟一个 ${label} 事件来测试所有启用的 ${label} 操作吗?\n注意:这可能会发送真实的消息、执行操作,并可能触发B站风控限制。` }} + + + +
+ +
+ + + + + 下一个执行: + + {{ autoActionStore.nextScheduledAction?.name || '未命名操作' }} + + + + + 手动设置下一个要执行的操作 + + +
+ + 定时发送类型已被禁用,所有相关操作不会执行。 + +
{ -
{ - - + 添加{{ typeMap[type] }} + + 添加{{ typeMap[type as TriggerType] }}
-
{ :key="action.id" class="action-item" > -
@@ -521,11 +678,19 @@ onMounted(() => {
+ + + + + +
- { /> + + + +
选择下一个要执行的定时操作:
+ + + 只会列出当前已启用、类型也已启用且使用全局定时器的操作。 + 选择后,下一个全局定时周期将执行您指定的操作。 + +
+
+ + + +
请输入私信接收者的UID:
+ + + 这是接收私信消息的B站用户UID,测试将向此UID发送私信。请确保该UID有效且您有权限向其发送私信。 + +
+
@@ -579,6 +798,7 @@ code { .fade-leave-active { transition: opacity 0.3s ease; } + .fade-enter-from, .fade-leave-to { opacity: 0; @@ -588,15 +808,18 @@ code { .list-item { transition: all 0.3s ease; } + .list-enter-active, .list-leave-active { transition: all 0.3s ease; } + .list-enter-from, .list-leave-to { opacity: 0; transform: translateY(20px); } + .list-move { transition: transform 0.3s ease; } @@ -606,10 +829,12 @@ code { .fade-slide-leave-active { transition: all 0.3s ease; } + .fade-slide-enter-from { opacity: 0; transform: translateX(20px); } + .fade-slide-leave-to { opacity: 0; transform: translateX(-20px); @@ -619,6 +844,7 @@ code { .btn-with-transition { transition: all 0.2s ease; } + .btn-with-transition:hover { transform: translateY(-2px); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); @@ -629,6 +855,7 @@ code { position: relative; overflow: hidden; } + .back-btn::after { content: ''; position: absolute; @@ -639,6 +866,7 @@ code { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: left 0.5s ease; } + .back-btn:hover::after { left: 100%; } @@ -649,4 +877,12 @@ code { transition: all 0.4s ease; transform-origin: center top; } + +.next-action-display { + margin-top: 12px; + padding: 8px 12px; + background-color: var(--n-color-embedded); + border-radius: var(--n-border-radius); + font-size: 13px; +} \ No newline at end of file diff --git a/src/client/components/autoaction/AutoActionEditor.vue b/src/client/components/autoaction/AutoActionEditor.vue index 92622ea..9f29444 100644 --- a/src/client/components/autoaction/AutoActionEditor.vue +++ b/src/client/components/autoaction/AutoActionEditor.vue @@ -48,48 +48,48 @@ const TriggerSettings = getTriggerSettings(); diff --git a/src/client/components/autoaction/DataManager.vue b/src/client/components/autoaction/DataManager.vue new file mode 100644 index 0000000..73acb28 --- /dev/null +++ b/src/client/components/autoaction/DataManager.vue @@ -0,0 +1,352 @@ + + + + + \ No newline at end of file diff --git a/src/client/components/autoaction/SingleTemplateEditor.vue b/src/client/components/autoaction/SingleTemplateEditor.vue new file mode 100644 index 0000000..906c136 --- /dev/null +++ b/src/client/components/autoaction/SingleTemplateEditor.vue @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/src/client/components/autoaction/TemplateEditor.vue b/src/client/components/autoaction/TemplateEditor.vue index fa95ec5..580f4c0 100644 --- a/src/client/components/autoaction/TemplateEditor.vue +++ b/src/client/components/autoaction/TemplateEditor.vue @@ -1,14 +1,18 @@

{ {{ description }}

- + { > - - + - - - + + + + - + + + + - + + + {{ showLivePreview ? '隐藏预览' : '显示预览' }} + + + +
- -
- -
- JS -
-
+ 实时预览: + +
+
+
- - - 测试 - - - 编辑 - - - - 确定要删除这个模板吗? - - - -
-
-
- - - - - + - + + 占位符转表达式 + - - - - 转换为表达式 - - + + 测试模板 + + - - + + + +
- 取消 - - - {{ isEditing ? '保存' : '添加' }} - - - - - +

{{ category.title }}

+ + + {{ example.label }} + + +
+
+
+
+
- - - +
+ + + + + + 模板支持插入变量和执行 JavaScript。 + + 1. 简单变量替换:
+ 直接使用 {{ '\{\{变量名.属性\}\}' }} 插入值。
+ 示例: {{ '\{\{user.name\}\}' }} → 显示用户名 + + 2. JS 表达式求值 (js:):
+ 使用 {{ '\{\{js: 表达式\}\}' }} 执行单个 JS 表达式并插入结果 (隐式返回)。
+ 适合简单计算、字符串操作、三元运算等。
+ 示例: {{ '\{\{js: user.guardLevel > 0 ? "舰长" : "非舰长\}\}' }}
+ 示例: {{ '\{\{js: gift.price * gift.count\}\}' }} + + 3. JS 代码块执行 (js+:js-run:):
+ 使用 {{ '\{\{js+: 代码...\}\}' }}{{ '\{\{js-run: 代码...\}\}' }} 执行多行 JS 代码。
+ 需要显式使用 return 语句来指定输出到模板的值。
+ 适合需要临时变量、多步逻辑或调用 getData/setData 等函数的场景。
+
{{ '\{\{js+:\n  const count = (getData(\'greetCount\') || 0) + 1;\n  setData(\'greetCount\', count);\n  return \`这是第 ${count} 次问候!\`;\n\}\}' }}
+
+ + + + + 运行时数据仅在本次运行有效, 重启后就没了,且操作是同步的。 + +
    +
  • getData(key, defaultValue?): 获取运行时数据。
  • +
  • setData(key, value): 设置运行时数据。
  • +
  • containsData(key): 检查运行时数据是否存在。
  • +
  • removeData(key): 移除运行时数据。
  • +
+ + + + + 持久化数据会长期保留,但操作是异步的 (返回 Promise)。
+ 在 js+js-run 中使用 await 处理或使用 .then()。 +
+
    +
  • getStorageData(key, defaultValue?): 获取持久化数据 (异步)。
  • +
  • setStorageData(key, value): 设置持久化数据 (异步)。
  • +
  • hasStorageData(key): 检查持久化数据是否存在 (异步)。
  • +
  • removeStorageData(key): 移除持久化数据 (异步)。
  • +
  • clearStorageData(): 清除所有用户持久化数据 (异步)。
  • +
+
{{ '\{\{js+:\n  // 异步获取并设置持久化数据\n  const key = \`user:${user.uid}:visitCount\`;\n  const count = (await getStorageData(key, 0)) + 1;\n  await setStorageData(key, count);\n  return \`你是第 ${count} 次访问!\`;\n\}\}' }}
+
+
+
+ 可用变量 (基础): + +
+ + {{ ph.name }} + : {{ ph.description }} +
+
+
+ diff --git a/src/client/components/autoaction/TemplateTester.vue b/src/client/components/autoaction/TemplateTester.vue index 900fac9..bfc64eb 100644 --- a/src/client/components/autoaction/TemplateTester.vue +++ b/src/client/components/autoaction/TemplateTester.vue @@ -46,6 +46,9 @@ import { ref, computed } from 'vue'; import { NSpace, NInput, NInputGroup, NInputGroupLabel, NButton, useMessage, NDivider } from 'naive-ui'; import { evaluateTemplateExpressions } from '@/client/store/autoAction/expressionEvaluator'; +import { EventModel } from '@/api/api-models'; +import { TriggerType } from '@/client/store/autoAction/types'; +import { buildExecutionContext } from '@/client/store/autoAction/utils'; const props = defineProps({ defaultTemplate: { @@ -63,9 +66,14 @@ const result = ref(''); const hasResult = computed(() => result.value !== ''); const message = useMessage(); +function evaluateTemplateForUI(template: string, contextObj: Record): string { + const tempContext = buildExecutionContext(contextObj, undefined, TriggerType.DANMAKU); + return evaluateTemplateExpressions(template, tempContext); +} + function testTemplate() { try { - result.value = evaluateTemplateExpressions(template.value, props.context); + result.value = evaluateTemplateForUI(template.value, props.context); } catch (error) { message.error(`表达式求值错误: ${(error as Error).message}`); result.value = `[错误] ${(error as Error).message}`; diff --git a/src/client/components/autoaction/TimerCountdown.vue b/src/client/components/autoaction/TimerCountdown.vue new file mode 100644 index 0000000..e71f229 --- /dev/null +++ b/src/client/components/autoaction/TimerCountdown.vue @@ -0,0 +1,151 @@ + + + \ No newline at end of file diff --git a/src/client/components/autoaction/settings/AdvancedSettings.vue b/src/client/components/autoaction/settings/AdvancedSettings.vue index 8a7448a..53f916e 100644 --- a/src/client/components/autoaction/settings/AdvancedSettings.vue +++ b/src/client/components/autoaction/settings/AdvancedSettings.vue @@ -1,7 +1,8 @@