// ==UserScript==
// @name 【云】FuBiJI自动购买功能
// @namespace http://tampermonkey.net/
// @version 1.4
// @description 自动购买功能,支持购买状态检测和链接复制,使用localStorage缓存,支持导入导出
// @author You
// @license MIT
// @match https://fubiji.site/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
// 样式定义
GM_addStyle(`
.auto-buy-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin: 5px;
position: relative;
overflow: hidden;
}
.auto-buy-button:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.auto-buy-button:active {
transform: translateY(0);
}
.auto-buy-button:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.auto-buy-button.loading {
background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);
}
.auto-buy-button.success {
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
color: black; /* 修改为黑色文字 */
}
.auto-buy-button::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.5s;
}
.auto-buy-button:hover::before {
left: 100%;
}
.auto-buy-message {
position: fixed;
top: 20px;
right: 20px;
background: #4CAF50;
color: white;
padding: 12px 20px;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 10000;
font-size: 14px;
font-weight: 500;
transform: translateX(100%);
transition: transform 0.3s ease;
}
.auto-buy-message.show {
transform: translateX(0);
}
.auto-buy-message.error {
background: #f44336;
}
.auto-buy-message.warning {
background: #ff9800;
}
/* 页面访问提示框样式 */
.page-visit-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 20000;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}
.page-visit-modal.show {
opacity: 1;
visibility: visible;
}
.page-visit-content {
background: white;
border-radius: 12px;
padding: 30px;
max-width: 400px;
width: 90%;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
transform: scale(0.8);
transition: transform 0.3s ease;
}
.page-visit-modal.show .page-visit-content {
transform: scale(1);
}
.page-visit-icon {
font-size: 48px;
margin-bottom: 20px;
}
.page-visit-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 15px;
color: #333;
}
.page-visit-message {
font-size: 16px;
color: #666;
margin-bottom: 25px;
line-height: 1.5;
}
.page-visit-buttons {
display: flex;
gap: 15px;
justify-content: center;
}
.page-visit-btn {
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.3s ease;
}
.page-visit-btn.primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.page-visit-btn.primary:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.page-visit-btn.secondary {
background: #f5f5f5;
color: #666;
}
.page-visit-btn.secondary:hover {
background: #e0e0e0;
}
/* 导入导出控制面板样式 */
.import-export-panel {
position: fixed;
bottom: 20px;
right: 20px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
padding: 15px;
z-index: 15000;
min-width: 200px;
border: 1px solid #e0e0e0;
}
.import-export-title {
font-size: 14px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
text-align: center;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 8px;
}
.import-export-buttons {
display: flex;
flex-direction: column;
gap: 8px;
}
.import-export-btn {
padding: 8px 12px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 12px;
font-weight: 500;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
}
.import-export-btn.export {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
color: white;
}
.import-export-btn.export:hover {
transform: translateY(-1px);
box-shadow: 0 3px 6px rgba(0,0,0,0.15);
}
.import-export-btn.import {
background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
color: white;
}
.import-export-btn.import:hover {
transform: translateY(-1px);
box-shadow: 0 3px 6px rgba(0,0,0,0.15);
}
.import-export-btn.clear {
background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);
color: white;
}
.import-export-btn.clear:hover {
transform: translateY(-1px);
box-shadow: 0 3px 6px rgba(0,0,0,0.15);
}
.import-export-btn.stats {
background: linear-gradient(135deg, #ff9800 0%, #f57c00 100%);
color: white;
}
.import-export-btn.stats:hover {
transform: translateY(-1px);
box-shadow: 0 3px 6px rgba(0,0,0,0.15);
}
/* 隐藏的文件输入框 */
.hidden-file-input {
display: none;
}
/* 统计信息弹窗样式 */
.stats-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 25000;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
}
.stats-modal.show {
opacity: 1;
visibility: visible;
}
.stats-content {
background: white;
border-radius: 12px;
padding: 25px;
max-width: 500px;
width: 90%;
max-height: 80vh;
overflow-y: auto;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
transform: scale(0.8);
transition: transform 0.3s ease;
}
.stats-modal.show .stats-content {
transform: scale(1);
}
.stats-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 15px;
color: #333;
text-align: center;
}
.stats-item {
display: flex;
justify-content: space-between;
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.stats-item:last-child {
border-bottom: none;
}
.stats-label {
font-weight: 500;
color: #666;
}
.stats-value {
color: #333;
font-weight: bold;
}
.stats-close-btn {
background: #f5f5f5;
color: #666;
border: none;
padding: 8px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
margin-top: 15px;
width: 100%;
}
.stats-close-btn:hover {
background: #e0e0e0;
}
`);
// 导入导出管理器
class ImportExportManager {
constructor(buyRecordManager, messageManager) {
this.buyRecordManager = buyRecordManager;
this.messageManager = messageManager;
this.panel = null;
this.statsModal = null;
this.init();
}
init() {
this.createPanel();
this.createStatsModal();
this.createHiddenFileInput();
}
createPanel() {
this.panel = document.createElement('div');
this.panel.className = 'import-export-panel';
this.panel.innerHTML = `
<div class="import-export-title">数据管理</div>
<div class="import-export-buttons">
<button class="import-export-btn export" id="exportBtn">
📤 导出数据
</button>
<button class="import-export-btn import" id="importBtn">
📥 导入数据
</button>
<button class="import-export-btn stats" id="statsBtn">
📊 查看统计
</button>
<button class="import-export-btn clear" id="clearBtn">
🗑️ 清空数据
</button>
</div>
`;
document.body.appendChild(this.panel);
// 绑定事件
this.panel.querySelector('#exportBtn').onclick = () => this.exportData();
this.panel.querySelector('#importBtn').onclick = () => this.importData();
this.panel.querySelector('#statsBtn').onclick = () => this.showStats();
this.panel.querySelector('#clearBtn').onclick = () => this.clearData();
}
createStatsModal() {
this.statsModal = document.createElement('div');
this.statsModal.className = 'stats-modal';
this.statsModal.innerHTML = `
<div class="stats-content">
<div class="stats-title">购买记录统计</div>
<div id="statsContent"></div>
<button class="stats-close-btn" id="closeStatsBtn">关闭</button>
</div>
`;
document.body.appendChild(this.statsModal);
// 绑定关闭事件
this.statsModal.querySelector('#closeStatsBtn').onclick = () => this.hideStats();
this.statsModal.onclick = (e) => {
if (e.target === this.statsModal) {
this.hideStats();
}
};
}
createHiddenFileInput() {
this.fileInput = document.createElement('input');
this.fileInput.type = 'file';
this.fileInput.accept = '.json';
this.fileInput.className = 'hidden-file-input';
this.fileInput.onchange = (e) => this.handleFileImport(e);
document.body.appendChild(this.fileInput);
}
// 导出数据
exportData() {
try {
const records = this.buyRecordManager.getAllRecords();
const exportData = {
version: '1.3',
exportTime: new Date().toISOString(),
totalRecords: Object.keys(records).length,
records: records
};
const dataStr = JSON.stringify(exportData, null, 2);
const dataBlob = new Blob([dataStr], { type: 'application/json' });
const link = document.createElement('a');
link.href = URL.createObjectURL(dataBlob);
link.download = `fubiji_buy_records_${new Date().toISOString().split('T')[0]}.json`;
link.click();
URL.revokeObjectURL(link.href);
this.messageManager.show('数据导出成功!', 'success');
} catch (error) {
console.error('导出失败:', error);
this.messageManager.show('导出失败: ' + error.message, 'error');
}
}
// 导入数据
importData() {
this.fileInput.click();
}
// 处理文件导入
handleFileImport(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
try {
const importData = JSON.parse(e.target.result);
// 验证数据格式
if (!importData.records || typeof importData.records !== 'object') {
throw new Error('无效的数据格式');
}
// 确认导入
const confirmMessage = `即将导入 ${Object.keys(importData.records).length} 条购买记录,是否继续?\n\n注意:这将覆盖现有的购买记录!`;
if (!confirm(confirmMessage)) {
return;
}
// 导入数据
this.buyRecordManager.records = importData.records;
this.buyRecordManager.saveRecords();
this.messageManager.show(`成功导入 ${Object.keys(importData.records).length} 条记录!`, 'success');
// 刷新页面按钮状态
if (window.autoBuyManager) {
window.autoBuyManager.updateAllButtonStates();
}
} catch (error) {
console.error('导入失败:', error);
this.messageManager.show('导入失败: ' + error.message, 'error');
}
};
reader.readAsText(file);
// 清空文件输入框
event.target.value = '';
}
// 显示统计信息
showStats() {
const records = this.buyRecordManager.getAllRecords();
const recordIds = Object.keys(records);
let totalCopyCount = 0;
let recentRecords = 0;
const now = Date.now();
const oneWeekAgo = now - (7 * 24 * 60 * 60 * 1000);
recordIds.forEach(id => {
const record = records[id];
totalCopyCount += record.copyCount || 0;
if (record.timestamp > oneWeekAgo) {
recentRecords++;
}
});
const statsContent = this.statsModal.querySelector('#statsContent');
statsContent.innerHTML = `
<div class="stats-item">
<span class="stats-label">总购买记录数</span>
<span class="stats-value">${recordIds.length}</span>
</div>
<div class="stats-item">
<span class="stats-label">总复制次数</span>
<span class="stats-value">${totalCopyCount}</span>
</div>
<div class="stats-item">
<span class="stats-label">最近一周新增</span>
<span class="stats-value">${recentRecords}</span>
</div>
<div class="stats-item">
<span class="stats-label">平均复制次数</span>
<span class="stats-value">${recordIds.length > 0 ? (totalCopyCount / recordIds.length).toFixed(1) : 0}</span>
</div>
<div class="stats-item">
<span class="stats-label">数据版本</span>
<span class="stats-value">1.3</span>
</div>
`;
this.statsModal.classList.add('show');
}
// 隐藏统计信息
hideStats() {
this.statsModal.classList.remove('show');
}
// 清空数据
clearData() {
const confirmMessage = '确定要清空所有购买记录吗?\n\n此操作不可恢复!';
if (confirm(confirmMessage)) {
this.buyRecordManager.clearRecords();
this.messageManager.show('数据已清空!', 'success');
// 刷新页面按钮状态
if (window.autoBuyManager) {
window.autoBuyManager.updateAllButtonStates();
}
}
}
}
// 购买记录管理器 - 使用localStorage
class BuyRecordManager {
constructor() {
this.storageKey = 'fubiji_buy_list';
this.records = this.loadRecords();
}
// 加载购买记录
loadRecords() {
try {
const data = localStorage.getItem(this.storageKey) || '{}';
return JSON.parse(data);
} catch (error) {
console.error('加载购买记录失败:', error);
return {};
}
}
// 保存购买记录
saveRecords() {
try {
localStorage.setItem(this.storageKey, JSON.stringify(this.records));
} catch (error) {
console.error('保存购买记录失败:', error);
}
}
// 添加购买记录
addRecord(id, link, content = '') {
this.records[id] = {
link: link,
content: content,
timestamp: Date.now(),
date: new Date().toLocaleString(),
copyCount: 0 // 添加复制次数字段
};
this.saveRecords();
}
// 获取购买记录
getRecord(id) {
return this.records[id] || null;
}
// 检查是否已购买
isPurchased(id) {
return id in this.records;
}
// 增加复制次数
incrementCopyCount(id) {
if (this.records[id]) {
this.records[id].copyCount = (this.records[id].copyCount || 0) + 1;
this.saveRecords();
return this.records[id].copyCount;
}
return 0;
}
// 获取复制次数
getCopyCount(id) {
return this.records[id]?.copyCount || 0;
}
// 获取所有记录
getAllRecords() {
return this.records;
}
// 清除记录
clearRecords() {
this.records = {};
this.saveRecords();
}
}
// 页面访问提示框管理器
class PageVisitModalManager {
constructor() {
this.modal = null;
this.init();
}
init() {
this.createModal();
}
createModal() {
this.modal = document.createElement('div');
this.modal.className = 'page-visit-modal';
this.modal.innerHTML = `
<div class="page-visit-content">
<div class="page-visit-icon">🎉</div>
<div class="page-visit-title">已购买内容</div>
<div class="page-visit-message">
您已购买过此内容,可以直接访问下载链接。
</div>
<div class="page-visit-buttons">
<button class="page-visit-btn primary" id="copyLinkBtn">复制链接</button>
<button class="page-visit-btn secondary" id="closeModalBtn">关闭</button>
</div>
</div>
`;
document.body.appendChild(this.modal);
// 绑定事件
this.modal.querySelector('#closeModalBtn').onclick = () => this.hide();
this.modal.onclick = (e) => {
if (e.target === this.modal) {
this.hide();
}
};
}
show(id, record) {
const copyBtn = this.modal.querySelector('#copyLinkBtn');
copyBtn.onclick = async () => {
try {
await navigator.clipboard.writeText(record.link);
this.messageManager?.show('链接已复制到剪贴板', 'success');
this.hide();
} catch (error) {
console.error('复制失败:', error);
this.messageManager?.show('复制失败', 'error');
}
};
this.modal.classList.add('show');
}
hide() {
this.modal.classList.remove('show');
}
setMessageManager(messageManager) {
this.messageManager = messageManager;
}
}
// 消息显示管理器
class MessageManager {
constructor() {
this.messageContainer = null;
this.init();
}
init() {
this.messageContainer = document.createElement('div');
this.messageContainer.className = 'auto-buy-message';
document.body.appendChild(this.messageContainer);
}
show(message, type = 'success', duration = 3000) {
this.messageContainer.textContent = message;
this.messageContainer.className = `auto-buy-message ${type}`;
this.messageContainer.classList.add('show');
setTimeout(() => {
this.messageContainer.classList.remove('show');
}, duration);
}
hide() {
this.messageContainer.classList.remove('show');
}
}
// 页面访问检查器 - 增强版,支持自动检测购买状态
class PageVisitChecker {
constructor(buyRecordManager, modalManager, messageManager) {
this.buyRecordManager = buyRecordManager;
this.modalManager = modalManager;
this.messageManager = messageManager;
this.modalManager.setMessageManager(messageManager);
}
// 检查当前页面
checkCurrentPage() {
const url = window.location.href;
const id = this.extractIdFromUrl(url);
if (!id) {
return;
}
// 检查页面是否包含 erphpdown-content-vip 元素(表示已购买)
const vipContent = this.extractVipContent();
const hasVipContent = vipContent && vipContent.isPurchased;
// 检查是否已在缓存中购买
const isInCache = this.buyRecordManager.isPurchased(id);
if (hasVipContent) {
// 页面显示已购买,检查缓存
if (!isInCache) {
// 不在缓存中,自动添加到购买记录
console.log(`检测到页面 ${id} 已购买但未在缓存中,自动添加到购买记录`);
this.buyRecordManager.addRecord(id, url, vipContent.text);
this.messageManager.show('检测到已购买内容,已自动添加到购买记录', 'success');
} else {
// 在缓存中,更新内容
const record = this.buyRecordManager.getRecord(id);
if (record.content !== vipContent.text) {
this.buyRecordManager.addRecord(id, url, vipContent.text);
console.log(`更新页面 ${id} 的购买记录内容`);
}
}
// 显示提示框
const record = this.buyRecordManager.getRecord(id);
this.modalManager.show(id, record);
console.log(`页面 ${id} 已购买,显示提示框并更新购买列表`);
} else if (isInCache) {
// 在缓存中但页面不显示已购买,可能是页面加载问题
console.log(`页面 ${id} 在缓存中但页面未显示购买状态,可能需要刷新`);
this.messageManager.show('页面可能未完全加载,请刷新页面查看购买状态', 'warning');
} else {
console.log(`页面 ${id} 未购买`);
}
}
// 从URL中提取ID
extractIdFromUrl(url) {
const match = url.match(/https:\/\/fubiji\.site\/(\d+)/);
return match ? match[1] : null;
}
// 提取 erphpdown-content-vip 元素的内容
extractVipContent() {
try {
const vipElement = document.querySelector('.erphpdown-content-vip');
if (vipElement) {
// 提取文本内容和链接
const content = vipElement.textContent.trim();
const links = Array.from(vipElement.querySelectorAll('a')).map(a => a.href);
// 判断是否真正已购买:包含"pan.baidu"才算已购买
const isPurchased = content.includes('pan.baidu');
return {
text: content,
links: links,
hasContent: content.length > 0,
isPurchased: isPurchased
};
}
return null;
} catch (error) {
console.error('提取VIP内容失败:', error);
return null;
}
}
// 检查页面是否已购买(通过VIP内容判断)
isPagePurchased() {
const vipContent = this.extractVipContent();
return vipContent && vipContent.isPurchased;
}
}
// 自动购买管理器
class AutoBuyManager {
constructor() {
this.recordManager = new BuyRecordManager();
this.messageManager = new MessageManager();
this.modalManager = new PageVisitModalManager();
this.pageChecker = new PageVisitChecker(
this.recordManager,
this.modalManager,
this.messageManager
);
this.importExportManager = new ImportExportManager(
this.recordManager,
this.messageManager
);
this.buttons = new Map();
this.cacheCheckInterval = null; // 缓存检查定时器
this.init();
}
init() {
// 检查当前页面
this.pageChecker.checkCurrentPage();
this.createBuyButtons();
this.observePageChanges();
this.startCacheMonitoring(); // 启动缓存监控
}
// 启动缓存监控
startCacheMonitoring() {
// 每5秒检查一次缓存变化
this.cacheCheckInterval = setInterval(() => {
this.checkCacheChanges();
}, 5000);
// 监听localStorage变化事件(跨标签页同步)
window.addEventListener('storage', (e) => {
if (e.key === 'fubiji_buy_list') {
console.log('检测到购买记录缓存变化,更新按钮状态');
this.updateAllButtonStates();
}
});
}
// 检查缓存变化
checkCacheChanges() {
// 重新从localStorage加载最新的购买记录
this.recordManager.records = this.recordManager.loadRecords();
// 检查每个按钮对应的记录状态
this.buttons.forEach((button, id) => {
const isCurrentlyPurchased = this.recordManager.isPurchased(id);
const buttonIsCopyState = button.textContent === '复制';
// 如果状态不匹配,更新按钮
if (isCurrentlyPurchased && !buttonIsCopyState) {
console.log(`检测到ID ${id} 已购买,更新按钮状态`);
this.updateButtonToCopy(button, id);
} else if (!isCurrentlyPurchased && buttonIsCopyState) {
console.log(`检测到ID ${id} 未购买,更新按钮状态`);
this.updateButtonToBuy(button, id);
}
});
}
// 更新所有按钮状态
updateAllButtonStates() {
// 重新从localStorage加载最新的购买记录
this.recordManager.records = this.recordManager.loadRecords();
this.buttons.forEach((button, id) => {
if (this.recordManager.isPurchased(id)) {
this.updateButtonToCopy(button, id);
} else {
this.updateButtonToBuy(button, id);
}
});
}
// 创建购买按钮
createBuyButtons() {
// 查找所有 list-item-buttons 容器
const buttonContainers = document.querySelectorAll('.list-item-buttons');
buttonContainers.forEach(container => {
// 获取第一个按钮的 data-id 属性
const firstButton = container.querySelector('button');
if (!firstButton || !firstButton.dataset.id) {
return;
}
const id = firstButton.dataset.id;
// 避免重复添加按钮
if (this.buttons.has(id)) {
return;
}
// 检查是否已经存在自动购买按钮
const existingAutoButton = container.querySelector('.auto-buy-button');
if (existingAutoButton) {
return;
}
// 创建购买按钮
const button = this.createButton(id);
this.buttons.set(id, button);
// 将按钮添加到容器的最后
container.appendChild(button);
});
}
// 创建按钮
createButton(id) {
const button = document.createElement('button');
button.className = 'auto-buy-button';
button.dataset.postid = id;
// 检查是否已购买
if (this.recordManager.isPurchased(id)) {
this.updateButtonToCopy(button, id);
} else {
this.updateButtonToBuy(button, id);
}
return button;
}
// 更新按钮为购买状态
updateButtonToBuy(button, id) {
button.textContent = '购买';
button.className = 'auto-buy-button';
button.onclick = () => this.handleBuy(id, button);
// 显示所有按钮(恢复隐藏的按钮)
this.showAllButtons(id);
}
// 更新按钮为复制状态
updateButtonToCopy(button, id) {
const copyCount = this.recordManager.getCopyCount(id);
if (copyCount > 0) {
button.textContent = `已复制${copyCount}次`;
} else {
button.textContent = '复制';
}
button.className = 'auto-buy-button success';
button.onclick = () => this.handleCopy(id, button);
// 隐藏第二个到第五个按钮
this.hideButtons(id);
}
// 隐藏第二个到第五个按钮
hideButtons(id) {
// 找到对应的按钮容器
const buttonContainers = document.querySelectorAll('.list-item-buttons');
buttonContainers.forEach(container => {
const firstButton = container.querySelector('button');
if (firstButton && firstButton.dataset.id === id) {
// 获取所有按钮
const allButtons = container.querySelectorAll('button');
// 隐藏第二个到第五个按钮(索引1-4)
for (let i = 1; i <= 4 && i < allButtons.length; i++) {
allButtons[i].style.display = 'none';
}
}
});
}
// 显示所有按钮
showAllButtons(id) {
// 找到对应的按钮容器
const buttonContainers = document.querySelectorAll('.list-item-buttons');
buttonContainers.forEach(container => {
const firstButton = container.querySelector('button');
if (firstButton && firstButton.dataset.id === id) {
// 获取所有按钮
const allButtons = container.querySelectorAll('button');
// 显示所有按钮
allButtons.forEach(button => {
button.style.display = '';
});
}
});
}
// 处理购买
async handleBuy(id, button) {
try {
button.disabled = true;
button.className = 'auto-buy-button loading';
button.textContent = '购买中...';
const buyUrl = `https://fubiji.site/wp-content/plugins/erphpdown/checkout.php?postid=${id}`;
// 发送购买请求
const response = await fetch(buyUrl, {
method: 'GET',
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Cache-Control': 'no-cache',
'Pragma': 'no-cache'
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// 获取页面内容检查购买结果
const pageContent = await response.text();
const result = this.extractDownloadLink(pageContent);
if (result && (result.link || result.content)) {
// 购买成功,保存链接和内容
this.recordManager.addRecord(id, result.link || '', result.content || '');
this.updateButtonToCopy(button, id);
this.messageManager.show('购买成功!', 'success');
} else {
// 购买失败或需要进一步处理
button.disabled = false;
button.className = 'auto-buy-button';
button.textContent = '购买';
this.messageManager.show('购买处理中,请稍后刷新页面查看', 'warning');
}
} catch (error) {
console.error('购买失败:', error);
button.disabled = false;
button.className = 'auto-buy-button';
button.textContent = '购买';
this.messageManager.show('购买失败: ' + error.message, 'error');
}
}
// 处理复制
async handleCopy(id, button) {
try {
const record = this.recordManager.getRecord(id);
if (!record) {
this.messageManager.show('未找到购买记录', 'error');
return;
}
// 复制内容到剪贴板(优先复制content,如果没有则复制link)
const copyContent = record.content || record.link;
await navigator.clipboard.writeText(copyContent);
// 增加复制次数
const newCopyCount = this.recordManager.incrementCopyCount(id);
// 更新按钮文字
button.textContent = `已复制${newCopyCount}次`;
// 显示成功消息
this.messageManager.show('内容已复制到剪贴板', 'success');
} catch (error) {
console.error('复制失败:', error);
this.messageManager.show('复制失败: ' + error.message, 'error');
}
}
// 从页面内容中提取下载链接和内容
extractDownloadLink(htmlContent) {
try {
// 创建临时DOM来解析HTML
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlContent;
// 查找erphpdown-content-vip类
const vipContent = tempDiv.querySelector('.erphpdown-content-vip');
if (!vipContent) return null;
// 提取文本内容
const content = vipContent.textContent.trim();
// 查找第一个a链接
const firstLink = vipContent.querySelector('a');
const link = firstLink ? firstLink.href : null;
return {
link: link,
content: content
};
} catch (error) {
console.error('解析下载链接失败:', error);
return null;
}
}
// 监听页面变化
observePageChanges() {
const observer = new MutationObserver((mutations) => {
let shouldUpdate = false;
mutations.forEach((mutation) => {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
// 检查新添加的元素是否包含 list-item-buttons
const hasListButtons = node.querySelector && (
node.querySelector('.list-item-buttons') ||
node.matches('.list-item-buttons')
);
if (hasListButtons) {
shouldUpdate = true;
}
}
});
}
});
if (shouldUpdate) {
setTimeout(() => {
this.createBuyButtons();
}, 500);
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
}
// 获取购买统计
getBuyStats() {
const records = this.recordManager.getAllRecords();
return {
totalPurchases: Object.keys(records).length,
records: records
};
}
// 销毁管理器(清理定时器)
destroy() {
if (this.cacheCheckInterval) {
clearInterval(this.cacheCheckInterval);
this.cacheCheckInterval = null;
}
}
}
// 初始化自动购买功能
function initAutoBuy() {
// 等待页面加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
window.autoBuyManager = new AutoBuyManager();
});
} else {
window.autoBuyManager = new AutoBuyManager();
}
}
// 添加控制台命令
function addConsoleCommands() {
window.getBuyStats = () => {
if (window.autoBuyManager) {
return window.autoBuyManager.getBuyStats();
}
return null;
};
window.clearBuyRecords = () => {
if (window.autoBuyManager) {
window.autoBuyManager.recordManager.clearRecords();
console.log('购买记录已清除');
}
};
window.showBuyRecords = () => {
if (window.autoBuyManager) {
const stats = window.autoBuyManager.getBuyStats();
console.table(stats.records);
}
};
// 新增:手动触发缓存检查
window.checkCacheNow = () => {
if (window.autoBuyManager) {
window.autoBuyManager.checkCacheChanges();
console.log('已手动触发缓存检查');
}
};
// 新增:停止/启动缓存监控
window.stopCacheMonitoring = () => {
if (window.autoBuyManager && window.autoBuyManager.cacheCheckInterval) {
clearInterval(window.autoBuyManager.cacheCheckInterval);
window.autoBuyManager.cacheCheckInterval = null;
console.log('缓存监控已停止');
}
};
window.startCacheMonitoring = () => {
if (window.autoBuyManager) {
window.autoBuyManager.startCacheMonitoring();
console.log('缓存监控已启动');
}
};
}
// 启动脚本
initAutoBuy();
addConsoleCommands();
console.log('自动购买功能已加载 v1.3');
console.log('可用命令: getBuyStats(), clearBuyRecords(), showBuyRecords(), checkCacheNow(), stopCacheMonitoring(), startCacheMonitoring()');
})();
Wrap
Beautify