feat(ActivitySwitchNotice): 添加新活动通知功能 (#2831)

* 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相关的活动数据
- 更新活动配置文件写入逻辑,支持多用户数据分离存储
- 优化新增活动检测机制,基于用户历史活动进行精确匹配
- 重构活动数据序列化处理,确保数据格式兼容性和持久化
This commit is contained in:
云端客
2026-02-02 07:27:12 +08:00
committed by GitHub
parent 4e9e1c0905
commit ecc2de529a
5 changed files with 68 additions and 8 deletions

View File

@@ -511,6 +511,8 @@ ActivitySwitchNotice/
## 版本历史
### 0.1.0 (2026-02-01)
- 新增 新活动通知(存储活动名称列表-历史对比)
### 0.0.8 (2026-01-22)
- 新增 地图识别任务提醒 如:

View File

@@ -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)
}

View File

@@ -1,6 +1,6 @@
{
"name": "活动期限/周本通知器",
"version": "0.0.8",
"version": "0.1.0",
"description": "",
"settings_ui": "settings.json",
"main": "main.js",

View File

@@ -19,6 +19,12 @@
{
"type": "separator"
},
{
"name": "newActivityNotice",
"type": "checkbox",
"label": "启用新活动通知",
"default": true
},
{
"label": "地图识别任务提醒",
"type": "multi-checkbox",

View File

@@ -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 = {