// ==UserScript==
// @name Microsoft Rewards 自动搜索助手
// @name:en Microsoft Rewards Auto Searcher
// @namespace WretchedSniper
// @version 1.0.0
// @description 自动完成 Microsoft Rewards 在必应(Bing)上的每日搜索任务,带有可配置的UI界面,模拟人工操作以提高安全性。
// @description:en Automatically completes Microsoft Rewards daily search tasks on Bing. Features a configurable UI and mimics human behavior for better safety.
// @author WretchedSniper
// @match *://*.bing.com/*
// @grant none
// @run-at document-end
// @license MIT
// @icon https://www.bing.com/favicon.ico
// ==/UserScript==
(function () {
'use strict';
// 存储搜索词和当前进度
let mainPageSearchTerms = []; // 主页面搜索词
let iframeSearchTerms = []; // iframe搜索词
let usedSearchTerms = []; // 已使用的搜索词
let currentProgress = {
current: 0,
total: 0,
lastChecked: 0, // 上次检查时的进度
completed: false, // 任务是否已完成
noProgressCount: 0 // 连续未增加进度的次数
};
let isSearching = false;
let countdownTimer = null;
// 配置参数
const config = {
restTime: 5 * 60, // 无进度时休息时间(秒)
scrollTime: 10, // 滚动时间(秒)
waitTime: 10, // 获取进度后等待时间(秒)
searchInterval: [5, 10], // 搜索间隔范围(秒)
debug: true, // 调试模式
maxNoProgressCount: 3 // 连续多少次不增加分数才休息
};
// 工作状态
const searchState = {
currentAction: 'idle', // 当前动作:idle, searching, scrolling, checking, waiting, resting
countdown: 0, // 倒计时
needRest: false // 是否需要休息
};
// 创建UI控件
function createUI() {
const container = document.createElement('div');
container.id = 'rewards-helper-container';
container.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background-color: white;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
z-index: 10000;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
width: 300px;
`;
const header = document.createElement('div');
header.style.cssText = `
font-weight: bold;
margin-bottom: 10px;
border-bottom: 1px solid #ddd;
padding-bottom: 5px;
display: flex;
justify-content: space-between;
`;
header.textContent = 'Microsoft Rewards 助手';
const closeBtn = document.createElement('span');
closeBtn.textContent = '×';
closeBtn.style.cssText = `
cursor: pointer;
font-size: 18px;
`;
closeBtn.onclick = function () {
container.style.display = 'none';
};
header.appendChild(closeBtn);
const content = document.createElement('div');
content.id = 'rewards-helper-content';
content.style.cssText = `
margin-bottom: 10px;
`;
const progress = document.createElement('div');
progress.id = 'rewards-progress';
progress.textContent = '进度: 加载中...';
content.appendChild(progress);
const searchStatus = document.createElement('div');
searchStatus.id = 'search-status';
searchStatus.style.cssText = `
margin-top: 5px;
font-style: italic;
`;
content.appendChild(searchStatus);
const countdown = document.createElement('div');
countdown.id = 'countdown';
countdown.style.cssText = `
margin-top: 5px;
font-weight: bold;
color: #0078d4;
`;
content.appendChild(countdown);
// 添加调试日志区域
const debugLog = document.createElement('div');
debugLog.id = 'debug-log';
debugLog.style.cssText = `
margin-top: 5px;
font-size: 12px;
color: #666;
max-height: 80px;
overflow-y: auto;
border-top: 1px dashed #ccc;
padding-top: 5px;
display: ${config.debug ? 'block' : 'none'};
`;
content.appendChild(debugLog);
const searchTermsContainer = document.createElement('div');
searchTermsContainer.style.cssText = `
margin-top: 10px;
max-height: 200px;
overflow-y: auto;
`;
const mainTermsTitle = document.createElement('div');
mainTermsTitle.textContent = '主页面搜索词:';
mainTermsTitle.style.fontWeight = 'bold';
searchTermsContainer.appendChild(mainTermsTitle);
const mainTerms = document.createElement('div');
mainTerms.id = 'main-search-terms';
mainTerms.style.cssText = `
margin-bottom: 10px;
padding-left: 10px;
`;
searchTermsContainer.appendChild(mainTerms);
const iframeTermsTitle = document.createElement('div');
iframeTermsTitle.textContent = 'iframe中的搜索词:';
iframeTermsTitle.style.fontWeight = 'bold';
searchTermsContainer.appendChild(iframeTermsTitle);
const iframeTerms = document.createElement('div');
iframeTerms.id = 'iframe-search-terms';
iframeTerms.style.cssText = `
padding-left: 10px;
`;
searchTermsContainer.appendChild(iframeTerms);
content.appendChild(searchTermsContainer);
const configSection = document.createElement('div');
configSection.style.cssText = `
margin-top: 10px;
border-top: 1px solid #ddd;
padding-top: 10px;
`;
const configTitle = document.createElement('div');
configTitle.textContent = '配置参数:';
configTitle.style.fontWeight = 'bold';
configSection.appendChild(configTitle);
const configForm = document.createElement('div');
configForm.style.cssText = `
display: grid;
grid-template-columns: auto auto;
gap: 5px;
margin-top: 5px;
`;
// 添加休息时间配置
configForm.innerHTML += `
<label for="rest-time">休息时间(分):</label>
<input type="number" id="rest-time" value="${config.restTime / 60}" min="1" max="30" style="width: 50px;">
<label for="scroll-time">滚动时间(秒):</label>
<input type="number" id="scroll-time" value="${config.scrollTime}" min="3" max="30" style="width: 50px;">
<label for="wait-time">等待时间(秒):</label>
<input type="number" id="wait-time" value="${config.waitTime}" min="3" max="30" style="width: 50px;">
<label for="max-no-progress">容错次数:</label>
<input type="number" id="max-no-progress" value="${config.maxNoProgressCount}" min="1" max="10" style="width: 50px;">
<label for="debug-mode">调试模式:</label>
<input type="checkbox" id="debug-mode" ${config.debug ? 'checked' : ''}>
`;
configSection.appendChild(configForm);
// 添加输入框变化事件监听
setTimeout(() => {
const restTimeInput = document.getElementById('rest-time');
const scrollTimeInput = document.getElementById('scroll-time');
const waitTimeInput = document.getElementById('wait-time');
const maxNoProgressInput = document.getElementById('max-no-progress');
const debugModeInput = document.getElementById('debug-mode');
if (restTimeInput) {
restTimeInput.addEventListener('change', () => {
const restTime = parseInt(restTimeInput.value) || 5;
config.restTime = restTime * 60;
updateStatus('休息时间已更新: ' + restTime + '分钟');
});
}
if (scrollTimeInput) {
scrollTimeInput.addEventListener('change', () => {
const scrollTime = parseInt(scrollTimeInput.value) || 10;
config.scrollTime = scrollTime;
updateStatus('滚动时间已更新: ' + scrollTime + '秒');
});
}
if (waitTimeInput) {
waitTimeInput.addEventListener('change', () => {
const waitTime = parseInt(waitTimeInput.value) || 10;
config.waitTime = waitTime;
updateStatus('等待时间已更新: ' + waitTime + '秒');
});
}
if (maxNoProgressInput) {
maxNoProgressInput.addEventListener('change', () => {
const maxNoProgressCount = parseInt(maxNoProgressInput.value) || 3;
config.maxNoProgressCount = maxNoProgressCount;
updateStatus('容错次数已更新: ' + maxNoProgressCount + '次');
});
}
if (debugModeInput) {
debugModeInput.addEventListener('change', () => {
config.debug = debugModeInput.checked;
document.getElementById('debug-log').style.display = config.debug ? 'block' : 'none';
updateStatus('调试模式: ' + (config.debug ? '开启' : '关闭'));
});
}
}, 1000);
content.appendChild(configSection);
const buttonsContainer = document.createElement('div');
buttonsContainer.style.cssText = `
display: flex;
justify-content: center;
margin-top: 10px;
`;
const startSearchBtn = document.createElement('button');
startSearchBtn.id = 'start-search-btn';
startSearchBtn.textContent = '开始自动搜索';
startSearchBtn.style.cssText = `
padding: 5px 10px;
cursor: pointer;
background-color: #0078d4;
color: white;
border: none;
border-radius: 3px;
width: 100%;
`;
startSearchBtn.onclick = function () {
if (!isSearching) {
startAutomatedSearch();
} else {
stopAutomatedSearch();
}
};
buttonsContainer.appendChild(startSearchBtn);
container.appendChild(header);
container.appendChild(content);
container.appendChild(buttonsContainer);
document.body.appendChild(container);
}
// 更新状态显示
function updateStatus(message) {
const statusElement = document.getElementById('search-status');
if (statusElement) {
statusElement.textContent = message;
}
console.log(message);
}
// 添加调试日志
function logDebug(message) {
if (!config.debug) return;
console.log('[DEBUG] ' + message);
const logElement = document.getElementById('debug-log');
if (logElement) {
const logItem = document.createElement('div');
logItem.textContent = new Date().toLocaleTimeString() + ': ' + message;
logElement.appendChild(logItem);
// 自动滚动到底部
logElement.scrollTop = logElement.scrollHeight;
// 限制日志条数
while (logElement.childNodes.length > 20) {
logElement.removeChild(logElement.firstChild);
}
}
}
// 更新倒计时显示
function updateCountdown(seconds, action) {
const countdownElement = document.getElementById('countdown');
if (countdownElement) {
if (seconds > 0) {
let actionText = '';
switch (action) {
case 'scrolling': actionText = '滚动中'; break;
case 'waiting': actionText = '等待中'; break;
case 'resting': actionText = '休息中'; break;
case 'checking': actionText = '检查中'; break;
default: actionText = '倒计时';
}
countdownElement.textContent = `${actionText}: ${seconds}秒`;
countdownElement.style.display = 'block';
} else {
countdownElement.style.display = 'none';
}
}
}
// 开始倒计时
function startCountdown(seconds, action, callback) {
// 清除现有倒计时
if (countdownTimer) {
clearInterval(countdownTimer);
countdownTimer = null;
}
searchState.currentAction = action;
searchState.countdown = seconds;
updateCountdown(seconds, action);
countdownTimer = setInterval(() => {
searchState.countdown--;
updateCountdown(searchState.countdown, action);
if (searchState.countdown <= 0) {
clearInterval(countdownTimer);
countdownTimer = null;
if (callback) callback();
}
}, 1000);
}
// 点击打开侧边栏
function openRewardsSidebar() {
const pointsContainer = document.querySelector('.points-container');
if (pointsContainer) {
pointsContainer.click();
logDebug('已点击积分按钮,正在打开侧边栏...');
return true;
} else {
logDebug('未找到积分按钮');
return false;
}
}
// 从iframe中获取数据
function getDataFromIframe() {
const iframe = document.querySelector('iframe');
if (!iframe) {
logDebug('未找到iframe');
return false;
}
try {
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
logDebug('成功访问iframe文档');
// 获取进度 - 检查任务完成的几种可能情况
// 1. 检查包含"你已获得 X 积分"文本的元素
const allElements = iframeDoc.querySelectorAll('*');
for (let element of allElements) {
const text = element.textContent || '';
if (text.includes('你已获得') && text.includes('积分')) {
logDebug(`找到完成文本: "${text}"`);
const match = text.match(/你已获得\s*(\d+)\s*积分/);
if (match) {
const totalPoints = parseInt(match[1]);
currentProgress.current = totalPoints;
currentProgress.total = totalPoints;
currentProgress.completed = true;
document.getElementById('rewards-progress').textContent = `进度: ${totalPoints}/${totalPoints} (已完成)`;
logDebug(`搜索任务已完成! 总积分: ${totalPoints}`);
return true;
}
}
}
// 2. 特定检查promo-title类
const promoTitleElements = iframeDoc.querySelectorAll('.promo-title');
if (promoTitleElements.length > 0) {
for (let element of promoTitleElements) {
const text = element.textContent || '';
logDebug(`找到promo-title元素: "${text}"`);
if (text.includes('已获得')) {
const match = text.match(/已获得\s*(\d+)\s*积分/);
if (match) {
const totalPoints = parseInt(match[1]);
currentProgress.current = totalPoints;
currentProgress.total = totalPoints;
currentProgress.completed = true;
document.getElementById('rewards-progress').textContent = `进度: ${totalPoints}/${totalPoints} (已完成)`;
logDebug(`搜索任务已完成! 总积分: ${totalPoints}`);
return true;
}
}
}
}
// 3. 检查是否有"Offer not Completed"的标识
const offerElements = iframeDoc.querySelectorAll('[aria-label="Offer not Completed"]');
if (offerElements.length > 0) {
logDebug('找到"Offer not Completed"元素,但仍需检查是否实际完成');
// 即使有这个标识,也可能已经完成,所以继续检查
for (let element of offerElements) {
const text = element.textContent || '';
if (text.includes('已获得') && text.includes('积分')) {
logDebug(`找到完成文本: "${text}"`);
const match = text.match(/已获得\s*(\d+)\s*积分/);
if (match) {
const totalPoints = parseInt(match[1]);
currentProgress.current = totalPoints;
currentProgress.total = totalPoints;
currentProgress.completed = true;
document.getElementById('rewards-progress').textContent = `进度: ${totalPoints}/${totalPoints} (已完成)`;
logDebug(`搜索任务已完成! 总积分: ${totalPoints}`);
return true;
}
}
}
}
// 如果未完成,获取正常进度
const progressElement = iframeDoc.querySelector('.daily_search_row span:last-child');
if (progressElement) {
const progress = progressElement.textContent;
document.getElementById('rewards-progress').textContent = '进度: ' + progress;
logDebug('搜索进度: ' + progress);
// 解析进度数字
const match = progress.match(/(\d+)\/(\d+)/);
if (match) {
const current = parseInt(match[1]);
currentProgress.total = parseInt(match[2]);
// 检查进度是否增加
if (currentProgress.lastChecked > 0 && current <= currentProgress.lastChecked && isSearching) {
logDebug(`进度未增加: ${current} <= ${currentProgress.lastChecked},已连续 ${currentProgress.noProgressCount + 1} 次未增加`);
currentProgress.noProgressCount++;
// 只有当连续多次未增加进度时才休息
if (currentProgress.noProgressCount >= config.maxNoProgressCount) {
searchState.needRest = true;
logDebug(`达到最大容错次数 ${config.maxNoProgressCount},需要休息`);
}
} else if (current > currentProgress.lastChecked) {
// 进度增加,重置计数器
logDebug(`进度增加: ${current} > ${currentProgress.lastChecked},重置未增加计数`);
currentProgress.noProgressCount = 0;
}
currentProgress.current = current;
currentProgress.lastChecked = current;
// 检查是否完成
if (current >= currentProgress.total) {
currentProgress.completed = true;
logDebug(`进度数字表明任务已完成: ${current}/${currentProgress.total}`);
}
}
} else {
logDebug('未找到进度元素');
}
// 获取iframe中的搜索词
const searchTermsContainer = iframeDoc.querySelector('.ss_items_wrapper');
if (searchTermsContainer) {
const terms = [];
const spans = searchTermsContainer.querySelectorAll('span');
spans.forEach(span => {
terms.push(span.textContent);
});
// 保存到iframe搜索词变量
iframeSearchTerms = [...terms];
const termsContainer = document.getElementById('iframe-search-terms');
termsContainer.innerHTML = '';
terms.forEach(term => {
const termElem = document.createElement('div');
termElem.textContent = term;
termsContainer.appendChild(termElem);
});
logDebug('找到iframe搜索词: ' + terms.length + '个');
} else {
logDebug('未找到iframe搜索词容器');
}
return true;
} catch (e) {
logDebug('读取iframe内容出错: ' + e.message);
return false;
}
}
// 从主文档中获取搜索词
function getSearchTermsFromMainDoc() {
const suggestionsContainer = document.querySelector('.richrsrailsugwrapper');
if (suggestionsContainer) {
const terms = [];
const suggestions = suggestionsContainer.querySelectorAll('.richrsrailsuggestion_text');
suggestions.forEach(suggestion => {
terms.push(suggestion.textContent);
});
// 保存到主页面搜索词变量
mainPageSearchTerms = [...terms];
const termsContainer = document.getElementById('main-search-terms');
termsContainer.innerHTML = '';
terms.forEach(term => {
const termElem = document.createElement('div');
termElem.textContent = term;
termsContainer.appendChild(termElem);
});
logDebug('找到主页面搜索词: ' + terms.length + '个');
return true;
} else {
logDebug('未找到主页面搜索词');
return false;
}
}
// 获取Rewards数据
function getRewardsData(callback) {
updateStatus('正在获取奖励数据...');
if (openRewardsSidebar()) {
// 等待iframe加载
setTimeout(() => {
const iframeLoaded = getDataFromIframe();
const mainTermsLoaded = getSearchTermsFromMainDoc();
if (!iframeLoaded && !mainTermsLoaded) {
updateStatus('获取数据失败,请重试');
} else {
updateStatus('数据获取成功');
if (currentProgress.completed) {
updateStatus('搜索任务已完成!');
if (isSearching) {
showCompletionNotification();
stopAutomatedSearch();
}
}
}
// 如果检测到需要休息,并且正在搜索
if (searchState.needRest && isSearching) {
startResting();
} else if (callback) {
callback();
}
}, 1500);
} else {
updateStatus('未找到积分按钮,请确保已登录(不可用)');
if (callback) callback();
}
}
// 开始休息
function startResting() {
searchState.needRest = false;
// 重置未增加计数
currentProgress.noProgressCount = 0;
updateStatus(`连续 ${config.maxNoProgressCount} 次搜索无进度,休息 ${config.restTime / 60} 分钟后继续`);
startCountdown(config.restTime, 'resting', () => {
updateStatus('休息结束,继续搜索');
setTimeout(performNextSearch, 1000);
});
}
// 获取搜索词(优先主页面,其次iframe)
function getSearchTerm() {
// 创建可用搜索词数组(排除已使用的搜索词)
let availableMainTerms = mainPageSearchTerms.filter(term => !usedSearchTerms.includes(term));
let availableIframeTerms = iframeSearchTerms.filter(term => !usedSearchTerms.includes(term));
// 如果所有搜索词都已使用过,重置已使用列表
if (availableMainTerms.length === 0 && availableIframeTerms.length === 0 &&
(mainPageSearchTerms.length > 0 || iframeSearchTerms.length > 0)) {
logDebug('所有搜索词已用完,重置已使用列表');
usedSearchTerms = [];
availableMainTerms = [...mainPageSearchTerms];
availableIframeTerms = [...iframeSearchTerms];
}
// 优先使用主页面搜索词
if (availableMainTerms.length > 0) {
const randomIndex = Math.floor(Math.random() * availableMainTerms.length);
const term = availableMainTerms[randomIndex];
// 添加到已使用列表
usedSearchTerms.push(term);
logDebug(`选择搜索词: ${term} (主页面,还有 ${availableMainTerms.length - 1} 个未使用)`);
return {
term: term,
source: '主页面'
};
}
// 如果主页面没有搜索词,使用iframe搜索词
else if (availableIframeTerms.length > 0) {
const randomIndex = Math.floor(Math.random() * availableIframeTerms.length);
const term = availableIframeTerms[randomIndex];
// 添加到已使用列表
usedSearchTerms.push(term);
logDebug(`选择搜索词: ${term} (iframe,还有 ${availableIframeTerms.length - 1} 个未使用)`);
return {
term: term,
source: 'iframe'
};
}
// 如果都没有搜索词,返回null
return null;
}
// 执行搜索
function performSearch(term) {
if (!term) return false;
const searchBox = document.querySelector('#sb_form_q');
if (searchBox) {
// 填入搜索词
searchBox.value = term;
// 提交搜索
const searchForm = document.querySelector('#sb_form');
if (searchForm) {
searchForm.submit();
return true;
}
}
return false;
}
// 模拟滚动
function simulateScrolling(callback) {
updateStatus('正在滚动页面...');
searchState.currentAction = 'scrolling';
// 开始倒计时
startCountdown(config.scrollTime, 'scrolling', callback);
// 模拟随机滚动
const scrollInterval = setInterval(() => {
// 随机滚动距离
const scrollAmount = Math.floor(Math.random() * 300) + 100;
const scrollDirection = Math.random() > 0.3 ? 1 : -1; // 70%向下,30%向上
window.scrollBy(0, scrollAmount * scrollDirection);
// 如果当前动作不是滚动,停止滚动
if (searchState.currentAction !== 'scrolling') {
clearInterval(scrollInterval);
}
}, 1000);
// 滚动结束后停止滚动
setTimeout(() => {
clearInterval(scrollInterval);
}, config.scrollTime * 1000);
}
// 检查进度
function checkProgress(callback) {
updateStatus('正在检查搜索进度...');
searchState.currentAction = 'checking';
if (openRewardsSidebar()) {
setTimeout(() => {
getDataFromIframe();
// 同时从主页面获取搜索词
getSearchTermsFromMainDoc();
if (currentProgress.completed) {
showCompletionNotification();
updateStatus('搜索任务已完成!');
stopAutomatedSearch();
return;
}
if (searchState.needRest) {
startResting();
} else if (callback) {
callback();
}
}, 1500);
} else {
updateStatus('无法打开侧边栏检查进度');
if (callback) callback();
}
}
// 等待下一次搜索
function waitForNextSearch() {
updateStatus('等待下一次搜索...');
startCountdown(config.waitTime, 'waiting', performNextSearch);
}
// 执行下一次搜索
function performNextSearch() {
// 如果不在搜索状态,停止
if (!isSearching) return;
// 计算还需要搜索的次数
const remainingSearches = currentProgress.total - currentProgress.current;
if (remainingSearches <= 0 || currentProgress.completed) {
showCompletionNotification();
updateStatus('搜索任务已完成!');
stopAutomatedSearch();
return;
}
// 先更新搜索词列表,然后再获取搜索词
updateStatus('获取最新搜索词...');
getSearchTermsFromMainDoc();
// 获取搜索词
const searchTermObj = getSearchTerm();
if (!searchTermObj) {
updateStatus('没有可用的搜索词,获取数据...');
getRewardsData(() => {
// 重新检查是否有搜索词
const newSearchTermObj = getSearchTerm();
if (newSearchTermObj) {
// 有搜索词,重新执行搜索
setTimeout(performNextSearch, 1000);
} else {
updateStatus('无法获取搜索词,停止搜索');
stopAutomatedSearch();
}
});
return;
}
const { term, source } = searchTermObj;
updateStatus(`正在搜索: ${term} (${source}搜索词) [剩余:${remainingSearches}]`);
if (performSearch(term)) {
// 搜索成功后模拟滚动
setTimeout(() => {
simulateScrolling(() => {
// 滚动结束后检查进度
checkProgress(() => {
// 检查进度后等待下一次搜索
waitForNextSearch();
});
});
}, 2000);
} else {
updateStatus('搜索失败,请检查网页状态');
// 3秒后重试
setTimeout(performNextSearch, 3000);
}
}
// 开始自动搜索
function startAutomatedSearch() {
// 首先检查是否有搜索词,如果没有就获取
if (mainPageSearchTerms.length === 0 && iframeSearchTerms.length === 0) {
updateStatus('获取搜索词中...');
getRewardsData(() => {
if (mainPageSearchTerms.length === 0 && iframeSearchTerms.length === 0) {
alert('没有搜索词,无法开始搜索');
return;
} else {
// 有搜索词,开始搜索
startSearchProcess();
}
});
} else {
startSearchProcess();
}
}
// 开始搜索流程
function startSearchProcess() {
isSearching = true;
searchState.needRest = false;
currentProgress.noProgressCount = 0; // 重置未增加计数
usedSearchTerms = []; // 重置已使用搜索词列表
document.getElementById('start-search-btn').textContent = '停止搜索';
document.getElementById('start-search-btn').style.backgroundColor = '#d83b01';
updateStatus('自动搜索已开始...');
// 计算还需要搜索的次数
const remainingSearches = currentProgress.total - currentProgress.current;
if (remainingSearches <= 0 || currentProgress.completed) {
updateStatus('搜索任务已完成!');
stopAutomatedSearch();
return;
}
// 开始第一次搜索
performNextSearch();
}
// 停止自动搜索
function stopAutomatedSearch() {
// 清除倒计时
if (countdownTimer) {
clearInterval(countdownTimer);
countdownTimer = null;
}
isSearching = false;
searchState.currentAction = 'idle';
searchState.needRest = false;
currentProgress.noProgressCount = 0; // 重置未增加计数
usedSearchTerms = []; // 重置已使用搜索词列表
updateCountdown(0, '');
document.getElementById('start-search-btn').textContent = '开始自动搜索';
document.getElementById('start-search-btn').style.backgroundColor = '#0078d4';
updateStatus('搜索已停止');
}
// 显示完成通知
function showCompletionNotification() {
// 创建通知元素
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #0078d4;
color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
z-index: 10001;
text-align: center;
font-size: 16px;
`;
notification.innerHTML = `
<div style="font-weight: bold; margin-bottom: 10px; font-size: 18px;">任务完成!</div>
<div>已完成所有 ${currentProgress.total} 次搜索任务</div>
<button id="notification-close" style="
margin-top: 15px;
padding: 5px 15px;
background-color: white;
color: #0078d4;
border: none;
border-radius: 3px;
cursor: pointer;
">关闭</button>
`;
document.body.appendChild(notification);
// 添加关闭按钮事件
document.getElementById('notification-close').addEventListener('click', function () {
notification.remove();
});
// 10秒后自动关闭
setTimeout(() => {
if (document.body.contains(notification)) {
notification.remove();
}
}, 10000);
}
// 在页面加载完成后初始化
window.addEventListener('load', function () {
console.log('Microsoft Rewards 助手已加载');
createUI();
// 初始获取数据
setTimeout(() => {
getRewardsData();
}, 2000);
});
})();