惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google Online Security Blog
Google Online Security Blog
S
Security @ Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
W
WeLiveSecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
博客园 - 司徒正美
雷峰网
雷峰网
L
LINUX DO - 最新话题
博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
V2EX - 技术
V2EX - 技术
S
Security Affairs
有赞技术团队
有赞技术团队
月光博客
月光博客
T
Threatpost
T
Tor Project blog
O
OpenAI News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
博客园 - 三生石上(FineUI控件)
D
Docker
AWS News Blog
AWS News Blog
AI
AI
P
Proofpoint News Feed
K
Kaspersky official blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Securelist
F
Fortinet All Blogs
F
Full Disclosure
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Palo Alto Networks Blog
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
美团技术团队
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog

北门清燕

🎙️ 科技热文播报 - 2026-03-14 【vscode扩展】apis-tester Notion工具人bot VPS橱窗 - 一个简单的哪吒面板主题 ios17.0可以安装Trollstore了 windows服务器安装mysql踩坑指北 为哪吒面板增加视频背景 继续折腾astro serv00部署FreshRSS 【原创】油猴脚本:哪吒VPS橱窗后台脚本 哪吒面板default主题小鸡底部增加购买同款按钮 Typecho二开魔改简单指北 【原创】油猴脚本:论坛快捷回帖 简单米表:Typecho-Simple-Mibiao Windows 11 23H2更新遇到下载错误解决方法 Microsoft 365 E5开发者订阅管理员双重认证丢失解决方法 Virtualbox安装Ubuntu不完全指北 一剑开天门 将chrome谷歌浏览器轻松打造成rss阅读器 地震云 罗刹海市 关于笑果我觉得还是罗翔老师说的好 推荐正在玩的游戏:SimpleMMO,附游戏助手SMMOHelper 集成Elog使用notion数据库 【原创】ios捷径:法定工作日打卡提醒 测试AI 再次折腾hexo docker部署freshrss apifox自动导入apidoc接口数据 node项目部署到ftp vite项目使用tinymce插件axupimgs实现多图片上传 tomcat服务器上utf8编码的文件乱码解决方法 快捷指令:图床 七牛上传视频获取视频封面和缩略图 注销网站得慎重 【原创】ios捷径:捷径库 【原创】ios捷径:自动壁纸 【原创】ios捷径:倒班闹钟 idea找回执行git pull操作后,被覆盖的本地未提交的代码 altserver跳坑指北 吐一吐三丰云免费服务器 Microsoft Store中的应用软件如何备份数据 卖盘 利用frp实现微软远程桌面管理内网电脑之不完全指北 apicloud用tortoisesvn管理代码,实现按不同分支编译打包app vscode插件提示:command 'extension.updateSettings' not found解决方法 apicloud使用alipayplus支付宝支付模块注意事项 【原创】越狱插件安装注意事项 api.closeFrameGroup的一些注意事项 【原创】ios捷径:我的心愿单 【原创】ios捷径:一键获取urlscheme 【原创】ios捷径:一键签到 【原创】ios捷径:qq群一键签到 【原创】ios捷径:百度搜索风云榜2.1.0 【原创】ios捷径:一键天气预报 【原创】ios捷径:微博热搜榜2.0强势更新 ios捷径:bmqy捷径库 自定义IntelliJ IDEA配置和插件的存放目录,以方便同步idea配置 wordpress平台next主题 vscode本地调试asp ajaxFileUpload上传成功也执行error方法 更换回wordpress。。。 一键收取熊猫守护者威力值 vscode软件窗口标题栏显示文件完整路径 微信小程序“支付签名验证失败”问题的解决参考 “idea已连接上ftp但看不到文件”的解决办法 js格式化时间显示 js实现中文转换成拼音 h5移动端ios输入法软键盘导致fixed布局bug的解决方案 生命不息,折腾不止之“hexo” echarts中tooltips自定义数据结构与样式 淘米辅助工具 聚名网辅助工具 仿站制作6 wordpress新添加页面显示评论 华为mate8(b584)root过程简要记录 asp解析json的方法 为子主题增加主题选项功能 自制chrome扩展:百度云分享链接一键登录 清燕的云集小店 Google play下载app状态栏进度显示异常的应对方法 吐槽百度翻译之离线翻译包 现在只有人民才是真正的为人民 吐槽腾讯大王卡 wordpress添加twentysixteen子主题 idea配置less自动编译 使用chrome浏览器调试移动端web页面 idea编译less并使用autoprefixer sublime自动编译less2css插件,保存时提示系统找不到指定文件 吐一吐中信的升白金 Android手机下输入框获取焦点时, 输入法挡住输入框bug的解决方法 wordpress头像不显示解决方法 用子主题functions.php添加自定义功能后访问网站报错解决方法 ueditor百度编辑器添加自定义模板并设为默认 仿站制作5 读老树画画随感 VMware-workstation 12 安装 Mac OS X 10.10 做梦想 再咏咳 webstorm10配置less编译环境
哪吒面板终极进化之VPS橱窗
bmqy · 2024-05-13 · via 北门清燕

