prompt: 前端H5应用中,有一个每日签到提醒的投承场景,提醒的UI有3种形式,弹窗、小黄条提醒、toast,签到奖励又会有3种,但是最终只会汇总成一个提醒展示,请从数据驱动的角度,批量系统的处理以上功能,比如策略模式,或者更优秀的算法与数据结构处理方案
以下是基于数据驱动的每日签到提醒优先级管理方案,结合策略模式、优先级队列与状态机,实现高效且可扩展的提醒处理系统:
一、数据结构设计
1. 提醒规则配置表(JSON Schema)
// 优先级规则配置
const priorityRules = [
{
rewardType: 'vip', // 奖励类型:vip/金币/道具
conditions: { // 触发条件
isFirstLogin: true, // 是否当日首次登录
rewardValue: { min: 50 } // 奖励值阈值
},
uiType: '弹窗', // 对应UI类型
priority: 1 // 优先级(数值越小优先级越高)
},
{
rewardType: '金币',
conditions: { rewardValue: { min: 100 } },
uiType: '小黄条',
priority: 2
},
// ...其他规则
];
// 用户签到状态数据模型
class SignState {
constructor() {
this.rewards = []; // 待领取奖励列表
this.lastShownType = null; // 上次展示的UI类型
this.lastShownTime = 0; // 上次展示时间戳
}
}
二、核心算法与策略模式
1. 策略选择器(Strategy Selector)
class ReminderStrategy {
// 策略接口
getReminder(reward) {
throw new Error('需实现策略方法');
}
}
// 具体策略类
class PopupStrategy extends ReminderStrategy {
getReminder(reward) {
return { type: '弹窗', content: reward.detail };
}
}
class ToastStrategy extends ReminderStrategy {
getReminder(reward) {
return { type: 'toast', content: reward.summary };
}
}
// 策略工厂(根据规则动态选择)
class StrategyFactory {
static createStrategy(rule) {
switch (rule.uiType) {
case '弹窗': return new PopupStrategy();
case '小黄条': return new YellowBarStrategy();
default: return new ToastStrategy();
}
}
}
2. 优先级队列处理
class PriorityQueue {
constructor() {
this.queue = [];
}
// 插入并排序(O(n)复杂度,适合小规模数据)
enqueue(item) {
let added = false;
for (let i = 0; i < this.queue.length; i++) {
if (item.priority < this.queue[i].priority) {
this.queue.splice(i, 0, item);
added = true;
break;
}
}
if (!added) this.queue.push(item);
}
dequeue() {
return this.queue.shift();
}
}
// 使用示例
const queue = new PriorityQueue();
rewards.forEach(reward => {
const matchedRule = findMatchingRule(reward); // 匹配规则
queue.enqueue({
...reward,
strategy: StrategyFactory.createStrategy(matchedRule),
priority: matchedRule.priority
});
});
三、状态驱动流程控制
1. 状态机管理(避免重复提醒)
class ReminderStateMachine {
constructor() {
this.state = new SignState();
}
// 状态转移判断
shouldShow(reminderType) {
const now = Date.now();
const cooldown = this.getCooldown(reminderType);
return now - this.state.lastShownTime > cooldown &&
this.state.lastShownType !== reminderType;
}
getCooldown(type) {
// 定义不同UI类型的冷却时间(ms)
const cooldowns = { '弹窗': 3600000, '小黄条': 1800000, 'toast': 0 };
return cooldowns[type] || 0;
}
}
2. 批量处理流程
function processReminders(rewards) {
const stateMachine = new ReminderStateMachine();
const queue = new PriorityQueue();
// 1. 规则匹配与入队
rewards.forEach(reward => {
const rule = priorityRules.find(r =>
r.rewardType === reward.type &&
checkConditions(r.conditions, reward)
);
if (rule) queue.enqueue({ reward, rule });
});
// 2. 优先级出队处理
while (!queue.isEmpty()) {
const { reward, rule } = queue.dequeue();
const strategy = StrategyFactory.createStrategy(rule);
if (stateMachine.shouldShow(rule.uiType)) {
const reminder = strategy.getReminder(reward);
showReminder(reminder);
stateMachine.updateState(rule.uiType);
break; // 只展示最高优先级
}
}
}
四、性能优化补充
-
规则预编译
使用Web Worker
预加载规则配置,将条件判断转换为JS函数:// 条件预编译示例 function compileCondition(condition) { const code = Object.entries(condition) .map(([key, val]) => `reward.${key} >= ${val.min}`) .join(' && '); return new Function('reward', `return ${code}`); }
-
缓存策略
对频繁触发的奖励类型增加缓存层,使用LRU算法管理:class ReminderCache { constructor(maxSize = 10) { this.cache = new Map(); this.maxSize = maxSize; } getKey(reward) { return `${reward.type}_${reward.value}`; } get(reward) { const key = this.getKey(reward); if (this.cache.has(key)) { const item = this.cache.get(key); this.cache.delete(key); this.cache.set(key, item); // 刷新为最近使用 return item; } return null; } }
五、扩展性设计
-
动态规则加载
通过接口获取远程配置,支持热更新:async function loadRules() { const response = await fetch('/api/reminder-rules'); priorityRules = await response.json(); // 更新时重新初始化策略工厂 StrategyFactory.init(priorityRules); }
-
AB测试支持
在规则中增加实验分组字段,动态分配UI类型:{ "rewardType": "金币", "experiment": { "groups": [ { "name": "A组", "uiType": "弹窗", "weight": 0.2 }, { "name": "B组", "uiType": "小黄条", "weight": 0.8 } ] } }
总结
该方案通过策略模式+优先级队列实现提醒决策,结合状态机控制展示频率,具备以下优势:
- 数据驱动:规则配置与业务逻辑解耦,支持动态调整
- 高效处理:优先级队列确保O(n)时间复杂度
- 可扩展性:新增UI类型只需添加策略类与规则配置
- 稳定性:状态机防止过度打扰用户
实际开发中可结合埋点监控(如记录规则匹配率、用户点击率)持续优化优先级策略。