Tokens Usage Number Formatter

将 DeepSeek 使用量统计图表中的 tokens 数字修改为下划线分隔格式 (如 '342054 tokens' -> '342_054 tokens')

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         Tokens Usage Number Formatter
// @author       ExcuseLme
// @namespace    https://github.com/ExcuseLme
// @version      1.1
// @description  将 DeepSeek 使用量统计图表中的 tokens 数字修改为下划线分隔格式 (如 '342054 tokens' -> '342_054 tokens')
// @match        https://platform.deepseek.com/usage
// @grant        none
// @icon         https://fe-static.deepseek.com/platform/favicon.svg
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

(function () {
  'use strict'

  /**
   * 格式化数字函数
   * 将 342054 转换为 342_054
   */
  const formatNumber = (text) => {
    const regex = /^(\d+)(\s+tokens)$/
    const match = text.match(regex)

    if (match) {
      const num = match[1]
      const unit = match[2]
      // 使用正则每隔三位插入下划线
      const formattedNum = num.replace(/\B(?=(\d{3})+(?!\d))/g, '_')
      return `${formattedNum}${unit}`
    }
    return null
  }

  /**
   * 处理节点函数
   */
  const processNode = (node) => {
    const processTextNode = (textNode) => {
      const originalText = textNode.textContent.trim()
      const newText = formatNumber(originalText)
      if (newText && originalText !== newText) {
        textNode.textContent = newText
      }
    }

    if (node.nodeType === Node.ELEMENT_NODE) {
      // 深度优先检查包含文本的 div
      // 创建自定义过滤器,只处理包含数字的文本节点以提高性能
      const numberFilter = {
        acceptNode: function (textNode) {
          // 只接受包含数字的文本节点
          if (/\d/.test(textNode.textContent)) {
            return NodeFilter.FILTER_ACCEPT
          }
          return NodeFilter.FILTER_SKIP
        }
      }

      const walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, numberFilter)
      let textNode
      while ((textNode = walker.nextNode()) !== null) {
        processTextNode(textNode)
      }
    } else if (node.nodeType === Node.TEXT_NODE) {
      // 直接处理文本节点
      processTextNode(node)
    }
  }

  // 实例化观察器
  const observer = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
      // 监听新增节点(浮窗出现时)
      mutation.addedNodes.forEach(node => {
        processNode(node)
      })
      // 监听文本变化(浮窗内容更新时)
      if (mutation.type === 'characterData' || mutation.type === 'childList') {
        processNode(mutation.target)
      }
    }
  })

  // 配置观察选项:子节点、后代节点、文本内容
  const config = {
    childList    : true,
    subtree      : true,
    characterData: true
  }

  // 开始观察 body 元素
  observer.observe(document.body, config)

  console.log('DeepSeek Tokens Formatter 脚本已启动')
})()