javascript

<script>
// 联系信息
var contacts = {
  main: 'telegram',
  animatedType: 'vertical',
  telegram: {
    label: 'TG',
    icon: 'telegram plane',
    url: 'https://t.me/bmqyChatBot'
  },
  qq: {
    label: 'QQ',
    icon: 'qq',
    url: 'https://wpa.qq.com/msgrd?V=3&Uin=88268459&Site=nezha.887776.xyz&menu=yes'
  },
  email: {
    label: 'Email',
    icon: 'mail',
    url: 'mailto:notice@bmqy.net'
  },
}
</script>

javascript

<script>
// 默认分组模式
if(!localStorage.getItem("showGroup")){
    localStorage.setItem("showGroup", true);
}
// 默认暗黑模式
if(!localStorage.getItem("theme")){
    localStorage.setItem("theme", 'dark');
}
// 默认半透明效果
if(!localStorage.getItem("semiTransparent")){
    localStorage.setItem("semiTransparent", 'false');
}
window.onload = function(){
	// 必要函数
  var nvwDeepCopy = function(obj) {
    if (obj === null || typeof obj !== 'object') {
      return obj;
    }
    const copy = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        copy[key] = nvwDeepCopy(obj[key]);
      }
    }
    return copy;
  }
  var nvwGetCurrentServer = (id)=>{
    if(!id){
      return null;
    }
    let arr = servers.filter(e=>{
      return e['ID'] == id;
    })
    if(arr[0]){
      return arr[0];
    }
    return null;
  }
  
  // 获取VPS数据
  var serversHtmlMatch = document.body.innerHTML.match(/(?<=this\.servers \= JSON.parse\(\')[\s\S]+(?=\'\)\.servers;)/g);
  if(!serversHtmlMatch){
    console.log('%cVPS橱窗提示:请先升级哪吒面板到v0.19.13+', 'padding:0 8px;background:red;color:#fff;line-height:1.8;');
    return false;
  }
  var servers = JSON.parse(serversHtmlMatch[0].replace(/\\u0022/g, '"').replace(/\\\\r/g, '').replace(/\\\\n/g, '').replace(/\\"/g, '"')).servers;
  
  // 判断版本
  var $version = document.body.innerText.match(/(哪吒监控\s+[0-9\.]+)/g);
  if($version){
    var $versionText = $version[0].split(' ')[1];
    $versionArr = $versionText.split('.');
    $versionArr.forEach((e,i)=>{
      if(e[0]<=0){
        if(e[1]<19){
          console.log('%cVPS橱窗提示:请先升级哪吒面板到v0.19.13+', 'padding:0 8px;background:red;color:#fff;line-height:1.8;');
          return false;
        } else {
          if(e[1]==19 && e[2]<13){
            console.log('%cVPS橱窗提示:请先升级哪吒面板到v0.19.13+', 'padding:0 8px;background:red;color:#fff;line-height:1.8;');
            return false;
          }
        }
      }
    });
  }
  
  // 数据处理
  servers.forEach(item=>{
    item.PublicNote = item.PublicNote ? JSON.parse(item.PublicNote) : null;
  });
  
  const commonContacts = 'none';
  const cycleNames = {
    '年付': 'year',
    '半年付': 'half',
    '季付': 'quarterly',
    '月付': 'month',
    '年': 'year',
    '半': 'half',
    '季': 'quarterly',
    '月': 'month',
    'Year': 'year',
    'Half': 'half',
    'Quarterly': 'quarterly',
    'Month': 'month',
    'Y': 'year',
    'H': 'half',
    'Q': 'quarterly',
    'M': 'month',
    'year': 'year',
    'half': 'half',
    'quarterly': 'quarterly',
    'month': 'month',
  }
  const cycleValues = {
    year: 365,
    half: 180,
    quarterly: 90,
    month: 30,
  }
  // 判断当前主题
  const cookie = document.cookie;
  let preferredTheme = document.body.innerHTML.match(/(?<=defaultTemplate: ")(default|server-status)(?=")/g) ? document.body.innerHTML.match(/(?<=defaultTemplate: ")(default|server-status)(?=")/g)[0] : 'default';
  preferredTheme = document.cookie.match(/(server-status|default)/g) ? document.cookie.match(/(server-status|default)/g)[0] : preferredTheme;
  // 默认主题
  if(preferredTheme === 'default'){
    const cats = document.querySelectorAll('.ui.accordion');
    cats.forEach((e, i)=>{
      let $catsTitle = e.querySelector('.title');
      let ct = $catsTitle.innerText;
      ct = ct.trim();	
      
      let $itemCard = e.querySelectorAll('.ui.card');
      let uiCardCount = $itemCard.length;
      $catsTitle.innerHTML = $catsTitle.innerHTML.replace(ct, ct+ ' ('+ uiCardCount +')');
      $itemCard.forEach((ee, ii)=>{
        let $content = ee.querySelector('.content');
        let $descriptionGrid = ee.querySelector('.description .ui.grid');
        let $itemTitle = $content.querySelector('.header');
        let id = ee.getAttribute('id');
        let extraData = nvwGetCurrentServer(id);
        if(extraData && extraData.PublicNote){
          let affLink = extraData.PublicNote.affLink;
          let price = extraData.PublicNote.price;
          let start = extraData.PublicNote.start;
          let expire = extraData.PublicNote.expire;
          let cycle = extraData.PublicNote.cycle;
          let autoPay = extraData.PublicNote.autoPay;
          let cycleName = cycleNames[cycle];
          let cycleValue = cycleValues[cycleName];
          let nowTime = parseInt(new Date().getTime() / 1000);
          let beginTime = parseInt(new Date(start).getTime() / 1000);
          if(autoPay && autoPay=='是'){
            let beginDate = new Date(start);
            let nowDate = new Date();
            let mSteps = {
              year: 12,
              half: 6,
              quarterly: 3,
              month: 1,
            }
            expire = beginDate.setMonth(beginDate.getMonth() + mSteps[cycleName]);
            expire = new Date(expire);
            while(expire.getTime() < nowDate.getTime()){
              expire = expire.setMonth(expire.getMonth() + mSteps[cycleName]);
              expire = new Date(expire);
            }
            expire = expire.toLocaleDateString();
          }
          let endTime = parseInt(new Date(expire).getTime() / 1000);
          
          // 购买同款按钮
          let $aButtonsBox = document.createElement('div');
          $aButtonsBox.setAttribute('style', 'margin-bottom: .5em;text-align:right;');
          let $aLinkButtons = document.createElement('div');
          $aLinkButtons.setAttribute('class', 'btn-buy-box ui buttons mini');
          let $aLinkBuy = document.createElement('a');
          $aLinkBuy.setAttribute('class', 'ui btn-buy button positive');
          $aLinkBuy.setAttribute('target', affLink ? '_blank' : '');
          $aLinkBuy.innerHTML = '购买同款';
          $aLinkBuy.href = affLink ? affLink : 'javascript:void(0);';
          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', 'price-box thirteen wide column');
            $priceR.innerHTML = '<div class="ui red label"><i class="money bill alternate yellow icon"></i>'+ price +'<a class="detail">'+ 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 aTime = (nowTime-beginTime);
            let bTime = (endTime-beginTime);
            let cTime = parseInt(aTime / bTime * 100);
            let progressType = 'red';
            let textStyle = 'text-shadow: 0px 0px 5px #db2828;left:.5em;text-align: right;';
            if(expire === '∞'){
              progressType = 'success';
              textStyle = '';
            }
            $expireR.setAttribute('class', 'expire-box thirteen wide column');
            $expireR.innerHTML = '<div class="ui indicating progress '+ progressType +' active"><div class="bar" style="line-height: 1em !important;transition-duration: 300ms; min-width: unset; width: '+ cTime +'% !important;padding-left: 0.4em;"><div class="progress" style="'+ textStyle +'">'+ expire +'</div></div></div>';
            $descriptionGrid.insertBefore($expireR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length-3])
          }
          $aLinkButtons.append($aLinkBuy);
          let $aLinkOr = document.createElement('div');
          $aLinkOr.innerHTML = '<div class="or" data-text="or"></div>';
          $aLinkButtons.append($aLinkOr);
          // 购买同款按钮右侧联系方式
          let priceValue = price.replace(/[$¥P€]/g, '');
          let priceUnit = price.match(/[$¥P€]/g)[0];
          let remainingDays = Math.floor((endTime - nowTime) / (24 * 60 * 60));
          let remainingPrice = parseFloat(priceValue) / cycleValue  * remainingDays;
          if(!remainingPrice){
            remainingPrice = 0;
          }
          remainingPrice = remainingPrice.toFixed(2);
          
          try{
            let remainingAnimatedType = contacts['animatedType'];
            let mainContact = contacts['main'];
            // 购买同款按钮右侧主要联系方式显示剩余价值
            let $aLinkContactMain = document.createElement('a');
            $aLinkContactMain.setAttribute('class', 'contact-main ui button '+ remainingAnimatedType +' animated blue');
            $aLinkContactMain.setAttribute('target', '_blank');
            $aLinkContactMain.innerHTML = '<div class="hidden content" style="padding:0;" title="剩余价值">'+ contacts[mainContact].label +'议价</div><div class="visible content" style="padding:0;" title="剩余价值"><i class="'+ contacts[mainContact].icon +' icon" style="color:white;"></i>'+ priceUnit + remainingPrice +'</div>';
            $aLinkContactMain.href = contacts[mainContact].url;
            $aLinkButtons.append($aLinkContactMain);
            $aButtonsBox.append($aLinkButtons);
            // 购买同款按钮右侧其它联系方式
            for(let key in contacts){
              if(key!='main' && key!='animatedType' && key!=contacts['main']){
                let icon = contacts[key].icon;
                let $aLinkContact = document.createElement('a');
                $aLinkContact.setAttribute('class', 'contact-btn ui circular '+ icon +' mini icon button');
                $aLinkContact.setAttribute('target', '_blank');
                $aLinkContact.setAttribute('style', 'margin-left:.5em;');
                $aLinkContact.innerHTML = '<i class="'+ icon +' icon"></i>';
                $aLinkContact.href = contacts[key].url;
                $aButtonsBox.append($aLinkContact);
              }
            }
          } catch(error){
            console.log('%cVPS橱窗提示:当前未配置 contacts 信息', 'padding:0 8px;background:orange;color:#fff;line-height:1.8;');
            let remainingAnimatedType = 'vertical';
            // 购买同款按钮右侧主要联系方式显示剩余价值
            let $aLinkContactMain = document.createElement('a');
            $aLinkContactMain.setAttribute('class', 'contact-main ui button '+ remainingAnimatedType +' animated blue');
            $aLinkContactMain.setAttribute('target', '_blank');
            $aLinkContactMain.innerHTML = '<div class="hidden content" style="padding:0;" title="剩余价值">剩余价值</div><div class="visible content" style="padding:0;min-width: 40px;" title="剩余价值">'+ priceUnit + remainingPrice +'</div>';
            $aLinkButtons.append($aLinkContactMain);
            $aButtonsBox.append($aLinkButtons);
          }
          $content.append($aButtonsBox);
        }
      });
    });
  }
  // ServerStatus主题
  function bindToggleViewClick(){
    let $toggleView = document.querySelector('aside.toolbox .toggleView')
    $toggleView && $toggleView.addEventListener('click', ()=>{
      setTimeout(function(){
        location.reload();
      }, 0);
    });
  }
  if(preferredTheme === 'server-status'){
    bindToggleViewClick();
    let $biThreeDots = document.querySelector('aside.toolbox .bi-three-dots');
    $biThreeDots && $biThreeDots.addEventListener('click', ()=>{
      bindToggleViewClick();
    });
    
    let $tables = document.querySelectorAll('.table.table-condensed');
    $tables.forEach(e=>{
      $tableTh = e.querySelector('.node-group-tag th');
      $list = e.querySelectorAll('tr.accordion-toggle');
      $tableTh && ($tableTh.innerText += '('+ $list.length +')');
      
      let $head = e.querySelector('table.table-condensed thead').lastChild;
      let $servers = e.querySelector('#servers');
      // 隐藏三列:系统、在线天数、负载
      $head.querySelector('th.os').style.display = 'none';
      $head.querySelector('th.uptime').style.display = 'none';
      $head.querySelector('th.load').style.display = 'none';
      // 添加三列
      let $expireTh = document.createElement('th');
      $expireTh.innerText = '到期 / 剩余价值';
      $expireTh.setAttribute('class', 'node-cell expire center');
      $head.insertBefore($expireTh, $head.childNodes[3]);
      
      let $buyTh = document.createElement('th');
      $buyTh.innerText = '购买同款';
      $buyTh.setAttribute('class', 'node-cell expire center');
      $head.append($buyTh);
      
      try{
        console.log(contacts);
        let $contactTh = document.createElement('th');
        $contactTh.innerText = '议价';
        $contactTh.setAttribute('class', 'node-cell expire center');
        $head.append($contactTh);
      } catch(error){
          console.log('%cVPS橱窗提示:当前未配置 contacts 信息', 'padding:0 8px;background:orange;color:#fff;line-height:1.8;');
      }
      
      $servers.querySelectorAll('tr.accordion-toggle').forEach(ee=>{
        ee.querySelector('td.os').style.display = 'none';
        ee.querySelector('td.uptime').style.display = 'none';
        ee.querySelector('td.load').style.display = 'none';
        
        let id = ee.getAttribute('id');
        id = id.replace('r', '');
        let extraData = nvwGetCurrentServer(id);
        if(extraData && extraData.PublicNote){
          let affLink = extraData.PublicNote.affLink;
          let price = extraData.PublicNote.price;
          let start = extraData.PublicNote.start;
          let expire = extraData.PublicNote.expire;
          let cycle = extraData.PublicNote.cycle;
          let autoPay = extraData.PublicNote.autoPay;
          let cycleName = cycleNames[cycle];
          let cycleValue = cycleValues[cycleName];
          let nowTime = parseInt(new Date().getTime() / 1000);
          let beginTime = parseInt(new Date(start).getTime() / 1000);
          if(autoPay && autoPay=='是'){
            let beginDate = new Date(start);
            let nowDate = new Date();
            let mSteps = {
              year: 12,
              half: 6,
              quarterly: 3,
              month: 1,
            }
            expire = beginDate.setMonth(beginDate.getMonth() + mSteps[cycleName]);
            expire = new Date(expire);
            while(expire.getTime() < nowDate.getTime()){
              expire = expire.setMonth(expire.getMonth() + mSteps[cycleName]);
              expire = new Date(expire);
            }
            expire = expire.toLocaleDateString();
          }
          let endTime = parseInt(new Date(expire).getTime() / 1000);
          
          if(expire || price){
            // 到期时间、剩余价值列
            let $expireTd = document.createElement('td');
            $expireTd.setAttribute('class', 'node-cell expire');
            let aTime = (nowTime-beginTime);
            let bTime = (endTime-beginTime);
            let cTime = parseInt(aTime / bTime * 100);
            let progressType = 'danger';
            if(expire === '∞'){
              progressType = 'warning';
            }
            
            let priceValue = price.replace(/[$¥P€]/g, '');
            let priceUnit = price.match(/[$¥P€]/g)[0];
            let remainingDays = Math.floor((endTime - nowTime) / (24 * 60 * 60));
            let remainingPrice = parseFloat(priceValue) / cycleValue  * remainingDays;
            if(!remainingPrice){
              remainingPrice = 0;
            }
            remainingPrice = remainingPrice.toFixed(2);
            $expireTd.innerHTML = '<div class="progress progress-expire"><div class="progress-bar progress-bar-'+ progressType +' progress-bar-striped active" style="width: '+ cTime +'%;padding-right:5px;background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);"><small class="progress" style="white-space: nowrap;background-color: transparent !important;background-image: unset;">'+ expire +' / '+ priceUnit + remainingPrice +'</small></div></div>';
            ee.insertBefore($expireTd, ee.childNodes[3]);
          }
          // 购买同款列
          let $buyTd = document.createElement('td');
          $buyTd.setAttribute('class', 'node-cell buy');
          $buyTd.setAttribute('style', 'text-align:center;');
          let $buyTdBtn = document.createElement('div');
          $buyTdBtn.setAttribute('class', 'ui left labeled button');
          let $buyTdBtnLabel = document.createElement('div');
          $buyTdBtnLabel.setAttribute('class', 'ui basic label mini');
          $buyTdBtnLabel.setAttribute('style', 'min-height: 20px;padding:0 .5em;height: 20px;font-weight:normal;line-height: 20px;font-size:.78571429rem;');
          $buyTdBtnLabel.innerHTML = price +' / '+ cycle;
          $buyTdBtn.append($buyTdBtnLabel);
          let $buyTdBtnLabelIcon = document.createElement('a');
          $buyTdBtnLabelIcon.setAttribute('class', 'ui icon button mini green');
          $buyTdBtnLabelIcon.setAttribute('style', 'min-height: 20px;padding:0 .5em;height: 20px;line-height: 20px;');
          $buyTdBtnLabelIcon.setAttribute('target', affLink ? '_blank' : '');
          $buyTdBtnLabelIcon.addEventListener('click', (e)=>{e.stopPropagation()});
          $buyTdBtnLabelIcon.innerHTML = '<i class="shopping cart icon"></i>';
          $buyTdBtnLabelIcon.href = affLink ? affLink : 'javascript:void(0);';
          $buyTdBtn.append($buyTdBtnLabelIcon);
          $buyTd.append($buyTdBtn);
          ee.append($buyTd);
          // 联系方式列
          try {
            let $contactTd = document.createElement('td');
            $contactTd.setAttribute('class', 'node-cell contact');
            $contactTd.setAttribute('style', 'text-align:center;white-space:nowrap;');
            for(let key in contacts){
              if(key!='main' && key!='animatedType'){
                let $contactTdContactBtn = document.createElement('a');
                let contactIcon = contacts[key].icon;
                $contactTdContactBtn.setAttribute('class', 'ui circular '+ contactIcon +' icon button mini blue');
                $contactTdContactBtn.setAttribute('style', 'min-height: 20px;padding:0 .5em;height: 20px;line-height: 20px;');
                $contactTdContactBtn.setAttribute('target', '_blank');
                $contactTdContactBtn.addEventListener('click', (e)=>{e.stopPropagation()});
                $contactTdContactBtn.innerHTML = '<i class="'+ contactIcon +' icon"></i>';
                $contactTdContactBtn.href = contacts[key].url;
                $contactTd.append($contactTdContactBtn);
              }
            }
            ee.append($contactTd);
          } catch(error){
          };
        } else {
          // 无附加信息时显示占位符
          let $expireTd = document.createElement('td');
          $expireTd.setAttribute('class', 'node-cell expire');
          $expireTd.setAttribute('style', 'text-align:center;');
          $expireTd.innerHTML = '-';
          ee.insertBefore($expireTd, ee.childNodes[3]);
          let $buyTd = document.createElement('td');
          $buyTd.setAttribute('class', 'node-cell buy');
          $buyTd.setAttribute('style', 'text-align:center;');
          $buyTd.innerHTML = '-';
          ee.append($buyTd);
          try {
            console.log(contacts);
            let $contactTd = document.createElement('td');
            $contactTd.setAttribute('class', 'node-cell contact');
            $contactTd.setAttribute('style', 'text-align:center;');
            $contactTd.innerHTML = '-';
            ee.append($contactTd);
          } catch(error){
          }
}
      });
    });
  }
}
</script>

javascript

// 公开备注:为避免与官方主题配置冲突,请按下面设置
{
    "affLink": "https://get.crunchbits.com/order/lblk-yearly-kvm-ssd-vps/84",
    "price": "$27.38",
    "cycle": "Year",
    "start": "08/13/2023",
    "expire": "08/13/2025",
    "autoPay": "否"
}

javascript

<script>
window.onload = function(){
  const extraDataKeyName = {
    affLink: "推广链接",
    price: "购买价格",
    cycle: "付款周期",
    start: "购买日期",
    expire: "过期时间",
    autoPay: '自动续费',
  }
  const cycleOptions = [
    '年付',
    '半年付',
    '季付',
    '月付',
    '年',
    '半',
    '季',
    '月',
    'Year',
    'Half',
    'Quarterly',
    'Month',
    'Y',
    'H',
    'Q',
    'M',
    'year',
    'half',
    'quarterly',
    'month',
  ];
  const autoPayOptions = [
    '否',
    '是'
  ];
  let timmer = null;
  let changer = false;
  const pathname = location.pathname;
  const $footer = document.querySelector('.footer');
  if(!$footer || $footer.innerText.indexOf('Powered by 哪吒监控')==-1) return false;

  if(pathname === '/server'){
    const $table = document.querySelector('table.table');
    const $tableTr = $table.querySelectorAll('tbody tr');
    $tableTr.forEach(e=>{
      let $tds = e.querySelectorAll('td');
      let $publicNoteTd = $tds[11];
      let $publicNoteBtton = $publicNoteTd.querySelector('button');
      if(!$publicNoteBtton) return;
      for(let key in extraDataKeyName){
        $publicNoteBtton.title = $publicNoteBtton.title.replace(key, extraDataKeyName[key]);
      }
    });
  }
  
  function nvwSuiAlert(message, type){
    if(!message){
      return false;
    }
    $.suiAlert({
        title: '',
        description: message,
        type: type || 'info',
        time: '3',
        position: 'top-center',
    });
  }
}
</script>