From ecc2de529a765fd98a7acb94932a658375ca4293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E7=AB=AF=E5=AE=A2?= <107686912+Kirito520Asuna@users.noreply.github.com> Date: Mon, 2 Feb 2026 07:27:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(ActivitySwitchNotice):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=96=B0=E6=B4=BB=E5=8A=A8=E9=80=9A=E7=9F=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=20(#2831)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(ActivitySwitchNotice): 添加新活动通知功能 - 新增配置文件路径定义用于存储活动数据 - 在activityMain函数中添加newActivityNotice参数控制新活动通知 - 读取历史活动配置文件并转换为Set进行对比 - 创建activityNameSet记录当前页面活动名称 - 修复OCR键值获取中的参数传递格式问题 - 实现新活动检测逻辑并与历史数据进行比较 - 添加新活动通知发送功能包括UID识别 - 更新版本号从0.0.8到0.1.0并在README中记录变更 - 在设置界面添加新活动通知的启用开关选项 * feat(ActivitySwitchNotice): 更新活动主函数调用以支持新活动通知设置 - 修改 activityMain 函数调用,传入 settings.newActivityNotice 参数 - 实现新活动通知功能的配置支持 * feat(ActivitySwitchNotice): 优化活动通知逻辑并修复数据处理问题 - 在遍历活动列表时同步更新 activityNameSet 集合 - 注释掉冗余的数组合并操作避免重复数据处理 - 重构新增活动检测逻辑提高代码可读性 - 优化通知发送后的配置文件更新时机确保数据一致性 - 改进错误处理机制并添加调试日志 - 修复当无新增活动时不执行通知发送的逻辑分支 * feat(ActivitySwitchNotice): 实现基于UID的个性化活动数据管理 - 添加UID识别功能,通过uidUtil.ocrUID()获取用户唯一标识 - 修改活动数据结构,将全局活动集合改为按UID分类存储 - 实现用户特定活动过滤,只处理当前UID相关的活动数据 - 更新活动配置文件写入逻辑,支持多用户数据分离存储 - 优化新增活动检测机制,基于用户历史活动进行精确匹配 - 重构活动数据序列化处理,确保数据格式兼容性和持久化 --- repo/js/ActivitySwitchNotice/README.md | 2 + repo/js/ActivitySwitchNotice/main.js | 2 +- repo/js/ActivitySwitchNotice/manifest.json | 2 +- repo/js/ActivitySwitchNotice/settings.json | 6 ++ .../js/ActivitySwitchNotice/utils/activity.js | 64 +++++++++++++++++-- 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/repo/js/ActivitySwitchNotice/README.md b/repo/js/ActivitySwitchNotice/README.md index 48082b3a1..368d99083 100644 --- a/repo/js/ActivitySwitchNotice/README.md +++ b/repo/js/ActivitySwitchNotice/README.md @@ -511,6 +511,8 @@ ActivitySwitchNotice/ ## 版本历史 +### 0.1.0 (2026-02-01) +- 新增 新活动通知(存储活动名称列表-历史对比) ### 0.0.8 (2026-01-22) - 新增 地图识别任务提醒 如: diff --git a/repo/js/ActivitySwitchNotice/main.js b/repo/js/ActivitySwitchNotice/main.js index 0d1b43508..4539e11eb 100644 --- a/repo/js/ActivitySwitchNotice/main.js +++ b/repo/js/ActivitySwitchNotice/main.js @@ -170,5 +170,5 @@ async function main() { await campaignAreaUtil.campaignAreaMain(openKey) await sleep(ms * 2); await toMainUi() - await activityUtil.activityMain() + await activityUtil.activityMain(settings.newActivityNotice) } \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/manifest.json b/repo/js/ActivitySwitchNotice/manifest.json index 778adb2f4..d5c8183c0 100644 --- a/repo/js/ActivitySwitchNotice/manifest.json +++ b/repo/js/ActivitySwitchNotice/manifest.json @@ -1,6 +1,6 @@ { "name": "活动期限/周本通知器", - "version": "0.0.8", + "version": "0.1.0", "description": "", "settings_ui": "settings.json", "main": "main.js", diff --git a/repo/js/ActivitySwitchNotice/settings.json b/repo/js/ActivitySwitchNotice/settings.json index 6c3b5de11..c24c0f58b 100644 --- a/repo/js/ActivitySwitchNotice/settings.json +++ b/repo/js/ActivitySwitchNotice/settings.json @@ -19,6 +19,12 @@ { "type": "separator" }, + { + "name": "newActivityNotice", + "type": "checkbox", + "label": "启用新活动通知", + "default": true + }, { "label": "地图识别任务提醒", "type": "multi-checkbox", diff --git a/repo/js/ActivitySwitchNotice/utils/activity.js b/repo/js/ActivitySwitchNotice/utils/activity.js index 44e1488f3..2b3a8aa75 100644 --- a/repo/js/ActivitySwitchNotice/utils/activity.js +++ b/repo/js/ActivitySwitchNotice/utils/activity.js @@ -1,3 +1,8 @@ +const config_name = "config" +const json_path = { + activity: `${config_name}/activity.json` +} + function settingsParseInt(str, defaultValue) { try { return str ? parseInt('' + str) : defaultValue; @@ -440,10 +445,21 @@ async function init() { /** * 活动主函数:扫描所有活动页面,识别剩余时间,最后统一发送通知 */ -async function activityMain() { +async function activityMain(newActivityNotice = true) { await init(); const ms = 1000; await sleep(ms); + let uid = await uidUtil.ocrUID() + let activityData=[] + let activitySetLast = new Set() + try { + // 读取活动配置文件并转换为Set + activityData = JSON.parse(file.readTextSync(json_path.activity)); + const uidActivity = (Array.isArray(activityData) ? activityData : []).filter(item => item?.uid === uid).find(item => item) + activitySetLast = new Set(uidActivity.activityNames); + } catch (e) { + log.warn(`error:{1}`, e.message) + } // 1. 打开活动页面(默认 F5) await keyPress(config.activityKey); @@ -456,7 +472,7 @@ async function activityMain() { } catch (e) { log.warn("回到顶部失败,但继续尝试执行"); } - + // let activityNameSet = new Set() // 3. 初始化存储所有活动的 Map let activityMap = new Map(); // key: 活动名称, value: 剩余时间文本 let previousPageActivities = new Set(); // 新增:记录上一页识别到的所有活动名称(用于重复页判断) @@ -466,7 +482,7 @@ async function activityMain() { let scannedPages = 0; const maxPages = 25; // 防止意外死循环的安全上限 let sameBottomCountMax = 1; // 连续相同底部活动名的最大次数 - + let currentActivityJson = {uid: uid, activityNames: new Set()} // 4. 主循环:逐页向下扫描 while (scannedPages < maxPages) { scannedPages++; @@ -494,8 +510,10 @@ async function activityMain() { } // ============ 新增:提前判断是否为重复页 ============ const currentPageNames = new Set(); + for (let res of resList) { currentPageNames.add(res.text.trim()); + currentActivityJson?.activityNames?.add(res.text.trim()); } // 计算与上一页的重合率 @@ -520,6 +538,9 @@ async function activityMain() { let currentPageBottomName = null; // 本页最下面的活动名 let newActivityCountThisPage = 0; + // const newActivityNames = new Set(Array.from(resList).map(item => item.text.trim())); + // activityNameSet = [...activityNameSet, ...currentPageNames]; + // 遍历当前页所有识别到的活动条目 for (let res of resList) { const activityName = res.text.trim(); @@ -537,7 +558,7 @@ async function activityMain() { let matched = config.blackActivityNameList.some(keyword => activityName.includes(keyword)); if (matched) { // 获取黑名单活动的条件配置 - let blackActivityConditions = getMapByKey(config.blackActivityMap, activityName,true); + let blackActivityConditions = getMapByKey(config.blackActivityMap, activityName, true); log.info(`[黑名单条件检测]blackActivityMap:{blackActivityMap},activityName:{activityName},blackActivityConditions:{blackActivityConditions}`, config.blackActivityMap, activityName, blackActivityConditions); if (blackActivityConditions && blackActivityConditions.length > 0) { @@ -546,7 +567,7 @@ async function activityMain() { // 遍历所有条件,检查是否满足黑名单条件 for (const blackActivityCondition of blackActivityConditions) { try { - let condition = await OcrKey(activityName,blackActivityCondition); + let condition = await OcrKey(activityName, blackActivityCondition); if (condition) { log.info(`满足黑名单条件==>{ac}->{ba}`, activityName, blackActivityCondition); matched = true; @@ -679,7 +700,6 @@ async function activityMain() { } // 7. 全部扫描完毕,统一发送通知(只发一次!) if (activityMapFilter.size > 0) { - let uid = await uidUtil.ocrUID() log.info(`扫描完成,共记录 {activityMap.size} 个活动,即将发送通知`, activityMapFilter.size); // 构建通知标题,根据配置显示剩余时间阈值和白名单活动信息 let titleKey = `[ `; @@ -708,6 +728,38 @@ async function activityMain() { } else { log.warn("不存在符合条件的活动,未发送通知"); } + //新活动通知 + if (newActivityNotice) { + // 计算新增活动 + const newActivities = [...currentActivityJson.activityNames].filter(activity => !activitySetLast.has(activity)); + + if (newActivities.length > 0 ) { + try { + if(activitySetLast.size > 0){ + log.info("新增活动: {newActivities}", newActivities); + await noticeUtil.sendText(newActivities.join("\n"), `UID:${uid}\n新增活动`); + } + activityData=activityData.filter(item => item.uid !== uid) + activityData.push(currentActivityJson) + // 确保所有数据都转换为可序列化格式 + const finalSerializableData = activityData.map(item => ({ + ...item, + activityNames: Array.isArray(item.activityNames) ? + item.activityNames : + [...(item.activityNames || [])] + })); + // 发送成功后更新配置文件 + file.writeTextSync(json_path.activity, JSON.stringify(finalSerializableData)); + log.debug("活动配置文件已更新"); + + } catch (e) { + log.error(`发送新增活动通知失败: {message}`, {message: e.message}); + // 即使发送失败也记录错误,但不更新配置文件以保持一致性 + } + } else { + log.debug("无新增活动"); + } + } } this.activityUtil = {