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

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

当前为 2025-07-10 提交的版本,查看 最新版本

// ==UserScript==
// @name         小红书广告数据查询与展示
// @namespace    http://tampermonkey.net/
// @version      1.45
// @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 =JSON.stringify(item.clickUrls) || "";
            const expoUrl =JSON.stringify(item.expoUrls) || "";
            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);
})();