🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

动态管理

动态管理页面

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name         动态管理
// @namespace    mscststs
// @version      0.31
// @description  动态管理页面
// @author       mscststs
// @match        https://space.bilibili.com/*
// @match        http://space.bilibili.com/*
// @require      https://greasyfork.org/scripts/38220-mscststs-tools/code/MSCSTSTS-TOOLS.js?version=713767
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js
// @icon         https://static.hdslb.com/images/favicon.ico
// @license      MIT
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
  
    // 全局状态
    let appState = {
      showModal: false,
      loading: false,
      loadCount: 20,
      dynamics: [],
      offset: '',
      uid: ''
    };
  
    // 等待页面加载完成
    document.addEventListener('DOMContentLoaded', init);
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', init);
    } else {
      init();
    }
  
    async function init() {
      try {
        const shijiao = await mscststs.wait(".view-switcher__trigger", false, 100);
        if (!shijiao || !~shijiao.innerText.indexOf("我自己")) {
          console.log('当前不是自己的个人动态');
          return;
        }
  
        await Promise.all([
          mscststs.wait(".space-dynamic__right")
        ]);
  
        // 获取用户ID
        appState.uid = getCurrentUid();
        
        const node = createControlPanel();
        document.querySelector("body").append(node);
  
        // 绑定事件
        bindEvents();
        
      } catch (error) {
        console.error('初始化失败:', error);
      }
    }
  
    // 获取当前用户ID
    function getCurrentUid() {
      const match = window.location.pathname.match(/\/(\d+)/);
      return match ? match[1] : '';
    }
  
    // 创建控制面板DOM结构
    function createControlPanel() {
      const panelHtml = `
        <div id="dynamic-manager" class="msc_panel" style="
          position: fixed;
          bottom: 20px;
          right: 20px;
          z-index: 9999;
        ">
          <button id="open-manager-btn" style="
            background: linear-gradient(135deg, #00b4d8, #0077b6);
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s ease;
            box-shadow: 0 2px 8px rgba(0, 180, 216, 0.3);
          ">
            📊 动态管理
          </button>
          
          <!-- 管理面板弹窗 -->
          <div id="manager-modal" style="
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            z-index: 10000;
            display: none;
            align-items: center;
            justify-content: center;
          ">
            <div style="
              background: white;
              border-radius: 12px;
              width: 95%;
              max-width: 1400px;
              max-height: 90%;
              overflow: hidden;
              box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
            ">
              <!-- 头部 -->
              <div style="
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 20px 30px;
                border-bottom: 1px solid #e1e1e1;
                background: linear-gradient(135deg, #f8f9fa, #e9ecef);
              ">
                <h2 style="margin: 0; color: #333;">动态管理面板</h2>
                <button id="close-modal-btn" style="
                  background: none;
                  border: none;
                  font-size: 24px;
                  cursor: pointer;
                  color: #666;
                  width: 30px;
                  height: 30px;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                  border-radius: 50%;
                  transition: all 0.2s;
                ">×</button>
              </div>
              
              <!-- 操作区域 -->
              <div style="padding: 20px 30px; border-bottom: 1px solid #e1e1e1;">
                <div style="display: flex; gap: 15px; align-items: center; flex-wrap: wrap;">
                  <div style="display: flex; align-items: center; gap: 10px;">
                    <label style="font-weight: 500; color: #333;">加载数量:</label>
                    <input 
                      id="load-count-input" 
                      type="number" 
                      min="1" 
                      max="100" 
                      value="20"
                      style="
                        width: 80px;
                        padding: 6px 10px;
                        border: 1px solid #ddd;
                        border-radius: 4px;
                        font-size: 14px;
                      "
                    >
                  </div>
                  <button 
                    id="load-dynamics-btn"
                    style="
                      background: #28a745;
                      color: white;
                      border: none;
                      padding: 8px 16px;
                      border-radius: 4px;
                      cursor: pointer;
                      font-size: 14px;
                      transition: all 0.2s;
                    "
                  >
                    加载动态
                  </button>
                  <button 
                    id="select-all-forward-btn"
                    style="
                      background: #17a2b8;
                      color: white;
                      border: none;
                      padding: 8px 16px;
                      border-radius: 4px;
                      cursor: pointer;
                      font-size: 14px;
                      margin-right: 10px;
                    "
                  >
                    勾选所有转发
                  </button>
                  <button 
                    id="select-all-lottery-btn"
                    style="
                      background: #fd7e14;
                      color: white;
                      border: none;
                      padding: 8px 16px;
                      border-radius: 4px;
                      cursor: pointer;
                      font-size: 14px;
                      margin-right: 10px;
                    "
                  >
                    勾选所有抽奖
                  </button>
                  <button 
                    id="batch-delete-btn"
                    style="
                      background: #dc3545;
                      color: white;
                      border: none;
                      padding: 8px 16px;
                      border-radius: 4px;
                      cursor: pointer;
                      font-size: 14px;
                      margin-right: 10px;
                    "
                  >
                    批量删除
                  </button>
                  <button 
                    id="batch-delete-unfollow-btn"
                    style="
                      background: #e74c3c;
                      color: white;
                      border: none;
                      padding: 8px 16px;
                      border-radius: 4px;
                      cursor: pointer;
                      font-size: 14px;
                      margin-right: 10px;
                    "
                  >
                    删除并取关
                  </button>
                  <button 
                    id="clear-data-btn"
                    style="
                      background: #dc3545;
                      color: white;
                      border: none;
                      padding: 8px 16px;
                      border-radius: 4px;
                      cursor: pointer;
                      font-size: 14px;
                    "
                  >
                    清空数据
                  </button>
                  <div id="dynamics-count" style="margin-left: auto; color: #666;">
                    已加载: 0 条动态
                  </div>
                </div>
              </div>
              
              <!-- 表格区域 -->
              <div style="padding: 0; max-height: 600px; overflow-y: auto;">
                <table id="dynamics-table" style="width: 100%; border-collapse: collapse; table-layout: fixed;">
                  <thead style="background: #f8f9fa; position: sticky; top: 0;">
                    <tr>
                      <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd; font-weight: 600; width: 80px;">
                        <input 
                          type="checkbox" 
                          id="select-all-checkbox"
                          style="margin-right: 8px;"
                        >
                        选择
                      </th>
                      <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd; font-weight: 600; width: 80px;">类型</th>
                      <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd; font-weight: 600; width: 500px;">内容</th>
                      <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd; font-weight: 600; width: 120px;">发布时间</th>
                      <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd; font-weight: 600; width: 120px;">操作</th>
                    </tr>
                  </thead>
                  <tbody id="dynamics-tbody">
                    <tr>
                      <td colspan="5" style="padding: 40px; text-align: center; color: #999;">
                        暂无数据,请点击"加载动态"获取数据
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </div>
      `;
  
      const div = document.createElement('div');
      div.innerHTML = panelHtml;
      return div.firstElementChild;
    }
  
    // 绑定事件
    function bindEvents() {
      // 打开弹窗
      document.getElementById('open-manager-btn').addEventListener('click', showModal);
      
      // 关闭弹窗
      document.getElementById('close-modal-btn').addEventListener('click', hideModal);
      
      // 点击遮罩关闭弹窗
      document.getElementById('manager-modal').addEventListener('click', function(e) {
        if (e.target === this) {
          hideModal();
        }
      });
      
      // 加载动态
      document.getElementById('load-dynamics-btn').addEventListener('click', loadDynamics);
      
      // 勾选所有转发
      document.getElementById('select-all-forward-btn').addEventListener('click', selectAllForward);
      
      // 勾选所有抽奖
      document.getElementById('select-all-lottery-btn').addEventListener('click', selectAllLottery);
      
      // 批量删除
      document.getElementById('batch-delete-btn').addEventListener('click', batchDeleteDynamics);
      
      // 批量删除并取关
      document.getElementById('batch-delete-unfollow-btn').addEventListener('click', batchDeleteAndUnfollowDynamics);
      
      // 清空数据
      document.getElementById('clear-data-btn').addEventListener('click', clearData);
      
      // 全选
      document.getElementById('select-all-checkbox').addEventListener('change', toggleAllSelection);
      
      // 加载数量输入
      document.getElementById('load-count-input').addEventListener('input', function() {
        appState.loadCount = parseInt(this.value) || 20;
      });
  
      // 按钮悬停效果
      const openBtn = document.getElementById('open-manager-btn');
      openBtn.addEventListener('mouseenter', function() {
        this.style.transform = 'translateY(-1px)';
        this.style.boxShadow = '0 4px 12px rgba(0, 180, 216, 0.4)';
      });
      openBtn.addEventListener('mouseleave', function() {
        this.style.transform = 'translateY(0)';
        this.style.boxShadow = '0 2px 8px rgba(0, 180, 216, 0.3)';
      });
  
      const closeBtn = document.getElementById('close-modal-btn');
      closeBtn.addEventListener('mouseenter', function() {
        this.style.background = '#f0f0f0';
      });
      closeBtn.addEventListener('mouseleave', function() {
        this.style.background = 'none';
      });
  
      // 绑定查看按钮事件
      document.querySelectorAll('.view-btn').forEach(btn => {
        btn.addEventListener('click', function() {
          const index = parseInt(this.dataset.index);
          viewDynamic(appState.dynamics[index]);
        });
      });
      
      // 绑定删除按钮事件
      document.querySelectorAll('.delete-btn').forEach(btn => {
        btn.addEventListener('click', function() {
          const index = parseInt(this.dataset.index);
          deleteDynamic(appState.dynamics[index]);
        });
      });
      
      // 绑定删除并取关按钮事件
      document.querySelectorAll('.delete-unfollow-btn').forEach(btn => {
        btn.addEventListener('click', function() {
          const index = parseInt(this.dataset.index);
          deleteAndUnfollowDynamic(appState.dynamics[index]);
        });
      });
    }
  
    // 显示弹窗
    function showModal() {
      appState.showModal = true;
      document.getElementById('manager-modal').style.display = 'flex';
    }
  
    // 隐藏弹窗
    function hideModal() {
      appState.showModal = false;
      document.getElementById('manager-modal').style.display = 'none';
    }
  
    // 加载动态
    async function loadDynamics() {
      if (!appState.uid) {
        alert('无法获取用户ID');
        return;
      }
      
      const loadBtn = document.getElementById('load-dynamics-btn');
      loadBtn.disabled = true;
      loadBtn.style.opacity = '0.6';
      loadBtn.style.cursor = 'not-allowed';
      
      const targetCount = appState.loadCount;
      let currentOffset = appState.offset;
      let totalLoadedInThisSession = 0;
      
      try {
        // 循环加载直到达到目标数量或没有更多数据
        while (totalLoadedInThisSession < targetCount) {
          // 更新按钮文本显示进度
          loadBtn.textContent = `加载中... (${totalLoadedInThisSession}/${targetCount})`;
          
          const response = await spaceHistory(currentOffset);
          
          if (response.code !== 0) {
            alert('加载失败: ' + response.message);
            break;
          }
          
          const items = response.data.items || [];
          if (items.length === 0 || !response.data.has_more) {
            console.log('没有更多动态数据');
            break;
          }
          
          // 计算本次需要添加的数量
          const remainingCount = targetCount - totalLoadedInThisSession;
          const itemsToAdd = items.slice(0, remainingCount).map(item => ({
            ...item,
            selected: false
          }));
          
          appState.dynamics = [...appState.dynamics, ...itemsToAdd];
          currentOffset = response.data.offset || '';
          appState.offset = currentOffset;
          
          totalLoadedInThisSession += itemsToAdd.length;
          
          console.log(`本次加载 ${itemsToAdd.length} 条动态,累计加载 ${totalLoadedInThisSession} 条`);
          
          // 如果没有更多数据(offset为空)或者API返回的数据少于预期,说明已经到底了
          if (!currentOffset || !response.data.has_more) {
            console.log('已加载所有可用的动态数据');
            break;
          }
          
          // 如果已经达到目标数量,退出循环
          if (totalLoadedInThisSession >= targetCount) {
            break;
          }
          
          // 添加短暂延迟避免请求过于频繁
          await new Promise(resolve => setTimeout(resolve, 500));
        }
        
        console.log(`加载完成,目标: ${targetCount} 条,实际加载: ${totalLoadedInThisSession} 条,总计: ${appState.dynamics.length} 条`);
        
        // 更新UI
        updateDynamicsTable();
        updateDynamicsCount();
        
        // 显示加载结果
        if (totalLoadedInThisSession > 0) {
          const message = totalLoadedInThisSession < targetCount 
            ? `成功加载 ${totalLoadedInThisSession} 条动态(已加载完所有可用数据)`
            : `成功加载 ${totalLoadedInThisSession} 条动态`;
          console.log(message);
        } else {
          alert('没有新的动态数据');
        }
        
      } catch (error) {
        console.error('加载动态失败:', error);
        alert('加载失败,请检查网络连接');
      } finally {
        loadBtn.disabled = false;
        loadBtn.textContent = '加载动态';
        loadBtn.style.opacity = '1';
        loadBtn.style.cursor = 'pointer';
      }
    }
  
    // API调用
    async function spaceHistory(offset = "") {
      const url = `https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=${offset}&host_mid=${appState.uid}&timezone_offset=-480&platform=web`;
      
      try {
        const response = await axios.get(url, {
          headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Referer': 'https://space.bilibili.com/'
          },
          withCredentials: true
        });
        return response.data;
      } catch (error) {
        if (error.response && error.response.status === 429) {
          // 429错误重试机制
          await new Promise(resolve => setTimeout(resolve, 2000));
          return spaceHistory(offset);
        }
        throw error;
      }
    }
  
    // 清空数据
    function clearData() {
      if (confirm('确定要清空所有数据吗?')) {
        appState.dynamics = [];
        appState.offset = '';
        updateDynamicsTable();
        updateDynamicsCount();
      }
    }
  
    // 全选/取消全选
    function toggleAllSelection() {
      const checkbox = document.getElementById('select-all-checkbox');
      const isChecked = checkbox.checked;
      
      appState.dynamics.forEach(item => {
        item.selected = isChecked;
      });
      
      // 更新表格中的复选框
      const itemCheckboxes = document.querySelectorAll('.item-checkbox');
      itemCheckboxes.forEach(cb => {
        cb.checked = isChecked;
      });
    }
  
    // 更新动态表格
    function updateDynamicsTable() {
      const tbody = document.getElementById('dynamics-tbody');
      
      if (appState.dynamics.length === 0) {
        tbody.innerHTML = `
          <tr>
            <td colspan="5" style="padding: 40px; text-align: center; color: #999;">
              暂无数据,请点击"加载动态"获取数据
            </td>
          </tr>
        `;
        return;
      }
      
      tbody.innerHTML = appState.dynamics.map((item, index) => `
        <tr style="border-bottom: 1px solid #eee;">
          <td style="padding: 12px;">
            <input 
              type="checkbox" 
              class="item-checkbox"
              data-index="${index}"
              ${item.selected ? 'checked' : ''}
              style="margin-right: 8px;"
            >
            ${index + 1}
          </td>
          <td style="padding: 12px;">
            <span style="
              display: inline-block;
              padding: 2px 8px;
              background: #e3f2fd;
              color: #1976d2;
              border-radius: 12px;
              font-size: 12px;
              white-space: nowrap;
            ">
              ${getTypeLabel(item)}
            </span>
          </td>
          <td style="padding: 12px; word-wrap: break-word; overflow: hidden;">
            <div style="display: flex; align-items: center; gap: 10px;">
              ${item.modules.module_dynamic.major && item.modules.module_dynamic.major.archive ? 
                `<img src="${item.modules.module_dynamic.major.archive.cover}" style="width: 60px; height: 40px; object-fit: cover; border-radius: 4px; flex-shrink: 0;">` : ''
              }
              <div style="overflow: hidden; flex: 1; min-width: 0;">
                <div style="font-weight: 500; margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="${getContentTitle(item)}">
                  ${getContentTitle(item)}
                </div>
                <div style="font-size: 12px; color: #666; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;" title="${getContentDesc(item)}">
                  ${getContentDesc(item)}
                </div>
              </div>
            </div>
          </td>
          <td style="padding: 12px; color: #666; font-size: 14px; white-space: nowrap;">
            ${item.modules.module_author.pub_time}
          </td>
          <td style="padding: 12px;">
            <div style="display: flex; gap: 8px;">
              <button 
                class="view-btn"
                data-index="${index}"
                style="
                  background: #007bff;
                  color: white;
                  border: none;
                  padding: 4px 8px;
                  border-radius: 3px;
                  cursor: pointer;
                  font-size: 12px;
                  white-space: nowrap;
                "
              >
                查看
              </button>
              <button 
                class="delete-btn"
                data-index="${index}"
                style="
                  background: #dc3545;
                  color: white;
                  border: none;
                  padding: 4px 8px;
                  border-radius: 3px;
                  cursor: pointer;
                  font-size: 12px;
                  white-space: nowrap;
                "
              >
                删除
              </button>
              <button 
                class="delete-unfollow-btn"
                data-index="${index}"
                style="
                  background: #e74c3c;
                  color: white;
                  border: none;
                  padding: 4px 6px;
                  border-radius: 3px;
                  cursor: pointer;
                  font-size: 12px;
                  white-space: nowrap;
                "
              >
                删除并取关
              </button>
            </div>
          </td>
        </tr>
      `).join('');
      
      // 绑定表格内的事件
      bindTableEvents();
    }
  
    // 绑定表格内的事件
    function bindTableEvents() {
      // 绑定复选框事件
      document.querySelectorAll('.item-checkbox').forEach(checkbox => {
        checkbox.addEventListener('change', function() {
          const index = parseInt(this.dataset.index);
          appState.dynamics[index].selected = this.checked;
          
          // 更新全选复选框状态
          const allSelected = appState.dynamics.every(item => item.selected);
          const someSelected = appState.dynamics.some(item => item.selected);
          const selectAllCheckbox = document.getElementById('select-all-checkbox');
          selectAllCheckbox.checked = allSelected;
          selectAllCheckbox.indeterminate = someSelected && !allSelected;
        });
      });
  
      // 绑定查看按钮事件
      document.querySelectorAll('.view-btn').forEach(btn => {
        btn.addEventListener('click', function() {
          const index = parseInt(this.dataset.index);
          viewDynamic(appState.dynamics[index]);
        });
      });
      
      // 绑定删除按钮事件
      document.querySelectorAll('.delete-btn').forEach(btn => {
        btn.addEventListener('click', function() {
          const index = parseInt(this.dataset.index);
          deleteDynamic(appState.dynamics[index]);
        });
      });
      
      // 绑定删除并取关按钮事件
      document.querySelectorAll('.delete-unfollow-btn').forEach(btn => {
        btn.addEventListener('click', function() {
          const index = parseInt(this.dataset.index);
          deleteAndUnfollowDynamic(appState.dynamics[index]);
        });
      });
    }
  
    // 更新动态数量显示
    function updateDynamicsCount() {
      document.getElementById('dynamics-count').textContent = `已加载: ${appState.dynamics.length} 条动态`;
    }
  
    // 勾选所有转发动态
    function selectAllForward() {
      let forwardCount = 0;
      
      appState.dynamics.forEach(item => {
        if (item.type === 'DYNAMIC_TYPE_FORWARD') {
          item.selected = true;
          forwardCount++;
        }
      });
      
      if (forwardCount === 0) {
        alert('暂无转发动态');
        return;
      }
      
      // 更新表格中的复选框
      const itemCheckboxes = document.querySelectorAll('.item-checkbox');
      itemCheckboxes.forEach((cb, index) => {
        if (appState.dynamics[index] && appState.dynamics[index].type === 'DYNAMIC_TYPE_FORWARD') {
          cb.checked = true;
        }
      });
      
      // 更新全选复选框状态
      const allSelected = appState.dynamics.every(item => item.selected);
      const someSelected = appState.dynamics.some(item => item.selected);
      const selectAllCheckbox = document.getElementById('select-all-checkbox');
      selectAllCheckbox.checked = allSelected;
      selectAllCheckbox.indeterminate = someSelected && !allSelected;
      
      alert(`已勾选 ${forwardCount} 条转发动态`);
    }
  
    // 勾选所有抽奖动态
    function selectAllLottery() {
      let lotteryCount = 0;
      
      appState.dynamics.forEach(item => {
        // 检查是否是转发抽奖动态
        if (item.type === 'DYNAMIC_TYPE_FORWARD' && 
            item.orig && 
            item.orig.modules && 
            item.orig.modules.module_dynamic &&
            item.orig.modules.module_dynamic.additional &&
            item.orig.modules.module_dynamic.additional.type === 'ADDITIONAL_TYPE_UPOWER_LOTTERY') {
          item.selected = true;
          lotteryCount++;
        }
      });
      
      if (lotteryCount === 0) {
        alert('暂无抽奖动态');
        return;
      }
      
      // 更新表格中的复选框
      const itemCheckboxes = document.querySelectorAll('.item-checkbox');
      itemCheckboxes.forEach((cb, index) => {
        const item = appState.dynamics[index];
        if (item && item.type === 'DYNAMIC_TYPE_FORWARD' && 
            item.orig && 
            item.orig.modules && 
            item.orig.modules.module_dynamic &&
            item.orig.modules.module_dynamic.additional &&
            item.orig.modules.module_dynamic.additional.type === 'ADDITIONAL_TYPE_UPOWER_LOTTERY') {
          cb.checked = true;
        }
      });
      
      // 更新全选复选框状态
      const allSelected = appState.dynamics.every(item => item.selected);
      const someSelected = appState.dynamics.some(item => item.selected);
      const selectAllCheckbox = document.getElementById('select-all-checkbox');
      selectAllCheckbox.checked = allSelected;
      selectAllCheckbox.indeterminate = someSelected && !allSelected;
      
      alert(`已勾选 ${lotteryCount} 条抽奖动态`);
    }
  
    // 获取类型标签
    function getTypeLabel(item) {
      const type = item.type;
      
      // 处理转发动态
      if (type === 'DYNAMIC_TYPE_FORWARD') {
        if (item.orig && item.orig.modules && item.orig.modules.module_dynamic) {
          const origDynamic = item.orig.modules.module_dynamic;
          // 检查是否是转发抽奖
          if (origDynamic.additional && origDynamic.additional.type === 'ADDITIONAL_TYPE_UPOWER_LOTTERY') {
            return '转发抽奖';
          }
        }
        return '转发';
      }
      
      const typeMap = {
        'DYNAMIC_TYPE_AV': '视频',
        'DYNAMIC_TYPE_WORD': '文字',
        'DYNAMIC_TYPE_DRAW': '图片',
        'DYNAMIC_TYPE_ARTICLE': '文章',
        'DYNAMIC_TYPE_MUSIC': '音频',
        'DYNAMIC_TYPE_COMMON_SQUARE': '分享',
        'DYNAMIC_TYPE_LIVE': '直播',
        'DYNAMIC_TYPE_LIVE_RCMD': '直播推荐'
      };
      
      return typeMap[type] || '其他';
    }
  
    // 获取内容标题
    function getContentTitle(item) {
      // 处理转发动态
      if (item.type === 'DYNAMIC_TYPE_FORWARD') {
        if (item.modules.module_dynamic.desc && item.modules.module_dynamic.desc.text) {
          return `${item.modules.module_dynamic.desc.text}`;
        }
        // 如果转发没有文字,显示转发的原动态标题
        if (item.orig) {
          const origTitle = getOriginalContentTitle(item.orig);
          return `转发:${origTitle}`;
        }
        return '转发动态';
      }
      
      // 处理视频动态
      if (item.modules.module_dynamic.major && item.modules.module_dynamic.major.archive) {
        return item.modules.module_dynamic.major.archive.title;
      }
      
      // 处理图片动态
      if (item.modules.module_dynamic.major && item.modules.module_dynamic.major.opus) {
        if (item.modules.module_dynamic.major.opus.summary) {
          return item.modules.module_dynamic.major.opus.summary.text || '图片动态';
        }
      }
      
      // 处理文字动态
      if (item.modules.module_dynamic.desc && item.modules.module_dynamic.desc.text) {
        return item.modules.module_dynamic.desc.text;
      }
      
      return '无标题';
    }
  
    // 获取原动态的标题(用于转发)
    function getOriginalContentTitle(origItem) {
      if (origItem.modules.module_dynamic.major && origItem.modules.module_dynamic.major.archive) {
        return origItem.modules.module_dynamic.major.archive.title;
      }
      if (origItem.modules.module_dynamic.major && origItem.modules.module_dynamic.major.opus) {
        if (origItem.modules.module_dynamic.major.opus.summary) {
          return origItem.modules.module_dynamic.major.opus.summary.text || '图片动态';
        }
      }
      if (origItem.modules.module_dynamic.desc && origItem.modules.module_dynamic.desc.text) {
        return origItem.modules.module_dynamic.desc.text;
      }
      return '动态内容';
    }
  
    // 获取内容描述
    function getContentDesc(item) {
      // 处理转发动态
      if (item.type === 'DYNAMIC_TYPE_FORWARD' && item.orig) {
        return getOriginalContentDesc(item.orig);
      }
      
      // 处理视频动态
      if (item.modules.module_dynamic.major && item.modules.module_dynamic.major.archive) {
        return item.modules.module_dynamic.major.archive.desc || '';
      }
      
      // 处理图片动态描述
      if (item.modules.module_dynamic.major && item.modules.module_dynamic.major.opus) {
        return '图片动态';
      }
      
      return '';
    }
  
    // 获取原动态的描述(用于转发)
    function getOriginalContentDesc(origItem) {
      if (origItem.modules.module_dynamic.major && origItem.modules.module_dynamic.major.archive) {
        return origItem.modules.module_dynamic.major.archive.desc || '';
      }
      if (origItem.modules.module_dynamic.major && origItem.modules.module_dynamic.major.opus) {
        return '图片动态';
      }
      return '';
    }
  
    // 查看动态
    function viewDynamic(item) {
      // 处理视频动态
      if (item.modules.module_dynamic.major && item.modules.module_dynamic.major.archive) {
        window.open(item.modules.module_dynamic.major.archive.jump_url, '_blank');
        return;
      }
      
      // 处理转发动态
      if (item.type === 'DYNAMIC_TYPE_FORWARD' && item.orig) {
        // 如果原动态是视频,跳转到视频
        if (item.orig.modules.module_dynamic.major && item.orig.modules.module_dynamic.major.archive) {
          window.open(item.orig.modules.module_dynamic.major.archive.jump_url, '_blank');
          return;
        }
        // 如果原动态是图片,跳转到图文
        if (item.orig.modules.module_dynamic.major && item.orig.modules.module_dynamic.major.opus) {
          window.open(item.orig.modules.module_dynamic.major.opus.jump_url, '_blank');
          return;
        }
        // 跳转到原动态
        window.open(`https://t.bilibili.com/${item.orig.id_str}`, '_blank');
        return;
      }
      
      // 处理图片动态
      if (item.modules.module_dynamic.major && item.modules.module_dynamic.major.opus) {
        window.open(item.modules.module_dynamic.major.opus.jump_url, '_blank');
        return;
      }
      
      // 默认跳转到动态页面
      window.open(`https://t.bilibili.com/${item.id_str}`, '_blank');
    }
  
    // 获取CSRF token
    function getCSRFToken() {
      const cookies = document.cookie.split(';');
      for (let cookie of cookies) {
        const [name, value] = cookie.trim().split('=');
        if (name === 'bili_jct') {
          return value;
        }
      }
      return '';
    }
  
    // 删除动态
    async function deleteDynamic(item) {
      const title = getContentTitle(item);
      if (!confirm(`确定要删除这条动态吗?\n${title}`)) {
        return;
      }
      
      try {
        // 获取删除参数
        const deleteParams = item.modules.module_more.three_point_items.find(
          item => item.type === 'THREE_POINT_DELETE'
        );
        
        if (!deleteParams || !deleteParams.params) {
          alert('无法获取删除参数');
          return;
        }
        
        const { dyn_id_str, dyn_type, rid_str } = deleteParams.params;
        const csrf = getCSRFToken();
        
        if (!csrf) {
          alert('未登录或获取CSRF token失败,请先登录B站');
          return;
        }
        
        // 调用删除API
        const response = await fetch(
          `https://api.bilibili.com/x/dynamic/feed/operate/remove?platform=web&csrf=${csrf}`,
          {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Accept': '*/*',
              'Cache-Control': 'no-cache',
              'Pragma': 'no-cache'
            },
            credentials: 'include',
            body: JSON.stringify({
              dyn_id_str,
              dyn_type,
              rid_str
            })
          }
        );
        
        const result = await response.json();
        
        if (result.code === 0) {
          alert('删除成功!');
          // 从本地数据中移除该动态
          const index = appState.dynamics.findIndex(d => d.id_str === item.id_str);
          if (index > -1) {
            appState.dynamics.splice(index, 1);
            updateDynamicsTable();
            updateDynamicsCount();
          }
        } else {
          alert(`删除失败: ${result.message || '未知错误'}`);
        }
      } catch (error) {
        console.error('删除失败:', error);
        if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {
          alert('删除失败:网络连接错误或跨域问题');
        } else {
          alert(`删除失败: ${error.message}`);
        }
      }
    }
  
    // 批量删除动态
    async function batchDeleteDynamics() {
      const selectedItems = appState.dynamics.filter(item => item.selected);
      
      if (selectedItems.length === 0) {
        alert('请先选择要删除的动态');
        return;
      }
      
      if (!confirm(`确定要删除选中的 ${selectedItems.length} 条动态吗?此操作无法撤销!`)) {
        return;
      }
      
      const csrf = getCSRFToken();
      if (!csrf) {
        alert('未登录或获取CSRF token失败,请先登录B站');
        return;
      }
      
      const batchBtn = document.getElementById('batch-delete-btn');
      const originalText = batchBtn.textContent;
      
      let successCount = 0;
      let failCount = 0;
      
      try {
        batchBtn.disabled = true;
        batchBtn.style.opacity = '0.6';
        
        for (let i = 0; i < selectedItems.length; i++) {
          const item = selectedItems[i];
          batchBtn.textContent = `删除中... (${i + 1}/${selectedItems.length})`;
          
          try {
            // 获取删除参数
            const deleteParams = item.modules.module_more.three_point_items.find(
              item => item.type === 'THREE_POINT_DELETE'
            );
            
            if (!deleteParams || !deleteParams.params) {
              console.warn(`动态 ${item.id_str} 无法获取删除参数`);
              failCount++;
              continue;
            }
            
            const { dyn_id_str, dyn_type, rid_str } = deleteParams.params;
            
            // 调用删除API
            const response = await fetch(
              `https://api.bilibili.com/x/dynamic/feed/operate/remove?platform=web&csrf=${csrf}`,
              {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json',
                  'Accept': '*/*',
                  'Cache-Control': 'no-cache',
                  'Pragma': 'no-cache'
                },
                credentials: 'include',
                body: JSON.stringify({
                  dyn_id_str,
                  dyn_type,
                  rid_str
                })
              }
            );
            
            const result = await response.json();
            
            if (result.code === 0) {
              successCount++;
              // 从本地数据中移除该动态
              const index = appState.dynamics.findIndex(d => d.id_str === item.id_str);
              if (index > -1) {
                appState.dynamics.splice(index, 1);
              }
            } else {
              console.error(`删除动态 ${item.id_str} 失败:`, result.message);
              failCount++;
            }
          } catch (error) {
            console.error(`删除动态 ${item.id_str} 出错:`, error);
            failCount++;
          }
          
          // 添加延迟避免请求过于频繁
          if (i < selectedItems.length - 1) {
            await new Promise(resolve => setTimeout(resolve, 1000));
          }
        }
        
        // 更新UI
        updateDynamicsTable();
        updateDynamicsCount();
        
        // 显示结果
        let message = `批量删除完成!\n成功: ${successCount} 条`;
        if (failCount > 0) {
          message += `\n失败: ${failCount} 条`;
        }
        alert(message);
        
      } catch (error) {
        console.error('批量删除失败:', error);
        alert(`批量删除失败: ${error.message}`);
      } finally {
        batchBtn.disabled = false;
        batchBtn.style.opacity = '1';
        batchBtn.textContent = originalText;
      }
    }
  
    // 批量删除并取关
    async function batchDeleteAndUnfollowDynamics() {
      const selectedItems = appState.dynamics.filter(item => item.selected);
      
      if (selectedItems.length === 0) {
        alert('请先选择要删除的动态');
        return;
      }
      
      if (!confirm(`确定要删除选中的 ${selectedItems.length} 条动态并取关对应的用户吗?此操作无法撤销!`)) {
        return;
      }
      
      const csrf = getCSRFToken();
      if (!csrf) {
        alert('未登录或获取CSRF token失败,请先登录B站');
        return;
      }
      
      const batchBtn = document.getElementById('batch-delete-unfollow-btn');
      const originalText = batchBtn.textContent;
      
      let deleteSuccessCount = 0;
      let unfollowSuccessCount = 0;
      let failCount = 0;
      const processedUsers = new Set(); // 记录已处理的用户,避免重复取关
      
      try {
        batchBtn.disabled = true;
        batchBtn.style.opacity = '0.6';
        
        for (let i = 0; i < selectedItems.length; i++) {
          const item = selectedItems[i];
          batchBtn.textContent = `处理中... (${i + 1}/${selectedItems.length})`;
          
          try {
            // 获取删除参数
            const deleteParams = item.modules.module_more.three_point_items.find(
              item => item.type === 'THREE_POINT_DELETE'
            );
            
            if (!deleteParams || !deleteParams.params) {
              console.warn(`动态 ${item.id_str} 无法获取删除参数`);
              failCount++;
              continue;
            }
            
            const { dyn_id_str, dyn_type, rid_str } = deleteParams.params;
            
            // 调用删除API
            const deleteResponse = await fetch(
              `https://api.bilibili.com/x/dynamic/feed/operate/remove?platform=web&csrf=${csrf}`,
              {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json',
                  'Accept': '*/*',
                  'Cache-Control': 'no-cache',
                  'Pragma': 'no-cache'
                },
                credentials: 'include',
                body: JSON.stringify({
                  dyn_id_str,
                  dyn_type,
                  rid_str
                })
              }
            );
            
            const deleteResult = await deleteResponse.json();
            
            if (deleteResult.code === 0) {
              deleteSuccessCount++;
              
              // 删除成功,尝试取关目标作者
              let targetAuthorUid = item.modules.module_author.mid;
              let targetAuthorName = item.modules.module_author.name;
              
              // 如果是转发动态,获取原动态的作者信息
              if (item.type === 'DYNAMIC_TYPE_FORWARD' && item.orig && item.orig.modules && item.orig.modules.module_author) {
                targetAuthorUid = item.orig.modules.module_author.mid;
                targetAuthorName = item.orig.modules.module_author.name;
              }
              
              // 检查是否是自己的动态或者已经处理过这个用户
              if (targetAuthorUid.toString() !== appState.uid && !processedUsers.has(targetAuthorUid)) {
                processedUsers.add(targetAuthorUid);
                
                const unfollowResult = await unfollowUser(targetAuthorUid);
                if (unfollowResult.success) {
                  unfollowSuccessCount++;
                  console.log(`成功取关用户 ${targetAuthorName} (${targetAuthorUid})`);
                } else {
                  console.warn(`取关用户 ${targetAuthorName} (${targetAuthorUid}) 失败: ${unfollowResult.message}`);
                }
                
                // 添加取关操作间的延迟
                await new Promise(resolve => setTimeout(resolve, 500));
              }
              
              // 从本地数据中移除该动态
              const index = appState.dynamics.findIndex(d => d.id_str === item.id_str);
              if (index > -1) {
                appState.dynamics.splice(index, 1);
              }
            } else {
              console.error(`删除动态 ${item.id_str} 失败:`, deleteResult.message);
              failCount++;
            }
          } catch (error) {
            console.error(`处理动态 ${item.id_str} 出错:`, error);
            failCount++;
          }
          
          // 添加延迟避免请求过于频繁
          if (i < selectedItems.length - 1) {
            await new Promise(resolve => setTimeout(resolve, 1000));
          }
        }
        
        // 更新UI
        updateDynamicsTable();
        updateDynamicsCount();
        
        // 显示结果
        let message = `批量操作完成!\n删除动态成功: ${deleteSuccessCount} 条\n取关用户成功: ${unfollowSuccessCount} 个`;
        if (failCount > 0) {
          message += `\n失败: ${failCount} 条`;
        }
        alert(message);
        
      } catch (error) {
        console.error('批量删除并取关失败:', error);
        alert(`批量操作失败: ${error.message}`);
      } finally {
        batchBtn.disabled = false;
        batchBtn.style.opacity = '1';
        batchBtn.textContent = originalText;
      }
    }
  
    // 取关用户
    async function unfollowUser(uid) {
      const csrf = getCSRFToken();
      if (!csrf) {
        throw new Error('未登录或获取CSRF token失败');
      }
      
      try {
        const formData = new URLSearchParams();
        formData.append('act', '2'); // 2表示取消关注
        formData.append('fid', uid.toString());
        formData.append('spmid', '333.1365');
        formData.append('re_src', '0');
        formData.append('csrf', csrf);
        
        const response = await fetch(
          'https://api.bilibili.com/x/relation/modify?statistics=%7B%22appId%22:100,%22platform%22:5%7D',
          {
            method: 'POST',
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded',
              'Accept': '*/*',
              'Cache-Control': 'no-cache',
              'Pragma': 'no-cache'
            },
            credentials: 'include',
            body: formData
          }
        );
        
        const result = await response.json();
        
        if (result.code === 0) {
          return { success: true };
        } else {
          return { success: false, message: result.message || '取关失败' };
        }
      } catch (error) {
        return { success: false, message: error.message };
      }
    }
  
    // 删除并取关动态
    async function deleteAndUnfollowDynamic(item) {
      const title = getContentTitle(item);
      let targetAuthorName = item.modules.module_author.name;
      let targetAuthorUid = item.modules.module_author.mid;
      
      // 如果是转发动态,获取原动态的作者信息
      if (item.type === 'DYNAMIC_TYPE_FORWARD' && item.orig && item.orig.modules && item.orig.modules.module_author) {
        targetAuthorName = item.orig.modules.module_author.name;
        targetAuthorUid = item.orig.modules.module_author.mid;
      }
      
      if (!confirm(`确定要删除这条动态并取关 "${targetAuthorName}" 吗?\n动态:${title}`)) {
        return;
      }
      
      try {
        // 先删除动态
        const deleteParams = item.modules.module_more.three_point_items.find(
          item => item.type === 'THREE_POINT_DELETE'
        );
        
        if (!deleteParams || !deleteParams.params) {
          alert('无法获取删除参数');
          return;
        }
        
        const { dyn_id_str, dyn_type, rid_str } = deleteParams.params;
        const csrf = getCSRFToken();
        
        if (!csrf) {
          alert('未登录或获取CSRF token失败,请先登录B站');
          return;
        }
        
        // 调用删除API
        const deleteResponse = await fetch(
          `https://api.bilibili.com/x/dynamic/feed/operate/remove?platform=web&csrf=${csrf}`,
          {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Accept': '*/*',
              'Cache-Control': 'no-cache',
              'Pragma': 'no-cache'
            },
            credentials: 'include',
            body: JSON.stringify({
              dyn_id_str,
              dyn_type,
              rid_str
            })
          }
        );
        
        const deleteResult = await deleteResponse.json();
        
        if (deleteResult.code === 0) {
          // 删除成功,尝试取关目标作者
          
          // 检查是否是自己的动态,如果是则跳过取关
          if (targetAuthorUid.toString() === appState.uid) {
            alert('删除成功!(跳过取关自己)');
          } else {
            const unfollowResult = await unfollowUser(targetAuthorUid);
            
            if (unfollowResult.success) {
              alert(`删除动态并取关 "${targetAuthorName}" 成功!`);
            } else {
              alert(`删除动态成功,但取关失败: ${unfollowResult.message}`);
            }
          }
          
          // 从本地数据中移除该动态
          const index = appState.dynamics.findIndex(d => d.id_str === item.id_str);
          if (index > -1) {
            appState.dynamics.splice(index, 1);
            updateDynamicsTable();
            updateDynamicsCount();
          }
        } else {
          alert(`删除失败: ${deleteResult.message || '未知错误'}`);
        }
      } catch (error) {
        console.error('删除并取关失败:', error);
        if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {
          alert('操作失败:网络连接错误或跨域问题');
        } else {
          alert(`操作失败: ${error.message}`);
        }
      }
    }
  
  })();