// 充值与货币管理模块
class CurrencyManager {
constructor(options = {}) {
this.apiBaseUrl = options.apiBaseUrl || 'http://localhost:3000';
this.packages = [
{ points: 100, bonus: 20, price: 5 },
{ points: 1000, bonus: 200, price: 50 },
{ points: 10000, bonus: 800, price: 500 }
];
// 保存原始值用于比较
this.originalPackages = [];
this.init();
}
init() {
this.bindEvents();
this.loadSettings();
}
bindEvents() {
const addBtn = document.getElementById('addBtn');
if (addBtn) {
addBtn.addEventListener('click', () => this.addPackage());
}
}
async loadSettings() {
try {
const response = await fetch(`${this.apiBaseUrl}/api/admin/currency/settings`);
if (response.ok) {
const result = await response.json();
if (result.success && result.packages) {
this.packages = result.packages;
}
}
} catch (error) {
console.log('[CurrencyManager] 使用默认设置');
}
// 深拷贝保存原始值
this.originalPackages = JSON.parse(JSON.stringify(this.packages));
this.render();
}
render() {
this.renderPackages();
this.renderPreview();
}
renderPackages() {
const list = document.getElementById('packageList');
if (!list) return;
list.innerHTML = this.packages.map((pkg, i) => `
`).join('');
// 绑定输入事件
list.querySelectorAll('input').forEach(input => {
input.addEventListener('input', (e) => this.onInputChange(e));
});
// 绑定确认按钮
list.querySelectorAll('.btn-confirm').forEach(btn => {
btn.addEventListener('click', (e) => {
const index = parseInt(e.target.dataset.index);
this.savePackage(index);
});
});
// 绑定删除按钮
list.querySelectorAll('.btn-remove').forEach(btn => {
btn.addEventListener('click', (e) => {
const index = parseInt(e.target.dataset.index);
this.removePackage(index);
});
});
}
onInputChange(e) {
const item = e.target.closest('.package-item');
const index = parseInt(item.dataset.index);
const field = e.target.dataset.field;
const value = parseFloat(e.target.value) || 0;
this.packages[index][field] = value;
// 更新总计显示
const pkg = this.packages[index];
const totalEl = item.querySelector('.package-total');
if (totalEl) {
totalEl.textContent = `= ${pkg.points + pkg.bonus} Ani币`;
}
// 检查是否有变化,显示确认按钮
const confirmBtn = item.querySelector('.btn-confirm');
const original = this.originalPackages[index];
const hasChange = !original ||
pkg.price !== original.price ||
pkg.points !== original.points ||
pkg.bonus !== original.bonus;
if (confirmBtn) {
confirmBtn.classList.toggle('show', hasChange);
}
this.renderPreview();
}
renderPreview() {
const preview = document.getElementById('preview');
if (!preview) return;
preview.innerHTML = this.packages.map(pkg => `
${pkg.points} Ani币
${pkg.bonus > 0 ? `
送 ${pkg.bonus} Ani币
` : ''}
¥${pkg.price}
`).join('');
}
addPackage() {
const last = this.packages[this.packages.length - 1] || { points: 100, bonus: 0, price: 10 };
const newPkg = {
points: last.points * 2,
bonus: Math.floor(last.bonus * 1.5),
price: last.price * 2
};
this.packages.push(newPkg);
this.originalPackages.push(null); // 新增的没有原始值
this.render();
// 显示新增项的确认按钮
setTimeout(() => {
const items = document.querySelectorAll('.package-item');
const lastItem = items[items.length - 1];
if (lastItem) {
const confirmBtn = lastItem.querySelector('.btn-confirm');
if (confirmBtn) confirmBtn.classList.add('show');
}
}, 0);
}
async removePackage(index) {
if (this.packages.length <= 1) {
this.showMsg('至少保留一个套餐', 'error');
return;
}
this.packages.splice(index, 1);
this.originalPackages.splice(index, 1);
// 保存到服务器
await this.saveAll();
this.render();
}
async savePackage(index) {
await this.saveAll();
// 更新原始值
this.originalPackages[index] = JSON.parse(JSON.stringify(this.packages[index]));
// 隐藏确认按钮
const items = document.querySelectorAll('.package-item');
const item = items[index];
if (item) {
const confirmBtn = item.querySelector('.btn-confirm');
if (confirmBtn) confirmBtn.classList.remove('show');
}
}
async saveAll() {
try {
const response = await fetch(`${this.apiBaseUrl}/api/admin/currency/settings`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ packages: this.packages })
});
const result = await response.json();
if (result.success) {
this.showMsg('保存成功', 'success');
// 更新所有原始值
this.originalPackages = JSON.parse(JSON.stringify(this.packages));
} else {
this.showMsg('保存失败: ' + (result.message || ''), 'error');
}
} catch (error) {
this.showMsg('保存失败', 'error');
}
}
showMsg(text, type) {
const msgBox = document.getElementById('msgBox');
if (msgBox) {
msgBox.textContent = text;
msgBox.className = 'msg ' + type;
msgBox.style.display = 'block';
setTimeout(() => {
msgBox.style.display = 'none';
}, 2000);
}
}
}
if (typeof module !== 'undefined' && module.exports) {
module.exports = CurrencyManager;
} else {
window.CurrencyManager = CurrencyManager;
}