feat: 更新项目配置和依赖,增强功能和用户体验

- 完成弹幕机功能
- 在 .editorconfig 中新增对 vine.ts 文件的支持。
- 更新 package.json 中多个依赖的版本,提升稳定性和性能。
- 在 vite.config.mts 中引入 @guolao/vue-monaco-editor 插件,增强代码编辑功能。
- 在 App.vue 中调整内容填充的样式,优化界面布局。
- 新增获取配置文件哈希的 API 方法,提升配置管理能力。
- 在多个组件中优化了样式和逻辑,提升用户交互体验。
This commit is contained in:
2025-04-25 00:08:06 +08:00
parent b24974540f
commit 07948e6777
36 changed files with 3108 additions and 1258 deletions

View File

@@ -508,8 +508,26 @@ onMounted(() => {
v-for="(label, type) in typeMap"
:key="type"
:name="type"
:tab="label"
>
<template #tab>
<NSpace
align="center"
size="small"
inline
>
{{ label }}
<span
:style="{
color: enabledTriggerTypes && enabledTriggerTypes[type] ? '#18a058' : '#d03050',
fontSize: '14px', // Adjust size as needed
verticalAlign: 'middle'
}"
:title="enabledTriggerTypes && enabledTriggerTypes[type] ? '已启用' : '已禁用'"
>
</span>
</NSpace>
</template>
<NSpace vertical>
<NSpace
v-if="enabledTriggerTypes"

View File

@@ -30,6 +30,7 @@ export function filterValidActions(
options?: {
actionType?: ActionType; // 特定操作类型
customFilter?: (action: AutoActionItem) => boolean; // 自定义过滤器
enabledTriggerTypes?: Ref<Record<TriggerType, boolean>> // 触发类型启用状态
}
): AutoActionItem[] {
return actions.filter(action => {
@@ -38,6 +39,11 @@ export function filterValidActions(
return false;
}
// 检查触发类型是否启用
if (options?.enabledTriggerTypes && !options.enabledTriggerTypes.value[triggerType]) {
return false;
}
// 直播状态过滤
if (action.triggerConfig.onlyDuringLive && !isLive.value) {
return false;
@@ -146,6 +152,38 @@ export function processTemplate(
}
}
// 辅助函数:发送弹幕并记录日志
async function sendAndLogDanmaku(
sendHandler: (roomId: number, message: string) => Promise<boolean>,
action: AutoActionItem,
roomId: number,
message: string
): Promise<boolean> {
try {
const success = await sendHandler(roomId, message);
logDanmakuHistory(
action.id,
action.name || '未命名操作',
message,
roomId,
success,
success ? undefined : '发送失败'
).catch(err => console.error('记录弹幕历史失败:', err));
return success;
} catch (err) {
console.error(`[AutoAction] 发送弹幕失败 (${action.name || action.id}):`, err);
logDanmakuHistory(
action.id,
action.name || '未命名操作',
message,
roomId,
false,
err instanceof Error ? err.toString() : String(err) // 确保err是字符串
).catch(e => console.error('记录弹幕历史失败:', e));
return false;
}
}
/**
* 执行操作的通用函数
* @param actions 过滤后的操作列表
@@ -220,61 +258,13 @@ export function executeActions(
// 更新冷却时间
runtimeState.lastExecutionTime[action.id] = Date.now();
const sendAction = () => sendAndLogDanmaku(handlers.sendLiveDanmaku!, action, roomId, message);
// 延迟发送
if (action.actionConfig.delaySeconds && action.actionConfig.delaySeconds > 0) {
setTimeout(() => {
handlers.sendLiveDanmaku!(roomId, message)
.then(success => {
// 记录弹幕发送历史
logDanmakuHistory(
action.id,
action.name || '未命名操作',
message,
roomId,
success,
success ? undefined : '发送失败'
).catch(err => console.error('记录弹幕历史失败:', err));
return success;
})
.catch(err => {
console.error(`[AutoAction] 发送弹幕失败 (${action.name || action.id}):`, err);
// 记录失败的发送
logDanmakuHistory(
action.id,
action.name || '未命名操作',
message,
roomId,
false,
err.toString()
).catch(e => console.error('记录弹幕历史失败:', e));
});
}, action.actionConfig.delaySeconds * 1000);
setTimeout(sendAction, action.actionConfig.delaySeconds * 1000);
} else {
handlers.sendLiveDanmaku(roomId, message)
.then(success => {
// 记录弹幕发送历史
logDanmakuHistory(
action.id,
action.name || '未命名操作',
message,
roomId,
success,
success ? undefined : '发送失败'
).catch(err => console.error('记录弹幕历史失败:', err));
return success;
})
.catch(err => {
console.error(`[AutoAction] 发送弹幕失败 (${action.name || action.id}):`, err);
// 记录失败的发送
logDanmakuHistory(
action.id,
action.name || '未命名操作',
message,
roomId,
false,
err.toString()
).catch(e => console.error('记录弹幕历史失败:', e));
});
sendAction();
}
}
} else {
@@ -321,7 +311,7 @@ export function executeActions(
msg,
uid,
false,
err.toString()
err instanceof Error ? err.toString() : String(err) // 确保err是字符串
).catch(e => console.error('记录私信历史失败:', e));
return false; // 明确返回 false 表示失败
});

View File

@@ -28,19 +28,21 @@ import {
createDefaultRuntimeState
} from './autoAction/utils';
import { evaluateTemplateExpressions } from './autoAction/expressionEvaluator';
// 导入 actionUtils 工具函数
import { filterValidActions, checkUserFilters, checkCooldown, processTemplate, executeActions } from './autoAction/actionUtils';
// 导入 nanoid 用于生成唯一 ID
import { nanoid } from 'nanoid';
// 导入开发环境判断标志
import { isDev } from '@/data/constants.js';
// 导入所有自动操作子模块
import { useGiftThank } from './autoAction/modules/giftThank.js';
import { useGuardPm } from './autoAction/modules/guardPm.js';
import { useFollowThank } from './autoAction/modules/followThank.js';
import { useEntryWelcome } from './autoAction/modules/entryWelcome.js';
import { useAutoReply } from './autoAction/modules/autoReply.js';
import { useScheduledDanmaku } from './autoAction/modules/scheduledDanmaku.js';
import { useSuperChatThank } from './autoAction/modules/superChatThank.js';
import { useGiftThank } from './autoAction/modules/giftThank';
import { useGuardPm } from './autoAction/modules/guardPm';
import { useFollowThank } from './autoAction/modules/followThank';
import { useEntryWelcome } from './autoAction/modules/entryWelcome';
import { useAutoReply } from './autoAction/modules/autoReply';
import { useScheduledDanmaku } from './autoAction/modules/scheduledDanmaku';
import { useSuperChatThank } from './autoAction/modules/superChatThank';
// 定义名为 'autoAction' 的 Pinia store
export const useAutoAction = defineStore('autoAction', () => {
@@ -540,38 +542,6 @@ export const useAutoAction = defineStore('autoAction', () => {
// 定时检查天选状态 (每5分钟)
const tianXuanTimer = setInterval(checkTianXuanStatus, 5 * 60 * 1000);
/**
* 判断是否应处理某个操作项 (基于事件和配置)
* @param action 操作项配置
* @param event 可选的事件数据
* @returns 是否应该处理
*/
function shouldProcessAction(action: AutoActionItem, event?: EventModel | null): boolean {
if (!action.enabled) return false; // 未启用则跳过
if (!enabledTriggerTypes.value[action.triggerType]) return false; // 触发类型未启用则跳过
// 检查模板是否为空 (添加新的检查)
if (!action.template || action.template.trim() === '') {
console.warn(`[AutoAction] 跳过操作 "${action.name}":未设置有效模板`);
return false;
}
// 根据配置检查条件
if (action.triggerConfig.onlyDuringLive && !isLive.value) return false; // 仅直播时
if (action.triggerConfig.ignoreTianXuan && isTianXuanActive.value) return false; // 忽略天选时
// 用户过滤条件
if (event && action.triggerConfig.userFilterEnabled) {
if (action.triggerConfig.requireMedal && !event.fans_medal_wearing_status) return false; // 要求粉丝牌
if (action.triggerConfig.requireCaptain && event.guard_level === GuardLevel.None) return false; // 要求舰长
}
// 逻辑表达式判断
if (action.logicalExpression && event) {
const context = buildExecutionContext(event, roomId.value, action.triggerType);
if (!evaluateExpression(action.logicalExpression, context)) return false; // 表达式不满足
}
return true; // 所有条件满足
}
/**
* 处理接收到的事件
* @param event 事件数据
@@ -579,10 +549,8 @@ export const useAutoAction = defineStore('autoAction', () => {
*/
function processEvent(event: EventModel, triggerType: TriggerType) {
if (!roomId.value) return; // 房间 ID 无效则跳过
// 检查触发类型是否启用
if (!enabledTriggerTypes.value[triggerType]) return;
// 根据触发类型调用相应模块的处理函数
switch (triggerType) {
case TriggerType.DANMAKU: