将代码复制到哪吒面板后台的自定义代码
日期+剩余天数
<script>
window.onload = function() {
// 定义产品的详细数据,包括价格、周期、开始和到期日期以及商家名称
const extraData = {
1: { price: '0.84€', cycle: 'Month', start: '2024-10-30', expire: '2024-10-31', merchant: 'MerchantA' },
2: { price: 'FREE', cycle: 'Month', start: '2021-04-15', expire: '∞', merchant: 'MerchantB' },
3: { price: '24¥', cycle: 'Month', start: '2023-12-24', expire: '2024-12-25', merchant: 'MerchantC' },
4: { price: '5$', cycle: 'Month', start: '2024-03-05', expire: '2024-05-31', merchant: 'MerchantA' },
5: { price: 'FREE', cycle: 'Year', start: '2023-05-03', expire: '2025-04-03', merchant: 'MerchantB' }
};
// 定义商家与其支付页面的 URL 映射
const merchantUrls = {
MerchantA: 'https://merchantA.com/payment',
MerchantB: 'https://merchantB.com/payment',
MerchantC: 'https://merchantC.com/payment'
};
// 设置到期阈值,当进度条超过此百分比时颜色变为红色
const threshold = 80;
// 获取页面上所有的 .ui.accordion 元素
const cats = document.querySelectorAll('.ui.accordion');
cats.forEach((e, i) => {
let $catsTitle = e.querySelector('.title');
let ct = $catsTitle.innerText.trim();
if (ct === '默认') return; // 跳过标题为“默认”的元素
let $itemCard = e.querySelectorAll('.ui.card');
let uiCardCount = $itemCard.length;
$catsTitle.innerHTML = $catsTitle.innerHTML.replace(ct, `${ct} (${uiCardCount})`); // 在标题中显示卡片数量
// 遍历每个卡片,插入价格和到期信息
$itemCard.forEach((ee, ii) => {
let $descriptionGrid = ee.querySelector('.description .ui.grid');
let id = ee.getAttribute('id');
// 确保 id 存在于 extraData 中
if (extraData.hasOwnProperty(id)) {
let { price, start, expire, cycle, merchant } = extraData[id];
if (price) {
// 插入价格标签
let $priceL = document.createElement('div');
$priceL.setAttribute('class', 'three wide column');
$priceL.innerHTML = '价格';
$descriptionGrid.insertBefore($priceL, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
let $priceR = document.createElement('div');
$priceR.setAttribute('class', 'thirteen wide column');
// 在价格标签中插入周期链接,点击后跳转到商家的支付页面
$priceR.innerHTML = `
<div class="ui green label" style="border-radius: 8px; display: inline-block;">
<i class="money bill alternate yellow icon"></i>${price}
<a href="${merchantUrls[merchant]}" target="_blank" class="detail" style="color: inherit; text-decoration: underline;">${cycle}</a>
</div>`;
$descriptionGrid.insertBefore($priceR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
}
if (expire) {
// 插入到期标签
let $expireL = document.createElement('div');
$expireL.setAttribute('class', 'three wide column');
$expireL.innerHTML = '到期';
$descriptionGrid.insertBefore($expireL, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
let $expireR = document.createElement('div');
let beginTime = new Date(start).getTime();
let endTime = expire === '∞' ? Infinity : new Date(expire).getTime();
let nowTime = new Date().getTime();
// 计算总天数、已过去的天数和剩余天数
let totalDays = expire === '∞' ? 1 : Math.ceil((endTime - beginTime) / (1000 * 60 * 60 * 24)); // 总天数
let passedDays = expire === '∞' ? 0 : Math.ceil((nowTime - beginTime) / (1000 * 60 * 60 * 24)); // 已过去的天数
let remainingDays = expire === '∞' ? 0 : Math.ceil((endTime - nowTime) / (1000 * 60 * 60 * 24)); // 剩余天数
if (remainingDays < 0) {
remainingDays = 0; // 设置为0,避免负值
}
// 计算进度条的百分比
let percentage = expire === '∞' ? 100 : (passedDays / totalDays) * 100;
percentage = Math.min(percentage, 100); // 确保不超过100%
// 根据剩余天数设置进度条颜色和标签文本
let progressColor;
let progressType;
let labelText;
if (expire === '∞') {
progressColor = '#48c9b0'; // 绿色代表永久
progressType = 'success';
labelText = '永久'; // 表示这是永久的
} else {
if (nowTime > endTime) {
progressColor = '#7f8c8d'; // 灰色代表已过期
progressType = 'expired';
labelText = '已过期';
percentage = 100; // 进度条宽度设置为100%
} else {
if (percentage >= threshold) {
progressColor = '#e74c3c'; // 红色代表超出阈值
progressType = 'error';
} else {
progressColor = '#48c9b0'; // 绿色代表安全范围
progressType = 'success';
}
// 格式化到期日期和剩余天数
const expireDate = new Date(expire).toISOString().split('T')[0]; // 将日期格式化为 YYYY-MM-DD
labelText = `${remainingDays}天 (${expireDate})`; // 显示剩余天数和到期日期
}
}
// 设置到期进度条的样式
$expireR.setAttribute('class', 'thirteen wide column');
$expireR.innerHTML = `
<div class="ui progress ${progressType}" style="border-radius: 8px; width: 100%;">
<div class="progress-bar" style="border-radius: 8px; transition-duration: 300ms; background-color: ${progressColor}; width: ${percentage}%; padding-left: 0.2em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">
<small style="display: inline-block; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">${labelText}</small> <!-- 这里显示剩余天数和到期日期 -->
</div>
</div>`;
$descriptionGrid.insertBefore($expireR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
}
}
});
});
}
</script>
剩余天数+日期
<script>
window.onload = function() {
// 定义产品的详细数据,包括价格、周期、开始和到期日期以及商家名称
const extraData = {
1: { price: '0.84€', cycle: 'Month', start: '2024-10-30', expire: '2024-10-31', merchant: 'MerchantA' },
2: { price: 'FREE', cycle: 'Month', start: '2021-04-15', expire: '∞', merchant: 'MerchantB' },
3: { price: '24¥', cycle: 'Month', start: '2023-12-24', expire: '2024-12-25', merchant: 'MerchantC' },
4: { price: '5$', cycle: 'Month', start: '2024-03-05', expire: '2024-05-31', merchant: 'MerchantA' },
5: { price: 'FREE', cycle: 'Year', start: '2023-05-03', expire: '2025-04-03', merchant: 'MerchantB' }
};
// 定义商家与其支付页面的 URL 映射
const merchantUrls = {
MerchantA: 'https://merchantA.com/payment',
MerchantB: 'https://merchantB.com/payment',
MerchantC: 'https://merchantC.com/payment'
};
// 设置到期阈值,当进度条超过此百分比时颜色变为红色
const threshold = 80;
// 获取页面上所有的 .ui.accordion 元素
const cats = document.querySelectorAll('.ui.accordion');
cats.forEach((e, i) => {
let $catsTitle = e.querySelector('.title');
let ct = $catsTitle.innerText.trim();
if (ct === '默认') return; // 跳过标题为“默认”的元素
let $itemCard = e.querySelectorAll('.ui.card');
let uiCardCount = $itemCard.length;
$catsTitle.innerHTML = $catsTitle.innerHTML.replace(ct, `${ct} (${uiCardCount})`); // 在标题中显示卡片数量
// 遍历每个卡片,插入价格和到期信息
$itemCard.forEach((ee, ii) => {
let $descriptionGrid = ee.querySelector('.description .ui.grid');
let id = ee.getAttribute('id');
// 确保 id 存在于 extraData 中
if (extraData.hasOwnProperty(id)) {
let { price, start, expire, cycle, merchant } = extraData[id];
if (price) {
// 插入价格标签
let $priceL = document.createElement('div');
$priceL.setAttribute('class', 'three wide column');
$priceL.innerHTML = '价格';
$descriptionGrid.insertBefore($priceL, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
let $priceR = document.createElement('div');
$priceR.setAttribute('class', 'thirteen wide column');
// 在价格标签中插入周期链接,点击后跳转到商家的支付页面
$priceR.innerHTML = `
<div class="ui green label" style="border-radius: 8px; display: inline-block;">
<i class="money bill alternate yellow icon"></i>${price}
<a href="${merchantUrls[merchant]}" target="_blank" class="detail" style="color: inherit; text-decoration: underline;">${cycle}</a>
</div>`;
$descriptionGrid.insertBefore($priceR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
}
if (expire) {
// 插入到期标签
let $expireL = document.createElement('div');
$expireL.setAttribute('class', 'three wide column');
$expireL.innerHTML = '到期';
$descriptionGrid.insertBefore($expireL, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
let $expireR = document.createElement('div');
let beginTime = new Date(start).getTime();
let endTime = expire === '∞' ? Infinity : new Date(expire).getTime();
let nowTime = new Date().getTime();
// 计算总天数、已过去的天数和剩余天数
let totalDays = expire === '∞' ? 1 : Math.ceil((endTime - beginTime) / (1000 * 60 * 60 * 24)); // 总天数
let passedDays = expire === '∞' ? 0 : Math.ceil((nowTime - beginTime) / (1000 * 60 * 60 * 24)); // 已过去的天数
let remainingDays = expire === '∞' ? 0 : Math.ceil((endTime - nowTime) / (1000 * 60 * 60 * 24)); // 剩余天数
if (remainingDays < 0) {
remainingDays = 0; // 设置为0,避免负值
}
// 计算进度条的百分比
let percentage = expire === '∞' ? 100 : (passedDays / totalDays) * 100;
percentage = Math.min(percentage, 100); // 确保不超过100%
// 根据剩余天数设置进度条颜色和标签文本
let progressColor;
let progressType;
let labelText;
if (expire === '∞') {
progressColor = '#48c9b0'; // 绿色代表永久
progressType = 'success';
labelText = '永久'; // 表示这是永久的
} else {
if (nowTime > endTime) {
progressColor = '#7f8c8d'; // 灰色代表已过期
progressType = 'expired';
labelText = '已过期';
percentage = 100; // 进度条宽度设置为100%
} else {
if (percentage >= threshold) {
progressColor = '#e74c3c'; // 红色代表超出阈值
progressType = 'error';
} else {
progressColor = '#48c9b0'; // 绿色代表安全范围
progressType = 'success';
}
// 格式化到期日期和剩余天数
const expireDate = new Date(expire).toISOString().split('T')[0]; // 将日期格式化为 YYYY-MM-DD
labelText = `${expireDate} (${remainingDays}天)`; // 显示到期日期和剩余天数
}
}
// 设置到期进度条的样式
$expireR.setAttribute('class', 'thirteen wide column');
$expireR.innerHTML = `
<div class="ui progress ${progressType}" style="border-radius: 8px; width: 100%;">
<div class="progress-bar" style="border-radius: 8px; transition-duration: 300ms; background-color: ${progressColor}; width: ${percentage}%; padding-left: 0.2em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">
<small style="display: inline-block; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">${labelText}</small> <!-- 这里显示到期日期和剩余天数 -->
</div>
</div>`;
$descriptionGrid.insertBefore($expireR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
}
}
});
});
}
</script>
自动续期
<script>
window.onload = function() {
const extraData = {
1: { price: '0.84€', cycle: 'Month', start: '2024-10-02', merchant: 'MerchantA', autoRenewal: 1 },
2: { price: 'FREE', cycle: 'Month', start: '2021-04-15', merchant: 'MerchantB', autoRenewal: 1 },
3: { price: '24¥', cycle: 'Month', start: '2023-12-24', merchant: 'MerchantC', autoRenewal: 1 },
4: { price: '5$', cycle: 'Month', start: '2024-03-05', merchant: 'MerchantA', autoRenewal: 0 },
5: { price: 'FREE', cycle: 'Year', start: '2023-05-03', merchant: 'MerchantB', autoRenewal: 1 },
6: { price: '10$', cycle: 'Year', start: '∞', merchant: 'MerchantA', autoRenewal: 1 } // Example with start '∞'
};
const merchantUrls = {
MerchantA: 'https://merchantA.com/payment',
MerchantB: 'https://merchantB.com/payment',
MerchantC: 'https://merchantC.com/payment'
};
const threshold = 80;
const cats = document.querySelectorAll('.ui.accordion');
cats.forEach((e, i) => {
let $catsTitle = e.querySelector('.title');
let ct = $catsTitle.innerText.trim();
if (ct === '默认') return;
let $itemCard = e.querySelectorAll('.ui.card');
let uiCardCount = $itemCard.length;
$catsTitle.innerHTML = $catsTitle.innerHTML.replace(ct, `${ct} (${uiCardCount})`);
$itemCard.forEach((ee, ii) => {
let $descriptionGrid = ee.querySelector('.description .ui.grid');
let id = ee.getAttribute('id');
if (extraData.hasOwnProperty(id)) {
let { price, start, cycle, merchant, autoRenewal } = extraData[id];
if (price) {
let $priceL = document.createElement('div');
$priceL.setAttribute('class', 'three wide column');
$priceL.innerHTML = '价格';
$descriptionGrid.insertBefore($priceL, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
let $priceR = document.createElement('div');
$priceR.setAttribute('class', 'thirteen wide column');
$priceR.innerHTML = `
<div class="ui green label" style="border-radius: 8px; display: inline-block;">
<i class="money bill alternate yellow icon"></i>${price}
<a href="${merchantUrls[merchant]}" target="_blank" class="detail" style="color: inherit; text-decoration: underline;">${cycle}</a>
</div>`;
$descriptionGrid.insertBefore($priceR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
}
if (autoRenewal || cycle) {
let $expireL = document.createElement('div');
$expireL.setAttribute('class', 'three wide column');
$expireL.innerHTML = '到期';
$descriptionGrid.insertBefore($expireL, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
let $expireR = document.createElement('div');
let beginTime;
let endTime;
// Handle '∞' case for permanent subscriptions
if (start === '∞') {
beginTime = Infinity;
endTime = Infinity;
} else {
beginTime = new Date(start);
endTime = new Date(start);
if (autoRenewal) {
if (cycle === 'Month') {
while (endTime < new Date()) {
endTime.setMonth(endTime.getMonth() + 1);
}
beginTime.setMonth(endTime.getMonth() - 1); // Set start date to current cycle
} else if (cycle === 'Year') {
while (endTime < new Date()) {
endTime.setFullYear(endTime.getFullYear() + 1);
}
beginTime.setFullYear(endTime.getFullYear() - 1);
}
} else {
if (cycle === 'Month') {
endTime.setMonth(beginTime.getMonth() + 1);
} else if (cycle === 'Year') {
endTime.setFullYear(beginTime.getFullYear() + 1);
}
}
}
let progressColor;
let progressType;
let labelText;
let percentage;
if (start === '∞') {
progressColor = '#48c9b0';
progressType = 'success';
labelText = '永久';
percentage = 100; // Full progress bar for permanent
} else {
const now = new Date();
let totalDays = Math.ceil((endTime - beginTime) / (1000 * 60 * 60 * 24));
let passedDays = Math.ceil((now - beginTime) / (1000 * 60 * 60 * 24));
let remainingDays = Math.ceil((endTime - now) / (1000 * 60 * 60 * 24));
if (remainingDays < 0) remainingDays = 0;
percentage = (passedDays / totalDays) * 100;
if (passedDays <= 1) percentage = 0;
percentage = Math.min(percentage, 100);
if (now > endTime) {
progressColor = '#7f8c8d';
progressType = 'expired';
labelText = '已过期';
percentage = 100;
} else {
if (percentage >= threshold) {
progressColor = '#e74c3c';
progressType = 'error';
} else {
progressColor = '#48c9b0';
progressType = 'success';
}
const expireDate = endTime.toISOString().split('T')[0];
labelText = `${remainingDays}天 (${expireDate})`;
}
}
$expireR.setAttribute('class', 'thirteen wide column');
$expireR.innerHTML = `
<div class="ui progress ${progressType}" style="border-radius: 8px; width: 100%;">
<div class="progress-bar" style="border-radius: 8px; transition-duration: 300ms; background-color: ${progressColor}; width: ${percentage}%; padding-left: 0.2em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">
<small style="display: inline-block; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">${labelText}</small>
</div>
</div>`;
$descriptionGrid.insertBefore($expireR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
}
}
});
});
}
</script>