Greasy Fork

Greasy Fork is available in English.

小红书广告数据查询与展示

在当前页面插入悬浮元素,点击展开窗口并发送请求,将结果展示在表格中并提供Excel下载按钮

// ==UserScript==
// @name         小红书广告数据查询与展示
// @namespace    http://tampermonkey.net/
// @version      1.41
// @description  在当前页面插入悬浮元素,点击展开窗口并发送请求,将结果展示在表格中并提供Excel下载按钮
// @author       You
// @match        https://ad.xiaohongshu.com/aurora*
// @grant        GM_xmlhttpRequest
// @connect      ad.xiaohongshu.com
// @license MIT
// ==/UserScript==

(function () {
  "use strict";
  // 
  // 
  // 进度条类定义
class ChainProgress {
  constructor() {
    this.totalSteps = 0;
    this.currentStep = 0;
    this.initDOM();
  }

  // 初始化DOM结构(参考材料1†、3†)
  initDOM() {
    this.progressContainer = document.createElement('div');
    this.progressBar = document.createElement('div');
    this.stepDots = document.createElement('div');
    
    Object.assign(this.progressContainer.style, {
      position: 'fixed',
      bottom: '0',
      left: '0',
      width: '100%',
      height: '8px',
      backgroundColor: '#eee',
      "z-index":2147483647
    });

    Object.assign(this.progressBar.style, {
      width: '0%',
      height: '100%',
      backgroundColor: '#4CAF50',
      transition: 'width 0.3s ease' // 添加平滑过渡(材料5†)
    });

    Object.assign(this.stepDots.style, {
      position: 'absolute',
      top: '-20px',
      display: 'flex',
      justifyContent: 'space-between',
      width: '100%'
    });

    this.progressContainer.appendChild(this.progressBar);
    this.progressContainer.appendChild(this.stepDots);
    document.body.appendChild(this.progressContainer);
  }

  // 设置总步数(材料6†)
  setTotal(steps) {
    this.totalSteps = steps;
    this.currentStep = 0;
    this.stepDots.innerHTML = Array(steps)
      .fill('<div style="width:20px;height:20px;border-radius:50%;background:#ddd"></div>')
      .join('');
  }

  // 推进进度(材料4†)
  next() {
    if(++this.currentStep > this.totalSteps) return;
    
    // 更新进度条(材料2†)
    const progress = (this.currentStep / this.totalSteps) * 100;
    this.progressBar.style.width = `${progress}%`;
    
    // 更新步骤点(链式效果)
    const dots = this.stepDots.children;
    if(dots[this.currentStep-1]) {
      dots[this.currentStep-1].style.background = '#4CAF50';
    }

    // 完成处理(材料5†)
    if(this.currentStep === this.totalSteps) {
      setTimeout(() => {
        this.progressBar.style.width = '0%';
        this.stepDots.innerHTML = '';
      }, 2000);
    }
  }
}

/* -------------------- 使用示例 -------------------- */
// const progress = new ChainProgress();

// // 初始化设置总步数
// progress.setTotal(5); 

// // 每次事件成功调用
// document.querySelector('.btn').addEventListener('click', () => {
//   progress.next();
// });
  // 
  // □
  // 创建日志系统核心类
  class XinliuLogger {
    constructor() {
      this.maxEntries = 200; // 最大存储200条
      this.entries = [];
      this.initUI();
    }

    // 初始化界面
    initUI() {
      GM_addStyle(`
            #xinliu-logger {
                position: fixed;
                bottom: 20px;
                right: 20px;
                width: 380px;
                height: 260px;
                background: rgba(40,40,40,0.95);
                color: #fff;
                font: 13px/1.5 'Consolas', monospace;
                z-index: 99999;
                border: 1px solid #555;
                box-shadow: 0 4px 12px rgba(0,0,0,0.2);
                border-radius: 6px;
                overflow: hidden;
            }
            .log-header {
                padding: 8px 12px;
                background: #333;
                border-bottom: 1px solid #444;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }
            .log-content {
                height: calc(100% - 40px);
                overflow-y: auto;
                padding: 8px;
            }
            .log-entry {
                margin: 4px 0;
                padding: 6px;
                border-radius: 3px;
                animation: fadeIn 0.3s;
            }
            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(10px); }
                to { opacity: 1; transform: translateY(0); }
            }
            .log-entry.info { background: rgba(26,82,118,0.7); }
            .log-entry.warn { background: rgba(183,149,11,0.7); }
            .log-entry.error { background: rgba(146,43,33,0.7); }
            .timestamp { color: #7f8c8d; margin-right: 10px; }
            .close-btn {
                background: #666;
                border: none;
                color: #fff;
                border-radius: 3px;
                padding: 2px 8px;
                cursor: pointer;
            }
        `);

      this.container = document.createElement("div");
      this.container.id = "xinliu-logger";
      this.container.innerHTML = `
            <div class="log-header">
                <span>Xinliu Logger v1.1</span>
                <button class="close-btn" onclick="this.parentElement.parentElement.style.display='none'">×</button>
            </div>
            <div class="log-content"></div>
        `;
      document.querySelector("body").appendChild(this.container);
      this.contentEl = this.container.querySelector(".log-content");
    }

    // 核心日志方法
    addEntry(level, ...args) {
      const timestamp = new Date().toLocaleTimeString();
      const message = args
        .map((arg) =>
          typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)
        )
        .join(" ");

      // 创建日志条目
      const entryEl = document.createElement("div");
      entryEl.className = `log-entry ${level}`;
      entryEl.innerHTML = `
            <span class="timestamp">[${timestamp}]</span>
            ${message}
        `;

      // 添加并维护条目数量
      this.contentEl.appendChild(entryEl);
      this.entries.push(entryEl);
      if (this.entries.length > this.maxEntries) {
        this.contentEl.removeChild(this.entries.shift());
      }

      // 自动滚动到底部
      this.contentEl.scrollTop = this.contentEl.scrollHeight;
    }

    // 公开的日志方法
    info(...args) {
      this.addEntry("info", ...args);
    }
    warn(...args) {
      this.addEntry("warn", ...args);
    }
    error(...args) {
      this.addEntry("error", ...args);
    }
  }

  // 初始化日志系统
  // window.log = new XinliuLogger();

  // // 使用示例
  // setTimeout(() => {
  //     log.info('系统初始化完成');
  //     log.warn('检测到非标准分辨率', window.screen.width + 'x' + window.screen.height);
  //     log.error('API请求失败', {
  //         status: 404,
  //         url: location.href
  //     });
  // }, 1000);

  // 获取版本号
  const getVersion = () => GM_info.script.version;
  function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  //提示==========

  // 注入样式
  const style = document.createElement("style");
  style.textContent = `
.custom-toast {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    padding: 12px 24px;
    border-radius: 4px;
    background: #333;
    color: white;
    box-shadow: 0 2px 8px rgba(0,0,0,0.2);
    opacity: 0;
    transition: all 0.3s ease;
    z-index: 9999;
    top: 20px;
    margin-top: 0;
}
.custom-toast.show {
    opacity: 1;
    margin-top: 0 !important;
}
.custom-toast.success { background: #67c23a; }
.custom-toast.warning { background: #e6a23c; }
.custom-toast.error { background: #f56c6c; }
.custom-toast.info { background: #909399; }
`;
  document.head.appendChild(style);

  // 提示队列管理
  const toastStack = {
    list: [],
    add(toast) {
      this.list.push(toast);
      this.updatePositions();
    },
    remove(toast) {
      this.list = this.list.filter((t) => t !== toast);
      this.updatePositions();
    },
    updatePositions() {
      this.list.forEach((toast, index) => {
        const baseTop = 20;
        const spacing = 60;
        const targetTop = baseTop + index * spacing;
        toast.style.top = `${targetTop}px`;
      });
    },
  };

  // 提示函数
  window.showToast = function (message, type = "info", duration = 3000) {
    const toast = document.createElement("div");
    toast.className = `custom-toast ${type}`;
    toast.textContent = message;

    document.body.appendChild(toast);
    void toast.offsetHeight; // 触发重绘

    toastStack.add(toast);
    toast.classList.add("show");

    setTimeout(() => {
      toast.classList.remove("show");
      setTimeout(() => {
        toast.remove();
        toastStack.remove(toast);
      }, 300);
    }, duration);
  };

  // // 使用示例
  // showToast('第一个提示', 'success');
  // setTimeout(() => showToast('第二个提示在下方', 'error'), 500);
  // setTimeout(() => showToast('第三个提示继续下移', 'info'), 1000);

  //提示----------

  //圆球=====================
  const sheet = new CSSStyleSheet();
  sheet.replaceSync(`
    /* 加载转圈圈 */
.loading {
  width: 30px;
  height: 30px;
  border: 2px solid #000;
  border-top-color: transparent;
  border-radius: 100%;

  animation: circle infinite 0.75s linear;
}
/* 加载转圈圈动画 */
@keyframes circle {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* 下面是卡片的样式 */
      #overlay {
        position: fixed;
        top: 50%;
        left: 50%;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        z-index: 999;
        transform: translate(-50%, -50%);
      }
      #card {
        position: fixed;
        top: 50%;
        left: 50%;
        width: 500px; /* 设置卡片的宽度 */
        height: 300px; /* 设置卡片的高度 */
        background-color: white;
        border: 1px solid #0057ff ;
        padding: 20px;
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        z-index: 2147483647;
        transform: translate(-50%, -50%);
        border-radius: 8px
      }

/* 下面是卡片中输入框还有下拉框的样式 */

 #card select {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    box-sizing: border-box;
    border: 2px solid #ccc;
    border-radius: 4px;
    background-color: #f8f8f8;
    font-size: 16px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
    background-repeat: no-repeat;
    background-position: right 10px top 50%;
    background-size: 12px 12px;
}

 #card label {
    display: block;
    margin-bottom: 8px;
    font-size: 16px;
    color: #333;
    font-weight: bold;
}
    #card input[type="text"],#card textarea {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    box-sizing: border-box;
    border: 2px solid #ccc;
    border-radius: 4px;
    background-color: #f8f8f8;
    font-size: 16px;
}
    #card button,.card button {
    margin-bottom: 10px;
    margin-top: 10px;
    margin-left: 10px;
margin-right: 10px;
    padding: 8px 16px;
    background-color: rgb(0, 102, 204);
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;

}

  `);

  function addStyleSheet(sheet) {
    const allSheets = [...document.adoptedStyleSheets, sheet];
    document.adoptedStyleSheets = allSheets;
  }
  addStyleSheet(sheet);
  // 存储请求返回的数据
  let responseData = [];

  function addBallAttributes(ball, text) {
    ball.style.cssText = `
      position: fixed;
      right: 10px;
      bottom: 10px;
      width: 60px;
      height: 60px;
      background-color: #0066CC;
      border-radius: 50%;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 12px;
      color: white;
      z-index: 9999;
    `;
    ball.textContent = text;
  }
  // 创建隐藏的小球元素
  const ball = document.createElement("div");
  addBallAttributes(ball, "检查链接");
  document.body.appendChild(ball);

  // 创建悬浮窗口元素
  const floatingWindow = document.createElement("div");
  floatingWindow.style.cssText = `
    position: fixed;
    right: 20px;
    top: 20px;
    width: 50vw;
    height: 80vh;
    background-color: white;
    border: 1px solid #0066CC;
    border-radius: 8px;
    display: none;
    padding: 20px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    z-index: 9999;
  `; // 改成 cssom
  document.body.appendChild(floatingWindow);

  // 创建关闭按钮
  const closeButton = document.createElement("div");
  closeButton.style.cssText = `
    position: absolute;
    right: 10px;
    top: 10px;
    cursor: pointer;
    font-size: 20px;
    color: #0066CC;
  `; // 改成 cssom
  closeButton.innerHTML = "×";
  floatingWindow.appendChild(closeButton);

  // 创建按钮容器
  const buttonContainer = document.createElement("div");
  buttonContainer.style.cssText = `
    margin-bottom: 20px;
  `; // 改成 cssom
  floatingWindow.appendChild(buttonContainer);
  function addButtonAttributes(checkButton, text) {
    checkButton.textContent = text; //"检查";
    checkButton.style.cssText = `
      margin-right: 10px;
      padding: 8px 16px;
      background-color: #0066CC;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    `; // 改成 cssom
  }
  // 创建检查按钮
  const checkButton = document.createElement("button");
  addButtonAttributes(checkButton, "检查");
  buttonContainer.appendChild(checkButton);

  // 创建下载按钮
  const downloadButton = document.createElement("button");
  addButtonAttributes(downloadButton, "下载");
  buttonContainer.appendChild(downloadButton);

  // 创建链接统计文本容器
  const linkStatsContainer = document.createElement("div");
  linkStatsContainer.style.cssText = `
    margin-bottom: 20px;
    font-size: 14px;
    color: #333333;
  `; // 改成 cssom
  floatingWindow.appendChild(linkStatsContainer);

  // 创建表格容器
  const tableContainer = document.createElement("div");
  tableContainer.style.cssText = `
    height: calc(100% - 100px);
    overflow-y: auto;
    overflow-x: auto;
  `; // 改成 cssom
  floatingWindow.appendChild(tableContainer);

  // 创建进度条
  const progressBar = document.createElement("progress");
  progressBar.style.cssText = `
    width: 100%;
    margin-top: 10px;
    display: none;
  `; // 改成 cssom
  progressBar.value = 0;
  progressBar.max = 100;
  floatingWindow.appendChild(progressBar);

  // 显示小球
  ball.style.display = "flex";

  // 点击小球展开悬浮窗口
  ball.addEventListener("click", function () {
    floatingWindow.style.display = "block";
    ball.style.display = "none";
  });

  // 点击关闭按钮
  closeButton.addEventListener("click", function () {
    floatingWindow.style.display = "none";
    ball.style.display = "flex";
    tableContainer.innerHTML = "";
    linkStatsContainer.innerHTML = "";
    responseData = []; // 清空存储的数据
  });

  // 点击检查按钮发送请求
  checkButton.addEventListener("click", function () {
    checkButton.disabled = true;
    checkButton.style.backgroundColor = "rgb(105, 102, 102)";
    const loading = document.createElement("div");
    loading.className = "loading";
    loading.id = "loading-indicator"; // 添加一个唯一ID
    tableContainer.appendChild(loading);
    sendRequest().then(() => {
      checkButton.disabled = false;
      checkButton.style.backgroundColor = "rgb(0, 102, 204)";

      // 使用更安全的方式移除loading
      const loadingElement = document.getElementById("loading-indicator");
      if (loadingElement) {
        loadingElement.remove();
      }
    });
  });

  // 点击下载按钮
  downloadButton.addEventListener("click", function () {
    if (responseData.length > 0) {
      console.log(responseData);
      downloadExcel(responseData);
    } else {
      alert("没有可下载的数据!");
    }
  });

  // 发送请求
  async function sendRequest() {
    let maxPageNum = 4;
    let pageNum = 1;
    let totalPage = 1;
    let allData = [];

    do {
      const headers = {
        accept: "application/json, text/plain, */*",
        "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        "content-type": "application/json;charset=UTF-8",
        priority: "u=1, i",
        "sec-ch-ua":
          '"Not A(Brand";v="8", "Chromium";v="132", "Microsoft Edge";v="132"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        Referer: location.href,
        Origin: location.origin,
        "User-Agent": navigator.userAgent,
      };

      if (location.href.indexOf("vSellerId") != -1) {
        headers["v-seller-id"] = location.search.match(
          /(?<=vSellerId=)[0-9a-z].*/g
        );
      }
      const response = await fetch(
        `https://ad.xiaohongshu.com/api/leona/rtb/creativity/list?pageNum=${pageNum}&pageSize=50`,
        {
          method: "POST",
          headers: headers,
          body: JSON.stringify({
            startTime: new Date().toISOString().split("T")[0],
            endTime: new Date().toISOString().split("T")[0],
            pageNum: pageNum,
            pageSize: 50,
          }),
        }
      );
      const data = await response.json();
      // console.log(data.data.list);

      allData = allData.concat(data.data.list);
      totalPage = data.data.totalPage;
      pageNum++;
    } while (pageNum <= totalPage || pageNum <= maxPageNum);

    try {
      // 保存响应数据
      responseData = allData;

      // 统计链接重复次数
      const clickUrlCounts = {};
      const expoUrlCounts = {};

      allData.forEach((item) => {
        if (item.clickUrls && item.clickUrls[0]) {
          const clickUrl = extractUrlParam(item.clickUrls[0]);
          clickUrlCounts[clickUrl] = (clickUrlCounts[clickUrl] || 0) + 1;
        }
        if (item.expoUrls && item.expoUrls[0]) {
          const expoUrl = extractUrlParam(item.expoUrls[0]);
          expoUrlCounts[expoUrl] = (expoUrlCounts[expoUrl] || 0) + 1;
        }
      });

      // 读取option 本地持久化的存储
      const storedOption = localStorage.getItem("data");
      const option = JSON.parse(storedOption);
      option.forEach((item) => {
        const link = item.link;
        const relink = link.match(/e=[^&]+/);
        if (relink) {
          item.relink = relink[0];
        } else {
          item.relink = link;
        }
      });
      console.log(option);

      if (storedOption) {
        Object.entries(clickUrlCounts).forEach(([url, count]) => {
          if (url) {
            const div = document.createElement("div");
            div.style.cssText = `
                    margin-bottom: 5px;
                  `; // 改成 cssom
            div.textContent = `点击链接:${url} 有${count}条`;
            const relink = url.match(/e=.*?(&|$)/)[0];
            if (option.some((item) => item.relink === relink)) {
              div.textContent += ` 配置符合:${
                option.find((item) => item.relink === relink).name
              }`;
            } else {
              div.textContent += " 无配置符合";
            }
            linkStatsContainer.appendChild(div);
          }
        });

        Object.entries(expoUrlCounts).forEach(([url, count]) => {
          if (url) {
            const div = document.createElement("div");
            div.style.cssText = `
                    margin-bottom: 5px;
                  `; // 改成 cssom
            div.textContent = `曝光链接:${url} 有${count}条`;
            const relink = url.match(/e=.*?(&|$)/)[0];
            if (option.some((item) => item.relink === relink)) {
              div.textContent += ` 配置符合:${
                option.find((item) => item.relink === relink).name
              }`;
            } else {
              div.textContent += " 无配置符合";
            }
            linkStatsContainer.appendChild(div);
          }
        });
      } else {
        Object.entries(clickUrlCounts).forEach(([url, count]) => {
          if (url) {
            const div = document.createElement("div");
            div.style.cssText = `
                    margin-bottom: 5px;
                  `; // 改成 cssom
            div.textContent = `点击链接:${url} 有${count}条`;
            div.textContent += " 无配置符合";
            linkStatsContainer.appendChild(div);
          }
        });

        Object.entries(expoUrlCounts).forEach(([url, count]) => {
          if (url) {
            const div = document.createElement("div");
            div.style.cssText = `
                    margin-bottom: 5px;
                  `; // 改成 cssom
            div.textContent = `曝光链接:${url} 有${count}条`;
            div.textContent += " 无配置符合";
            linkStatsContainer.appendChild(div);
          }
        });
      }

      createTable(allData);
      showToast("读取成功", "success");
    } catch (error) {
      console.error("解析响应数据时出错:", error);
      showToast("读取报错,可能是没有配置", "error");
    }
  }

  // 提取URL参数
  function extractUrlParam(url) {
    const match = url.match(/https:\/\/magellan.alimama.com\/(.*?)&/);
    return match ? match[1] : "";
  }

  // 创建表格
  function createTable(data) {
    const table = document.createElement("table");
    table.style.cssText = `
      width: 100%;
      border-collapse: collapse;
      background-color: white;
    `; // 改成 cssom

    // 创建表头
    const thead = document.createElement("thead");
    thead.style.cssText = `
      background-color: #0066CC;
    `; // 改成 cssom
    const headerRow = document.createElement("tr");
    const headers = ["创建时间", "创意名", "创意ID", "点击链接", "曝光链接"];
    headers.forEach((headerText) => {
      const th = document.createElement("th");
      th.style.cssText = `
        border: 1px solid #0066CC;
        padding: 12px;
        color: white;
        font-weight: bold;
      `; // 改成 cssom
      th.textContent = headerText;
      headerRow.appendChild(th);
    });
    thead.appendChild(headerRow);
    table.appendChild(thead);

    // 创建表体
    const tbody = document.createElement("tbody");
    data.forEach((item, index) => {
      const row = document.createElement("tr");
      row.style.cssText = `
        background-color: ${index % 2 === 0 ? "#F5F8FA" : "white"};
      `; // 改成 cssom

      const createTime = item.creativityCreateTime;
      const creativityName = item.creativityName;
      const creativityId = item.creativityId;
      const clickUrl = item.clickUrls
        ? JSON.stringify(item.clickUrls.map(extractUrlParam)).replace(
            /,/g,
            "\n"
          )
        : "";
      const expoUrl = item.expoUrls
        ? JSON.stringify(item.expoUrls.map(extractUrlParam)).replace(/,/g, "\n")
        : "";

      const values = [
        createTime,
        creativityName,
        creativityId,
        clickUrl,
        expoUrl,
      ];
      values.forEach((value) => {
        const td = document.createElement("td");
        td.style.cssText = `
          border: 1px solid #E5E5E5;
          padding: 12px;
          color: #333333;
        `; // 改成 cssom
        td.textContent = value;
        row.appendChild(td);
      });
      tbody.appendChild(row);
    });
    table.appendChild(tbody);

    // 清空表格容器并插入新表格
    tableContainer.innerHTML = "";
    tableContainer.appendChild(table);
  }

  // 下载Excel
  function downloadExcel(data) {
    // 添加BOM头,解决中文乱码问题
    // 数据是原始数据创意层级 下载添加笔记di
    const BOM = "\uFEFF";
    const headers = [
      "创建时间",
      "创意名",
      "创意ID",
      "点击链接",
      "曝光链接",
      "笔记id",
    ];
    const csvContent = [headers.join(",")];

    data.forEach((item) => {
      const createTime = item.creativityCreateTime || "";
      const creativityName = item.creativityName || "";
      const creativityId = item.creativityId || "";
      const clickUrl =
        item.clickUrls && item.clickUrls[0]
          ? JSON.stringify(item.clickUrls.map(extractUrlParam)).replace(
              /,/g,
              "\n"
            )
          : "";
      const expoUrl =
        item.expoUrls && item.expoUrls[0]
          ? JSON.stringify(item.expoUrls.map(extractUrlParam)).replace(
              /,/g,
              "\n"
            )
          : "";
      const noteId = item.noteId + "" || "";
      // 处理CSV中的特殊字符
      const escapeCsvValue = (value) => {
        if (typeof value !== "string") return value;
        if (
          value.includes(",") ||
          value.includes('"') ||
          value.includes("\n")
        ) {
          return `"${value.replace(/"/g, '""')}"`;
        }
        return value;
      };

      const values = [
        createTime,
        creativityName,
        creativityId,
        clickUrl,
        expoUrl,
        noteId,
      ].map(escapeCsvValue);
      csvContent.push(values.join(","));
    });

    const csv = BOM + csvContent.join("\n");
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    const timestamp = new Date().toLocaleString().replace(/[/:]/g, "-");

    link.setAttribute("href", url);
    link.setAttribute("download", `data_${timestamp}.csv`);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  }

  function option() {
    const div = document.createElement("div");
    div.className = "card";
    div.style.cssText = `
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 9999;
        width: 500px;
        height: 300px;
        overflow-x: auto;
        overflow-y: auto;
        background: white;
        border: 1px solid rgb(0, 102, 204);
        border-radius: 8px;
      `;
    const table = document.createElement("table");
    table.style.cssText = `
        width: 100%;
        border-collapse: collapse;
      `;
    const addButton = document.createElement("button");
    addButton.textContent = "添加";
    addButton.onclick = () => {
      const newRow = document.createElement("tr");
      const newTd1 = document.createElement("td");
      const newLinkInput = document.createElement("input");
      newLinkInput.type = "text";
      newTd1.appendChild(newLinkInput);
      newRow.appendChild(newTd1);
      const newTd2 = document.createElement("td");
      const newNameInput = document.createElement("input");
      newNameInput.type = "text";
      newTd2.appendChild(newNameInput);
      newRow.appendChild(newTd2);
      tbody.insertBefore(newRow, tbody.children[0]);
    };
    const saveButton = document.createElement("button");
    saveButton.textContent = "保存(关闭)";
    saveButton.onclick = () => {
      const rows = tbody.rows;
      const data = [];
      for (let i = 0; i < rows.length; i++) {
        const link = rows[i].cells[0].children[0].value;
        const name = rows[i].cells[1].children[0].value;
        data.push({ link, name });
      }
      localStorage.setItem("data", JSON.stringify(data));
      div.style.display = "none";
    };
    const clearButton = document.createElement("button");
    clearButton.textContent = "清空";
    clearButton.onclick = () => {
      tbody.innerHTML = ""; // 清空tbody中的所有内容
    };
    div.appendChild(addButton);
    div.appendChild(saveButton);
    div.appendChild(clearButton);

    const thead = document.createElement("thead");
    const tr = document.createElement("tr");
    const th1 = document.createElement("th");
    th1.textContent = "链接";
    tr.appendChild(th1);
    const th2 = document.createElement("th");
    th2.textContent = "名字";
    tr.appendChild(th2);
    thead.appendChild(tr);

    const tbody = document.createElement("tbody");
    const storedData = localStorage.getItem("data");
    if (storedData) {
      const data = JSON.parse(storedData);
      data.forEach((item) => {
        const row = document.createElement("tr");
        const td1 = document.createElement("td");
        const linkInput = document.createElement("input");
        linkInput.type = "text";
        linkInput.value = item.link;
        td1.appendChild(linkInput);
        row.appendChild(td1);
        const td2 = document.createElement("td");
        const nameInput = document.createElement("input");
        nameInput.type = "text";
        nameInput.value = item.name;
        td2.appendChild(nameInput);
        row.appendChild(td2);
        tbody.appendChild(row);
      });
    } else {
      const row = document.createElement("tr");
      const td1 = document.createElement("td");
      const linkInput = document.createElement("input");
      linkInput.type = "text";
      td1.appendChild(linkInput);
      row.appendChild(td1);
      const td2 = document.createElement("td");
      const nameInput = document.createElement("input");
      nameInput.type = "text";
      td2.appendChild(nameInput);
      row.appendChild(td2);
      tbody.appendChild(row);
    }

    table.appendChild(thead);
    table.appendChild(tbody);
    div.appendChild(table);
    document.body.appendChild(div);
  }

  //tools==================
  function create_car() {
    // 创建遮罩层
    const overlay = document.createElement("div");
    overlay.id = "overlay";

    // 创建卡片
    const card = document.createElement("div");
    card.id = "card";

    // 创建关闭按钮
    const closeButton = document.createElement("span");
    closeButton.textContent = "x";
    closeButton.style.position = "absolute";
    closeButton.style.top = "10px";
    closeButton.style.right = "10px";
    closeButton.style.cursor = "pointer";
    closeButton.addEventListener("click", function () {
      document.body.removeChild(overlay);
      document.body.removeChild(card);
    });
    card.appendChild(closeButton);
    return {
      overlay,
      card,
      closeButton,
    };
  }

  //tools-------------------
  //======================改名
  // 创建打开卡片的按钮
  const openButton = document.createElement("button");
  addButtonAttributes(openButton, "修改单元内计划字符");

  // 为打开按钮添加点击事件监听器
  openButton.addEventListener("click", function () {
    const { overlay, card, closeButton } = create_car();

    // 创建第一个输入框及其标签
    const oldCharLabel = document.createElement("label");
    oldCharLabel.textContent = "旧字符";
    const oldCharInput = document.createElement("input");
    oldCharInput.type = "text";

    // 创建第二个输入框及其标签
    const newCharLabel = document.createElement("label");
    newCharLabel.textContent = "新字符";
    const newCharInput = document.createElement("input");
    newCharInput.type = "text";

    // 创建替换按钮
    const replaceButton = document.createElement("button");
    replaceButton.textContent = "替换";
    replaceButton.addEventListener("click", async function () {
      const oldChar = oldCharInput.value;
      const newChar = newCharInput.value;
      await mainSend(oldChar, newChar);

      // 这里可以执行其他脚本,例如替换页面上的文本
      console.log(`将 "${oldChar}" 替换为 "${newChar}"`);
    });

    // 将元素添加到卡片中
    card.appendChild(closeButton);
    card.appendChild(oldCharLabel);
    card.appendChild(oldCharInput);
    card.appendChild(newCharLabel);
    card.appendChild(newCharInput);
    card.appendChild(replaceButton);

    // 将遮罩层和卡片添加到页面中
    document.body.appendChild(overlay);
    document.body.appendChild(card);
  });

  async function mainSend(old1, new1) {
    const n = location.href.match(/[0-9]{1,20}/g);
    const headers = {
      accept: "application/json, text/plain, */*",
      "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
      "content-type": "application/json;charset=UTF-8",
      priority: "u=1, i",
      "sec-ch-ua":
        '"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"',
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": '"macOS"',
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin",
      // "x-b3-traceid": "37e8ffc9e25f798c",
    };

    if (location.href.indexOf("vSellerId") != -1) {
      headers["v-seller-id"] = location.search.match(
        /(?<=vSellerId=)[0-9a-z].*/g
      );
    }
    const r = await fetch(
      "https://ad.xiaohongshu.com/api/leona/rtb/creativity/list",
      {
        headers: headers,
        // referrer:
        //   "https://ad.xiaohongshu.com/aurora/ad/manage/103584356/192658846/creativity",
        referrerPolicy: "strict-origin-when-cross-origin",
        body: `{\"campaignId\":${n[0]},\"unitId\":${n[1]},\"startTime\":\"${
          new Date().toISOString().split("T")[0]
        }\",\"endTime\":\"${
          new Date().toISOString().split("T")[0]
        }\",\"pageNum\":1,\"pageSize\":50}`,
        method: "POST",
        mode: "cors",
        credentials: "include",
      }
    );

    const j = await r.json();
    const total = j.data.list.length;
    let completed = 0;
    const sheet = new CSSStyleSheet();
    sheet.replaceSync(`
      #progressBar {
        width: 0;
        height: 20px;
        background-color: #54FF9F;
        position: fixed;
        bottom: 10px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 2147483647;
      }
    `);
    addStyleSheet(sheet);
    // document.adoptedStyleSheets = [sheet];
    const progressBar = document.createElement("div");
    progressBar.id = "progressBar";
    progressBar.innerText = "进度";
    document.body.appendChild(progressBar);

    for (let index = 0; index < j.data.list.length; index++) {
      const element = j.data.list[index];
      const oldName = element.creativityName;
      const regex = new RegExp(old1, "g");
      const newName = oldName.replace(regex, new1);
      await reanmeSend(element.creativityId, newName);
      completed++;
      const progress = (completed / total) * 100;
      progressBar.style.width = `${progress}%`;
    }

    document.body.removeChild(progressBar);
    showToast("完成", "success");
    // alert("完成");
  }
  async function reanmeSend(id, name) {
    const headers = {
      accept: "application/json, text/plain, */*",
      "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
      "content-type": "application/json;charset=UTF-8",
      priority: "u=1, i",
      "sec-ch-ua":
        '"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"',
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": '"macOS"',
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin",
      "x-b3-traceid": "dee287ce9b6526cc",
    };

    if (location.href.indexOf("vSellerId") != -1) {
      headers["v-seller-id"] = location.search.match(
        /(?<=vSellerId=)[0-9a-z].*/g
      );
    }
    return fetch(
      "https://ad.xiaohongshu.com/api/leona/rtb/creativity/batch/update/name",
      {
        headers: headers,
        //"referrer": "https://ad.xiaohongshu.com/aurora/ad/manage/103596579/192712174/creativity",
        referrerPolicy: "strict-origin-when-cross-origin",
        body: `{\"creativityId\":${id},\"creativityName\":\"${name}\"}`,
        method: "POST",
        mode: "cors",
        credentials: "include",
      }
    );
  }

  //调价函数======================

  function getCurrentTimestamp() {
    return Math.floor(Date.now() / 1000);
  }

  async function getData(body, bid, result) {
    body.removeBind = 0;
    body.sourceFlag = "web";
    body.pageEnterTime = getCurrentTimestamp() - 10;
    body.pageSubmitTime = getCurrentTimestamp();
    body.keywordWithBid.map((e) => {
      e.bid = bid * 100;
    });

    const headers = {
      accept: "application/json, text/plain, */*",
      "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
      "content-type": "application/json",
      priority: "u=1, i",
      "sec-ch-ua":
        '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"',
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": '"Windows"',
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin",
      "x-b3-traceid": "631398efd0ea1db1",
    };

    if (location.href.indexOf("vSellerId") != -1) {
      headers["v-seller-id"] = location.search.match(
        /(?<=vSellerId=)[0-9a-z].*/g
      );
    }
    const r = await fetch("https://ad.xiaohongshu.com/api/leona/rtb/unit", {
      headers: headers,
      // "referrer": "https://ad.xiaohongshu.com/aurora/ad/edit/unit/107358958/208378008/4/2?byManage=true&manageLevel=byAccount&AFormGrayFlag=false",
      referrerPolicy: "strict-origin-when-cross-origin",
      body: JSON.stringify(body),
      method: "PUT",
      mode: "cors",
      credentials: "include",
    });
    const j = await r.json();
    showToast(`单元:【${body.unitName}】,id:【${body.unitId}】,${j.msg}`, "success");
    console.log(`单元:【${body.unitName}】,id:【${body.unitId}】,${j.msg}`);
    result.push(`单元:【${body.unitName}】,id:【${body.unitId}】,调整出价${bid},${j.msg}`);
  }

  async function set_bid(bid, state, uidValue) {
    const headers = {
      accept: "application/json, text/plain, */*",
      "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
      "content-type": "application/json",
      priority: "u=1, i",
      "sec-ch-ua":
        '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"',
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": '"Windows"',
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin",
      "x-b3-traceid": "e900951027b4cc32",
    };
    if (location.href.indexOf("vSellerId") != -1) {
      headers["v-seller-id"] = location.search.match(
        /(?<=vSellerId=)[0-9a-z].*/g
      );
    }
    var data = [];
    let pageNum = 1;
    let totalPage = 1;
    // 修改价格 do w
    do {
      const r = await fetch(
        "https://ad.xiaohongshu.com/api/leona/rtb/unit/search",
        {
          headers: headers,
          referrer: "https://ad.xiaohongshu.com/aurora/ad/manage/creativity",
          referrerPolicy: "strict-origin-when-cross-origin",
          body: `{\"startTime\":\"${
            new Date().toISOString().split("T")[0]
          }\",\"endTime\":\"${
            new Date().toISOString().split("T")[0]
          }\",\"pageNum\":${pageNum},\"pageSize\":100,\"placementList\":[2]}`,//placementList是搜索
          method: "POST",
          mode: "cors",
          credentials: "include",
        }
      );

      const j = await r.json();
      data = data.concat(j.data.list);
      totalPage = j.data.totalPage;
      pageNum++;
    } while (pageNum <= totalPage);

    showToast(`获取数据:当前获取总单元${data.length}条\n开始执行调价`, "info");
    const result = [];
    if (state == "all") {
      console.log("全部调整");
      showToast(`当前模式全部调整`, "info");
    }

    if (state == "uid") {
      console.log("只调整输入");
      showToast(`当前模式根据输入调整`, "info");

      const uid = uidValue.trim().split("\n");
      var t = [];
      for (let index = 0; index < uid.length; index++) {
        const element = uid[index];
        if (data.filter((item) => item.unitId == element).length > 0) {
          t.push(data.filter((item) => item.unitId == element)[0]);
        }
      }
      data = t;
    }
    const progress = new ChainProgress();
    progress.setTotal(data.length); 
    /* -------------------- 使用示例 -------------------- */
// 

// // 初始化设置总步数
//

// // 每次事件成功调用
// document.querySelector('.btn').addEventListener('click', () => {
//  
// });
    for (let index = 0; index < data.length; index++) {
      const element = data[index];
      showToast(`当前执行单元${element.unitName},调整出价为${bid}`, "info");
      console.log(`当前执行单元${element.unitName},调整出价为${bid}`);

      await getData(element, bid, result);
      progress.next();
      await sleep(1000);
    }

    alert(result.join("\n"));
    return 1;
  }

  //调价函数----------------------

  // 创意开启关闭创意============================

  // 关闭计划
  async function closePlan(chunkedA, isColse) {
    const text = isColse == 1 ? "开启创意" : "关闭创意";

    const headers = {
      accept: "application/json, text/plain, */*",
      "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
      "content-type": "application/json;charset=UTF-8",
      priority: "u=1, i",
      "sec-ch-ua":
        '"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"',
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": '"macOS"',
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin",
      "x-b3-traceid": "c1adc74c127d40f2",
    };
    if (location.href.indexOf("vSellerId") != -1) {
      headers["v-seller-id"] = location.search.match(
        /(?<=vSellerId=)[0-9a-z].*/g
      );
    }
    for (let i = 0; i < chunkedA.length; i++) {
      const ids = chunkedA[i];
      let retry = true;

      while (retry) {
        const r = await fetch(
          "https://ad.xiaohongshu.com/api/leona/rtb/creativity/batch/status",
          {
            headers: headers,
            referrer: "https://ad.xiaohongshu.com/aurora/ad/manage/creativity",
            referrerPolicy: "strict-origin-when-cross-origin",
            // 2是关闭 1是开启
            body: JSON.stringify({
              ids: ids,
              actionType: parseInt(isColse),
            }),
            method: "PUT",
            mode: "cors",
            credentials: "include",
          }
        );
        const res = await r.json();
        console.log(res.msg);
        if (res.msg === "成功") {
          showToast(`${text},${res.msg}:${JSON.stringify(ids)}`, "success");
          retry = false;
        } else {
          retry = true;
        }
        await new Promise((resolve) => setTimeout(resolve, 500));
      }
    }
  }
  // 关闭计划笔记 noteid 和 名称
  async function closePlanNote(ids, isColse, creativeIdSelect) {
    // 确保 isColse 是有效的值
    if (isColse === null || isColse === undefined) {
      showToast.error("isColse 参数无效");
      return; // 或者抛出错误
    }

    const headers = {
      accept: "application/json, text/plain, */*",
      "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
      "content-type": "application/json;charset=UTF-8",
      priority: "u=1, i",
      "sec-ch-ua":
        '"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"',
      "sec-ch-ua-mobile": "?0",
      "sec-ch-ua-platform": '"macOS"',
      "sec-fetch-dest": "empty",
      "sec-fetch-mode": "cors",
      "sec-fetch-site": "same-origin",
      "x-b3-traceid": "c1adc74c127d40f2",
    };
    if (location.href.indexOf("vSellerId") != -1) {
      headers["v-seller-id"] = location.search.match(
        /(?<=vSellerId=)[0-9a-z].*/g
      );
    }

    for (let index = 0; index < ids.length; index++) {
      const id = ids[index];
      var bbody = ``;
      // 判断是否还有制表符
      if (id.indexOf("\t") != -1) {
        const idArr = id.split("\t");
        const n = idArr[1] == "信息流" ? 1 : 2;
        bbody = `{\"startTime\":\"2025-03-27\",\"endTime\":\"2025-03-27\",\"${creativeIdSelect.value}\":\"${idArr[0]}\",\"pageNum\":1,\"pageSize\":50,\"placementList\":[${n}]}`;
      } else {
        const idArr = [id];
        bbody = `{\"startTime\":\"2025-03-27\",\"endTime\":\"2025-03-27\",\"${creativeIdSelect.value}\":\"${idArr[0]}\",\"pageNum\":1,\"pageSize\":50}`;
      }

      const r = await fetch(
        "https://ad.xiaohongshu.com/api/leona/rtb/creativity/list",
        {
          headers: headers,
          referrer: "https://ad.xiaohongshu.com/aurora/ad/manage/creativity",
          referrerPolicy: "strict-origin-when-cross-origin",
          body: bbody,
          method: "POST",
          mode: "cors",
          credentials: "include",
        }
      );
      const res = await r.json();
      if (res.data.list.length > 0) {
        const data = res.data.list.map((e) => e.creativityId);
        const chunkedA = data.reduce((acc, _, index) => {
          const chunkIndex = Math.floor(index / 50);
          if (!acc[chunkIndex]) {
            acc[chunkIndex] = [];
          }
          acc[chunkIndex].push(_);
          return acc;
        }, []);
        console.log(isColse);
        await closePlan(chunkedA, isColse);
      }
    }
  }
  function split_array(array, number) {
    // 将数组a以number个为一组切割
    const chunkedA = array.reduce((acc, _, index) => {
      const chunkIndex = Math.floor(index / number);
      if (!acc[chunkIndex]) {
        acc[chunkIndex] = [];
      }
      acc[chunkIndex].push(_);
      return acc;
    }, []);
    return chunkedA;
  }

  // 创意开启关闭创意-----------------------------

  // 创建配置按钮
  const optionButton = document.createElement("button");
  addButtonAttributes(optionButton, "配置");

  // 开启关闭创意============================

  const openOrClose = document.createElement("button");
  addButtonAttributes(openOrClose, "关闭/开启创意");
  openOrClose.onclick = () => {
    const { overlay, card, closeButton } = create_car();
    // 创建第一个下拉列表
    const creativeIdSelect = document.createElement("select");
    creativeIdSelect.options.add(new Option("创意ID", "creativeId"));
    creativeIdSelect.options.add(new Option("文字匹配", "name"));
    creativeIdSelect.options.add(new Option("笔记ID", "noteId"));
    card.appendChild(creativeIdSelect);

    // 创建第二个下拉列表
    const toggleSelect = document.createElement("select");
    toggleSelect.options.add(new Option("关闭", "2"));
    toggleSelect.options.add(new Option("开启", "1"));

    card.appendChild(toggleSelect);

    // 创建多行文本输入框
    const textArea = document.createElement("textarea");
    card.appendChild(textArea);
    //1 是信息流 2是搜索
    // \"placementList\":[2]
    // 创建请求按钮
    const requestButton = document.createElement("button");
    requestButton.textContent = "请求";
    requestButton.onclick = async () => {
      const input_list = textArea.value
        .trim()
        .split(/\n|,\n/g)
        .map((e) => e.trim());
      const d = toggleSelect.value;
      if (input_list.length === 0) {
        showToast("请输入内容", "error");
        return;
      }
      if (input_list[0].length <= 11 && creativeIdSelect.value === "noteId") {
        showToast("不符合笔记ID", "error");
        return;
      }
      if (
        input_list[0].length >= 11 &&
        creativeIdSelect.value === "creativeId"
      ) {
        showToast("不符合创意ID", "error");
        return;
      }
      console.log(creativeIdSelect.value);
      if (creativeIdSelect.value === "creativeId") {
        const chunkedA = split_array(input_list, 50);
        // console.log();

        closePlan(chunkedA, d);
      }
      if (
        creativeIdSelect.value === "name" ||
        creativeIdSelect.value === "noteId"
      ) {
        const chunkedA = input_list;
        closePlanNote(chunkedA, d, creativeIdSelect);
      }
    };
    card.appendChild(requestButton);
    // 将遮罩层和卡片添加到页面中
    document.body.appendChild(overlay);
    document.body.appendChild(card);
  };

  // 批量调价搜索词
  const modify_the_price = document.createElement("button");
  addButtonAttributes(modify_the_price, "批量调整出价");

  modify_the_price.onclick = () => {
    const { overlay, card, closeButton } = create_car();
    // 创建第一个下拉列表
    const creativeIdSelect = document.createElement("select");
    creativeIdSelect.options.add(new Option("全部调价", "all"));
    creativeIdSelect.options.add(new Option("单元id调价", "uid"));

    const priceInput = document.createElement("input");
    priceInput.type = "number";
    priceInput.id = "dynamicPriceInput";
    priceInput.inputMode = "numeric";
    priceInput.pattern = "[0-9]*\\.?[0-9]*";
    priceInput.placeholder = "请输入金额";
    priceInput.autocomplete = "off";
    priceInput.step = "0.01";

    const textArea = document.createElement("textarea");
    textArea.style.display = "none"
    textArea.placeholder = "请输入单元ID";
    creativeIdSelect.addEventListener("change", function () {
      // 判断是否选择第二个选项(索引从0开始)
      if (this.value === "uid") {
        // 或判断值:this.value === '2'
        textArea.style.display = "block";
      } else {
        textArea.style.display = "none";
      }
    });

    card.appendChild(creativeIdSelect);
    card.appendChild(priceInput);
    // 创建多行文本输入框
    card.appendChild(textArea);

    //1 是信息流 2是搜索
    // \"placementList\":[2]
    // 创建请求按钮
    const requestButton = document.createElement("button");
    requestButton.textContent = "请求";

    requestButton.addEventListener("click",async function()  {
      this.disabled = true;
      const c = this.style.backgroundColor 
      this.style.backgroundColor  = "rgb(105, 102, 102)";
      const Newbid = priceInput.valueAsNumber;
      const r = await set_bid(Newbid, creativeIdSelect.value, textArea.value);
      this.style.backgroundColor  = c; 
      this.disabled = false; 
    });

    // const bid = prompt("请输入出价");
    // //判断bid是否是数值 并且就bid转换成小数
    // if (isNaN(bid)) {
    //   showToast("请输入数字", "error");
    //   return;
    // }

    // if (bid) {
    //   var Newbid = parseFloat(bid);
    //   set_bid(Newbid);
    // }
    card.appendChild(requestButton);
    // 将遮罩层和卡片添加到页面中
    document.body.appendChild(overlay);
    document.body.appendChild(card);
  };

  // const download_today = document.createElement("button");
  // addButtonAttributes(download_today, "下载今日创建");
  // download_today.onclick =  () => {

  //   fetch("https://ad.xiaohongshu.com/api/leona/rtb/creativity/list", {
  //     "headers": {
  //       "accept": "application/json, text/plain, */*",
  //       "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
  //       "content-type": "application/json",
  //       "priority": "u=1, i",
  //       "sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Microsoft Edge\";v=\"134\"",
  //       "sec-ch-ua-mobile": "?0",
  //       "sec-ch-ua-platform": "\"macOS\"",
  //       "sec-fetch-dest": "empty",
  //       "sec-fetch-mode": "cors",
  //       "sec-fetch-site": "same-origin",
  //       "x-b3-traceid": "268ef6d4ba91e008"
  //     },
  //     "referrer": "https://ad.xiaohongshu.com/aurora/ad/manage/creativity",
  //     "referrerPolicy": "strict-origin-when-cross-origin",
  //     "body": "{\"startTime\":\"2025-03-28\",\"endTime\":\"2025-03-28\",\"creativityCreateBeginTime\":\"2025-03-27\",\"creativityCreateEndTime\":\"2025-03-27\",\"pageNum\":1,\"pageSize\":20}",
  //     "method": "POST",
  //     "mode": "cors",
  //     "credentials": "include"
  //   });
  // };
  // 加载元素
  optionButton.onclick = option;
  buttonContainer.appendChild(optionButton);
  buttonContainer.appendChild(openButton);
  buttonContainer.appendChild(openOrClose);
  buttonContainer.appendChild(modify_the_price);
  // buttonContainer.appendChild(download_today);
})();