拼多多订单导出与分析

导出拼多多订单并生成详细分析报告,包含商品图片、消费统计与购买趋势分析 改版自 @[seeker](https://greasyfork.org/zh-CN/scripts/534938-%E5%AF%BC%E5%87%BA%E6%8B%BC%E5%A4%9A%E5%A4%9A%E8%AE%A2%E5%8D%95)

当前为 2025-05-08 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name 拼多多订单导出与分析
// @namespace win.somereason.web.utils
// @version 1.0.1
// @description 导出拼多多订单并生成详细分析报告,包含商品图片、消费统计与购买趋势分析 改版自 @[seeker](https://greasyfork.org/zh-CN/scripts/534938-%E5%AF%BC%E5%87%BA%E6%8B%BC%E5%A4%9A%E5%A4%9A%E8%AE%A2%E5%8D%95)
// @author wenmoux
// @match *://mobile.pinduoduo.com/orders.html*
// @grant none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // ===== 数据结构 =====
    let orderData = {
        items: [],
        summary: {
            totalOrders: 0,
            totalAmount: 0,
            averagePrice: 0,
            frequentCategories: {},
            frequentShops: {},
            repurchasedItems: [],
            monthlyTrends: {}
        }
    };

    // ===== 插入控制面板和日志浮窗 =====
    (function setupUI() {
        const controlPanel = document.createElement("div");
        controlPanel.id = "pdd-analysis-panel";
        controlPanel.innerHTML = `
            <style>
                /* Material Design 3 风格 */
                #pdd-analysis-panel {
                    position: fixed;
                    bottom: 20px;
                    right: 20px;
                    width: 360px;
                    background: #ffffff;
                    border-radius: 16px;
                    box-shadow: 0 4px 20px rgba(0,0,0,0.15);
                    padding: 16px;
                    z-index: 9999;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
                    display: flex;
                    flex-direction: column;
                    gap: 12px;
                    transition: all 0.3s ease;
                    max-height: 80vh;
                    overflow-y: auto;
                }
                #pdd-control-buttons {
                    display: flex;
                    gap: 8px;
                }
                .pdd-btn {
                    flex: 1;
                    background-color: #e2231a;
                    color: white;
                    border: none;
                    padding: 12px;
                    border-radius: 8px;
                    font-size: 14px;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    font-weight: 600;
                    text-align: center;
                }
                .pdd-btn:hover {
                    background-color: #c41c14;
                    transform: translateY(-1px);
                }
                .pdd-btn-secondary {
                    background-color: #f5f5f5;
                    color: #333;
                }
                .pdd-btn-secondary:hover {
                    background-color: #e0e0e0;
                }
                #pdd-log-container {
                    max-height: 200px;
                    overflow-y: auto;
                    padding: 10px;
                    background: #f5f5f5;
                    border-radius: 8px;
                    font-size: 13px;
                    color: #333;
                }
                .log-entry {
                    margin-bottom: 6px;
                    padding-bottom: 6px;
                    border-bottom: 1px solid #e0e0e0;
                }
                .log-time {
                    font-size: 11px;
                    color: #888;
                    margin-right: 5px;
                }
                .log-message {
                    font-weight: 500;
                }
                .progress-container {
                    width: 100%;
                    height: 6px;
                    background-color: #e0e0e0;
                    border-radius: 3px;
                    margin-top: 8px;
                }
                .progress-bar {
                    height: 100%;
                    width: 0%;
                    background-color: #e2231a;
                    border-radius: 3px;
                    transition: width 0.3s ease;
                }
                .panel-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 4px;
                }
                .panel-title {
                    font-size: 16px;
                    font-weight: 700;
                    color: #333;
                }
                .panel-actions {
                    display: flex;
                    gap: 8px;
                }
                .panel-action {
                    width: 28px;
                    height: 28px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    background: #f5f5f5;
                    border-radius: 50%;
                    cursor: pointer;
                }
                .panel-action:hover {
                    background: #e0e0e0;
                }
            </style>
            <div class="panel-header">
                <div class="panel-title">拼多多订单分析器</div>
                <div class="panel-actions">
                    <div class="panel-action" id="pdd-panel-minimize" title="最小化">−</div>
                </div>
            </div>
            <div id="pdd-control-buttons">
                <button id="exportOrdersBtn" class="pdd-btn">导出订单数据</button>
                <button id="generateReportBtn" class="pdd-btn pdd-btn-secondary">生成分析报告</button>
            </div>
            <div id="pdd-log-container"></div>
            <div class="progress-container">
                <div class="progress-bar" id="progress-indicator"></div>
            </div>`;
        document.body.appendChild(controlPanel);

        // 事件绑定
        document.getElementById('pdd-panel-minimize').addEventListener('click', function() {
            const panel = document.getElementById('pdd-analysis-panel');
            if (panel.style.height === '42px') {
                panel.style.height = '';
            } else {
                panel.style.height = '42px';
                setTimeout(() => {
                    panel.querySelector('.panel-actions').style.display = 'flex';
                    panel.querySelector('#pdd-control-buttons').style.display = 'none';
                    panel.querySelector('#pdd-log-container').style.display = 'none';
                    panel.querySelector('.progress-container').style.display = 'none';
                }, 300);
            }
        });
    })();

    // ===== 日志记录函数 =====
    window.logMessage = function(msg, type = 'info') {
        const logContainer = document.getElementById('pdd-log-container');
        if (!logContainer) return;

        const logEntry = document.createElement("div");
        logEntry.className = `log-entry log-${type}`;

        const timeSpan = document.createElement("span");
        timeSpan.className = "log-time";
        timeSpan.textContent = `[${new Date().toLocaleTimeString()}]`;

        const messageSpan = document.createElement("span");
        messageSpan.className = "log-message";
        messageSpan.textContent = msg;

        logEntry.appendChild(timeSpan);
        logEntry.appendChild(messageSpan);
        logContainer.appendChild(logEntry);
        logContainer.scrollTop = logContainer.scrollHeight;
    };

    // ===== 进度条更新函数 =====
    function updateProgress(percent) {
        const progressBar = document.getElementById('progress-indicator');
        if (progressBar) {
            progressBar.style.width = `${percent}%`;
        }
    }

    // ===== 自动滚动到底部后调用 callback =====
    function autoScrollUntilDone(callback) {
        let lastHeight = document.body.scrollHeight;
        let noChangeCount = 0;
        let progress = 0;
        logMessage("🚀 开始自动滚动加载更多订单...");
        updateProgress(5);

        const interval = setInterval(() => {
            const doneText = document.querySelector('.loading-text');
            if (doneText && doneText.innerText.includes('您已经没有更多的订单了')) {
                logMessage("✅ 已滚动到底部,加载完成!");
                updateProgress(100);
                clearInterval(interval);
                setTimeout(callback, 1000);
                return;
            }

            const currentHeight = document.body.scrollHeight;
            if (currentHeight === lastHeight) {
                noChangeCount++;
                if (noChangeCount > 5) {
                    window.scrollBy({ top: 1500, behavior: 'smooth' });
                    noChangeCount = 0;
                }
            } else {
                noChangeCount = 0;
                progress = Math.min(95, progress + 5);
                updateProgress(progress);
            }

            lastHeight = currentHeight;
            window.scrollBy({ top: 800, behavior: 'smooth' });
            logMessage("⬇️ 正在加载更多订单...");
        }, 800);
    }

    // ===== 提取订单数据 =====
    function extractOrderData() {
        logMessage("📦 正在提取订单商品信息...");
        orderData.items = [];

        const orderItems = document.querySelectorAll(".U6SAh0Eo");
        if (!orderItems || orderItems.length === 0) {
            logMessage("⚠️ 未找到订单项,请确认页面加载完成", "error");
            return false;
        }orderItems.forEach((item, index) => {
            try {
                // 基本信息提取
                const shopName = item.querySelector('[data-test="店铺名称"]')?.innerText.trim() || "未知店铺";
                const productName = item.querySelector('[data-test="商品名称"]')?.innerText.trim() || "未知商品";
                const productModel = item.querySelector(".bJrhQPD0")?.innerText.trim() || "";
                const price = parseFloat((item.querySelector('[data-test="商品价格"]')?.innerText.replace("¥", "").trim() || "0"));
                const status = item.querySelector('[data-test="订单状态"]')?.innerText.trim() || "";
                const paid = parseFloat((item.querySelector(".pdcOje4N")?.innerText.replace("¥", "").trim() || "0"));

                // 提取图片
                const imgElement = item.querySelector('[data-test="商品图片"] img');
                const imgUrl = imgElement ? imgElement.getAttribute('src') : "";// 提取订单时间
                const orderTimeElement = item.parentNode.querySelector('.MZwI5r1b');
                const orderTime = orderTimeElement ? orderTimeElement.innerText.replace('下单时间:', '').trim() : "";

                // 提取订单号
                const orderIdElement = item.parentNode.querySelector('.TQ8iHK1y');
                const orderId = orderIdElement ? orderIdElement.innerText.replace('订单号:', '').trim() : "";// 商品分类推断(简单基于关键词)
                let category = "其他";
const keywordCategories = {
    "食品生鲜": [
        // 基础食品类
        "食品", "零食", "饼干", "糖果", "巧克力", "坚果", "水果", "蔬菜", "肉", "海鲜", "调料", "酒", "茶", "咖啡",
        // 中国特色零食
        "鲜花饼", "玫瑰花饼", "月饼", "辣条", "休闲食品", "小吃", "批发", "整箱", "网红食品", "麻辣", "手工", "老式",
        // 地方特产
        "土特产", "云南特产", "东北特产", "新疆特产", "广式月饼", "苏式月饼", "粽子", "腊肉", "香肠",
        // 休闲食品细分
        "薯片", "膨化食品", "瓜子", "开心果", "碧根果", "夏威夷果", "腰果", "话梅", "鱿鱼丝", "牛肉干", "猪肉脯",
        // 方便速食
        "方便面", "自热火锅", "自热米饭", "即食", "速食", "冲泡", "螺蛳粉", "酸辣粉", "米线",
        // 生鲜
        "水产", "三文鱼", "龙虾", "大闸蟹", "咸鸭蛋", "松花蛋", "皮蛋", "咸鸭蛋黄", "腊肠"
    ],

    "服饰穿搭": [
        // 基础服装类
        "衣", "裤", "鞋", "袜", "帽", "围巾", "包", "服", "裙", "外套", "内衣", "T恤", "西装", "牛仔",
        // 时尚服装
        "男鞋", "运动鞋", "板鞋", "潮鞋", "小白鞋", "休闲鞋", "古着", "vintage", "宽松", "直筒", "牛仔裤", "男装", "女装", "百搭",
        // 中国风服装
        "汉服", "旗袍", "唐装", "中式服装", "中国风", "复古风", "中式婚礼", "盘扣", "团扇", "香囊",
        // 季节性服装
        "羽绒服", "棉衣", "保暖内衣", "秋裤", "毛衣", "卫衣", "雪地靴", "泳装", "沙滩裤", "防晒衣", "防晒霜",
        // 配饰
        "项链", "耳环", "手镯", "戒指", "发饰", "胸针", "丝巾", "皮带", "钱包", "手表", "墨镜",
        // 家纺
        "干衣机", "烘干机", "风干机", "床单", "四件套", "被罩", "枕套", "毛毯", "凉席", "蚊帐"
    ],

    "家居家装": [
        // 基础家居类
        "床", "沙发", "桌", "椅", "柜", "灯", "窗帘", "地毯", "家具", "装饰", "摆件", "餐具", "厨具",
        // 新增家居
        "香薰机", "香氛", "杯子", "塑料杯", "水杯", "一次性杯", "智能家居", "全屋智能", "小米智能", "排插", "电源板", "开关", "灯具", "空调", "智能开关", "干衣柜",
        // 家装细分
        "床垫", "席梦思", "乳胶床垫", "床头柜", "衣柜", "电视柜", "书柜", "鞋柜", "餐桌", "茶几", "梳妆台", "电脑桌",
        // 厨房用品
        "电饭煲", "电压力锅", "豆浆机", "破壁机", "料理机", "空气炸锅", "微波炉", "电磁炉", "蒸锅", "炒锅", "菜刀", "砧板",
        // 中式家居
        "紫砂壶", "茶具", "茶盘", "香道", "瓷器", "青花瓷", "景德镇", "陶瓷", "刺绣", "十字绣", "福字", "春联", "中国结"
    ],

    "数码电器": [
        // 基础电子类
        "手机", "电脑", "平板", "相机", "耳机", "音箱", "充电器", "电视", "显示器", "键盘", "鼠标",
        // 智能设备
        "智能设备", "米家", "APP智能", "远程控制", "USB", "电量统计", "遥控", "定时开关", "接线端子", "电源板", "数码配件", "分控排插",
        // 手机品牌
        "华为", "小米", "OPPO", "vivo", "苹果", "三星", "荣耀", "红米", "realme", "iQOO",
        // 电脑配件
        "CPU", "显卡", "主板", "内存", "硬盘", "SSD", "机械硬盘", "散热器", "电源", "机箱", "显示器", "路由器",
        // 游戏设备
        "游戏本", "游戏台式机", "游戏显卡", "游戏鼠标", "游戏键盘", "机械键盘", "耳麦", "游戏耳机", "游戏手柄", "RGB灯效",
        // 家用电器
        "冰箱", "洗衣机", "油烟机", "燃气灶", "热水器", "净水器", "空气净化器", "扫地机器人", "加湿器", "吸尘器", "除螨仪"
    ],

    "美妆个护": [
        // 基础美妆类
        "化妆品", "护肤", "面膜", "口红", "粉底", "眼影", "香水", "洗面奶", "护发", "美妆工具",
        // 护肤成分
        "烟酰胺", "珍珠", "海盐", "手工皂", "美白", "黑色素", "改善肤质", "精油", "玻尿酸", "胶原蛋白", "维生素C",
        // 国货美妆
        "花西子", "完美日记", "colorkey", "橘朵", "稚优泉", "美康粉黛", "大宝", "百雀羚", "相宜本草", "百草味",
        // 个人护理
        "洗发水", "护发素", "沐浴露", "身体乳", "香体", "防晒霜", "卫生巾", "洗手液", "消毒液", "漱口水", "牙膏", "牙刷",
        // 男士护理
        "男士护肤", "剃须刀", "刮胡刀", "须后水", "男士面霜", "男士洗面奶", "控油", "祛痘", "美容仪", "脱毛器"
    ],

    "母婴亲子": [
        // 基础母婴类
        "奶粉", "尿布", "婴儿", "童装", "玩具", "孕妇", "奶瓶", "推车", "儿童", "宝宝",
        // 婴幼儿用品
        "婴儿车", "婴儿床", "学步车", "婴儿餐椅", "婴儿洗澡盆", "婴儿背带", "婴儿睡袋", "婴儿枕头", "婴儿床垫",
        // 婴幼儿食品
        "辅食", "婴儿米粉", "婴儿面条", "婴儿饼干", "DHA", "钙铁锌", "益生菌", "鱼肝油", "婴儿营养品",
        // 孕产妇用品
        "月子服", "哺乳内衣", "孕妇裤", "孕妇枕", "孕妇护肤", "防辐射服", "产后修复", "催奶", "吸奶器",
        // 儿童教育
        "早教", "绘本", "识字卡", "拼图", "积木", "乐高", "画板", "学习桌", "书包", "文具盒"
    ],

    "日用百货": [
        // 基础日用品
        "纸巾", "洗发水", "沐浴露", "牙膏", "洗衣液", "清洁", "卫生纸", "毛巾", "卫生巾",
        // 纸品细分
        "抽纸", "原木纸巾", "便携装", "原生木浆", "面巾纸", "餐巾纸", "批发整箱", "家庭装", "湿厕纸", "湿巾",
        // 清洁用品
        "洗衣粉", "消毒剂", "洁厕灵", "管道疏通", "地板清洁", "玻璃清洁", "厨房清洁", "除湿剂", "除味剂", "垃圾袋",
        // 居家日用
        "衣架", "晾衣架", "收纳盒", "收纳箱", "防尘罩", "防潮垫", "防滑垫", "门垫", "蚊香", "电蚊香", "灭蚊灯"
    ],

    "办公文具": [
        // 基础办公用品
        "美工刀", "壁纸刀", "介刀", "刀片", "工具刀", "拆箱刀", "快递刀", "物流刀", "电商用品", "五金工具",
        // 文具
        "笔记本", "签字笔", "中性笔", "钢笔", "铅笔", "橡皮", "文件夹", "档案袋", "订书机", "打孔器", "计算器",
        // 办公耗材
        "复印纸", "打印纸", "彩色纸", "照片纸", "标签纸", "墨盒", "硒鼓", "碳粉", "打印机", "复印机", "扫描仪",
        // 学生文具
        "课本保护套", "作业本", "日记本", "练习册", "书皮", "书套", "尺子", "圆规", "三角板", "涂改液", "荧光笔"
    ],

    "医药健康": [
        // 基础医疗保健
        "口罩", "医用口罩", "外科口罩", "防疫", "防护", "防尘", "抗病毒", "防细菌", "三层防护",
        // 中医药品
        "中药", "中成药", "膏药", "创可贴", "云南白药", "正红花油", "板蓝根", "清热解毒", "感冒灵", "退烧药",
        // 营养保健
        "维生素", "蛋白粉", "钙片", "鱼油", "蜂王浆", "蜂蜜", "阿胶", "燕窝", "人参", "灵芝", "西洋参",
        // 医疗器械
        "血压计", "血糖仪", "体温计", "电子体温计", "雾化器", "制氧机", "助听器", "轮椅", "拐杖", "医用手套",
        // 消毒用品
        "酒精", "碘伏", "过氧化氢", "84消毒液", "免洗洗手液", "消毒湿巾", "紫外线消毒灯"
    ],

    "运动户外": [
        // 基础运动户外
        "运动装备", "户外用品", "运动服装", "运动鞋", "休闲运动", "健身器材",
        // 体育用品
        "篮球", "足球", "排球", "乒乓球", "羽毛球", "网球", "高尔夫", "游泳", "瑜伽垫", "瑜伽服", "健身手套",
        // 户外装备
        "帐篷", "睡袋", "登山包", "户外服装", "户外鞋", "望远镜", "指南针", "登山杖", "野餐垫", "防潮垫", "野营灯",
        // 运动智能
        "智能手环", "运动手表", "心率带", "计步器", "GPS导航", "运动相机", "骑行码表", "骑行灯", "头戴式耳机"
    ],

    "宠物用品": [
        // 基础宠物用品
        "宠物食品", "宠物玩具", "宠物床", "宠物清洁", "宠物医疗", "猫砂", "狗粮", "猫粮",
        // 猫咪用品
        "猫抓板", "猫爬架", "猫窝", "猫厕所", "猫砂盆", "猫粮盆", "猫玩具", "逗猫棒", "猫咪零食", "猫草",
        // 狗狗用品
        "狗窝", "狗链", "狗厕所", "狗尿垫", "狗狗玩具", "狗粮盆", "狗狗衣服", "狗狗鞋", "狗狗零食", "狗狗磨牙",
        // 宠物医疗
        "宠物驱虫", "宠物体外驱虫", "宠物体内驱虫", "宠物疫苗", "宠物消毒", "宠物医院", "宠物保健", "宠物美容"
    ],

    "汽车用品": [
        // 基础汽车用品
        "汽车配件", "车载设备", "汽车装饰", "汽车清洁", "汽车维修", "车载香薰",
        // 车内装饰
        "座垫", "方向盘套", "头枕", "腰靠", "脚垫", "后备箱垫", "香水", "车载挂饰", "车贴", "车衣", "遮阳挡",
        // 车载电子
        "行车记录仪", "车载充电器", "车载蓝牙", "导航仪", "倒车雷达", "胎压监测", "车载净化器", "车载吸尘器",
        // 汽车维护
        "机油", "防冻液", "玻璃水", "轮胎", "电瓶", "雨刷", "灯泡", "刹车片", "火花塞", "汽车贴膜", "洗车工具"
    ],

    "图书文娱": [
        // 新增类别
        "图书", "小说", "文学", "教育", "历史", "科学", "艺术", "杂志", "漫画", "绘本",
        // 教育类
        "教材", "教辅", "考试", "中小学教辅", "大学教材", "考研", "公务员", "英语", "字帖", "课外读物",
        // 文艺类
        "武侠小说", "言情小说", "科幻小说", "悬疑推理", "青春文学", "历史小说", "诗歌", "散文", "传记", "艺术欣赏",
        // 娱乐产品
        "CD", "DVD", "蓝光", "黑胶唱片", "电影", "音乐", "乐器", "吉他", "钢琴", "电子琴", "口琴"
    ],

    "数字虚拟": [
        // 新增类别
        "游戏点卡", "充值卡", "Q币", "视频会员", "音乐会员", "电子书", "虚拟资产", "主题", "皮肤", "表情包",
        // 游戏类
        "网游充值", "手游充值", "王者荣耀", "和平精英", "阴阳师", "LOL", "DNF", "梦幻西游", "游戏装备", "游戏代练",
        // 服务类
        "腾讯视频会员", "爱奇艺会员", "优酷会员", "芒果TV会员", "网易云音乐", "QQ音乐", "酷狗音乐", "喜马拉雅",
        // 电商服务
        "淘宝会员", "京东PLUS", "拼多多会员", "美团会员", "饿了么会员", "滴滴打车券"
    ],

    "礼品鲜花": [
        // 新增类别
        "鲜花", "绿植", "干花", "永生花", "礼盒", "贺卡", "创意礼品", "纪念品", "定制礼品", "生日礼物",
        // 节日礼品
        "春节礼品", "元宵礼品", "情人节礼物", "母亲节礼物", "父亲节礼物", "儿童节礼物", "教师节礼物", "中秋礼品", "圣诞礼物",
        // 鲜花类别
        "玫瑰", "康乃馨", "百合", "向日葵", "郁金香", "满天星", "扶郎花", "马蹄莲", "绣球花", "风信子"
    ],

    "特产区域": [
        // 新增类别
        "华北特产", "东北特产", "华东特产", "华中特产", "华南特产", "西南特产", "西北特产", "港澳台特产", "进口商品",
        // 地方特产
        "新疆特产", "内蒙古特产", "云南特产", "四川特产", "广东特产", "福建特产", "浙江特产", "山东特产", "东北特产",
        // 特产细分
        "大闸蟹", "西湖龙井", "金华火腿", "临安山核桃", "安溪铁观音", "武夷岩茶", "陈皮", "东阿阿胶", "枸杞", "红枣"
    ]
};
                for (const [cat, keywords] of Object.entries(keywordCategories)) {
                    if (keywords.some(word => productName.includes(word))) {
                        category = cat;
                        break;
                    }
                }

                // 构造订单数据对象
                const orderItem = {
                    orderId,
                    shopName,
                    productName,
                    productModel,
                    price,
                    status,
                    paid,
                    imgUrl,
                    orderTime,
                    category,
                    timeStamp: new Date(orderTime).getTime() || Date.now()
                };

                orderData.items.push(orderItem);
            } catch (e) {
                logMessage(`⚠️ 订单项${index+1} 提取失败,已跳过: ${e.message}`, "error");}
        });
        logMessage(`✅ 成功提取 ${orderData.items.length} 条订单信息`);
        return orderData.items.length > 0;
    }

    // ===== 计算数据统计和分析 =====
    function calculateStatistics() {
        logMessage("📊 正在生成数据统计和购买趋势分析...");

        const items = orderData.items;
        if (!items || items.length === 0) {
            logMessage("⚠️ 没有订单数据可供分析", "error");
            return false;
        }

        // 基本统计
        const totalOrders = items.length;
        const totalAmount = items.reduce((sum, item) => sum + item.paid, 0);
        const averagePrice = totalAmount / totalOrders;

        // 分类统计
        const categoryCounts = {};
        const shopCounts = {};
        items.forEach(item => {
            // 品类统计
            categoryCounts[item.category] = (categoryCounts[item.category] || 0) + 1;
            // 店铺统计
            shopCounts[item.shopName] = (shopCounts[item.shopName] || 0) + 1;
        });

        // 常购商品分析(找出相同或相似名称的商品)
        const productNameMap = {};
        items.forEach(item => {
            // 简化商品名称用于匹配(取前10个字符作为基础名称)
            const simpleName = item.productName.substring(0, 10);
            if (!productNameMap[simpleName]) {
                productNameMap[simpleName] = [];
            }
            productNameMap[simpleName].push(item);
        });

        // 找出购买次数超过1次的商品
        const repurchasedItems = [];
        for (const [name, products] of Object.entries(productNameMap)) {
            if (products.length > 1) {
                repurchasedItems.push({
                    name: name,
                    count: products.length,
                    totalSpent: products.reduce((sum, p) => sum + p.paid, 0),
                    items: products
                });
            }
        }

        // 按月消费趋势
        const monthlyTrends = {};
        items.forEach(item => {
            if (item.orderTime) {
                const date = new Date(item.orderTime);
                if (!isNaN(date.getTime())) {
                    const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
                    if (!monthlyTrends[monthKey]) {
                        monthlyTrends[monthKey] = {
                            count: 0,
                            amount: 0,
                            items: []
                        };
                    }
                    monthlyTrends[monthKey].count++;
                    monthlyTrends[monthKey].amount += item.paid;
                    monthlyTrends[monthKey].items.push(item);
                }
            }
        });

        // 保存统计结果
        orderData.summary = {
            totalOrders,
            totalAmount,
            averagePrice,
            frequentCategories: categoryCounts,
            frequentShops: shopCounts,
            repurchasedItems,
            monthlyTrends
        };

        logMessage("✅ 数据统计分析完成!");
        return true;
    }

    // ===== 下载 CSV 文件 =====
    function downloadCSV() {
        logMessage("📄 正在生成 CSV 文件...");let csv = `订单号,店铺名称,商品名称,商品型号,商品价格,订单状态,实付价格,订单时间,商品分类,图片链接\n`;

        orderData.items.forEach(item => {
            csv += `"${item.orderId}","${item.shopName}","${item.productName}","${item.productModel}","${item.price}","${item.status}","${item.paid}","${item.orderTime}","${item.category}","${item.imgUrl}"\n`;
        });const blob = new Blob(['\uFEFF' + csv], { type: "text/csv;charset=utf-8;" });
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = `PDD_订单数据_${new Date().toISOString().slice(0,10)}.csv`;
        document.body.appendChild(a);
        a.click();
        setTimeout(() => {
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }, 100);

        logMessage("✅ CSV 文件导出成功!");
    }

    // ===== 生成HTML报告 =====
    function generateHTMLReport() {
        logMessage("📊 正在生成详细分析报告...");

        // 格式化货币
        const formatCurrency = num => `¥${num.toFixed(2)}`;

        // 准备分类数据
        const categoryLabels = Object.keys(orderData.summary.frequentCategories);
        const categoryData = categoryLabels.map(cat => orderData.summary.frequentCategories[cat]);
        // 准备店铺数据
        const shopLabels = Object.keys(orderData.summary.frequentShops).filter((_, i) => i < 10); // 最多显示前10个店铺
        const shopData = shopLabels.map(shop => orderData.summary.frequentShops[shop]);

        // 准备月度趋势数据
        const trendLabels = Object.keys(orderData.summary.monthlyTrends).sort();
        const trendAmounts = trendLabels.map(month => orderData.summary.monthlyTrends[month].amount);
        const trendCounts = trendLabels.map(month => orderData.summary.monthlyTrends[month].count);

        // 构建报告HTML
        const reportHTML = `
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>拼多多订单分析报告</title>
            <style>
                :root {
                    --primary-color: #e2231a;
                    --secondary-color: #f5762a;
                    --background-color: #f5f5f5;
                    --card-background: #ffffff;
                    --text-color: #333333;
                    --text-secondary: #757575;
                    --border-radius: 16px;
                }
                * {
                    box-sizing: border-box;margin: 0;
                    padding: 0;
                }body {
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
                    background-color: var(--background-color);
                    color: var(--text-color);
                    line-height: 1.6;
                    padding: 20px;
                }

                .container {
                    max-width: 1200px;
                    margin: 0 auto;
                }h1, h2, h3 {
                    color: var(--text-color);
                    margin-bottom: 16px;
                }

                .header {
                    text-align: center;
                    margin-bottom: 40px;
                padding: 24px;
                    background: var(--card-background);
                    border-radius: var(--border-radius);
                    box-shadow: 0 4px 20px rgba(0,0,0,0.08);
                }.header h1 {
                    color: var(--primary-color);
                    font-size: 32px;
                    margin-bottom: 8px;
                }

                .header p {
                    color: var(--text-secondary);
                    font-size: 16px;
                }.summary-cards {
                    display: grid;
                    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
                    gap: 20px;
                margin-bottom: 40px;
                }

                .card {
                    background: var(--card-background);
                    border-radius: var(--border-radius);
                    padding: 24px;
                    box-shadow: 0 4px 20px rgba(0,0,0,0.08);
                }.card-title {
                    font-size: 16px;
                    color: var(--text-secondary);
                    margin-bottom: 8px;
                }

                .card-value {
                    font-size: 28px;
                    font-weight: bold;
                    color: var(--primary-color);
                }.tab-container {
                    margin-bottom: 40px;
                }

                .tab-nav {
                    display: flex;
                    margin-bottom: 20px;
                background: var(--card-background);
                    border-radius: var(--border-radius);
                    padding: 4px;
                    overflow: hidden;
                    box-shadow: 0 4px 20px rgba(0,0,0,0.08);
                }

                .tab-btn {
                    padding: 12px 20px;
                    cursor: pointer;
                    border: none;
                    background: transparent;
                    font-size: 16px;
                    font-weight: 500;
                    color: var(--text-secondary);
                    flex-grow: 1;
                    text-align: center;
                    transition: all 0.3s;border-radius: 12px;
                }.tab-btn.active {
                    color: var(--card-background);
                    background: var(--primary-color);
                }.tab-content {
                    display: none;
                    background: var(--card-background);
                    border-radius: var(--border-radius);
                    padding: 24px;
                    box-shadow: 0 4px 20px rgba(0,0,0,0.08);
                }

                .tab-content.active {
                    display: block;
                }.chart-container {
                    margin-bottom: 40px;height: 400px;
                }.items-grid {
                    display: grid;
                    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
                    gap: 20px;
                    margin-bottom: 40px;
                }

                .item-card {
                    background: var(--card-background);
                    border-radius: var(--border-radius);
                    overflow: hidden;
                    box-shadow: 0 4px 20px rgba(0,0,0,0.08);
                    transition: transform 0.3s ease;
                }.item-card:hover {
                    transform: translateY(-5px);
                }.item-image {
                    height: 200px;
                    overflow: hidden;
                }.item-image img {
                    width: 100%;
                    height: 100%;
                    object-fit: cover;
                    transition: transform 0.3s ease;
                }.item-card:hover .item-image img {
                    transform: scale(1.05);
                }.item-details {
                    padding: 16px;
                }

                .item-name {
                    font-weight: bold;
                    margin-bottom: 8px;
                white-space: nowrap;
                    overflow: hidden;
                    text-overflow: ellipsis;
                }

                .item-shop {
                    color: var(--text-secondary);
                    margin-bottom: 8px;
                font-size: 14px;
                }

                .item-meta {
                    display: flex;
                    justify-content: space-between;
                    color: var(--text-secondary);
                    font-size: 14px;
                }.item-price {
                    color: var(--primary-color);
                    font-weight: bold;
                }.footer {
                    text-align: center;
                    margin-top: 60px;
                    padding: 20px;
                    color: var(--text-secondary);
                }
                table {
                    width: 100%;
                    border-collapse: collapse;
                    margin-bottom: 20px;
                }

                table th, table td {
                    padding: 12px;
                    text-align: left;
                    border-bottom: 1px solid #eeeeee;
                }

                table th {
                    font-weight: 600;
                    background-color: #f9f9f9;
                }.repurchase-stats {
                    display: flex;
                    align-items: center;
                    gap: 12px;
                margin-bottom: 8px;
                flex-wrap: wrap;
                }

                .repurchase-count, .repurchase-total {
                    background: #f3f3f3;
                    border-radius: 20px;
                    padding: 4px 12px;
                    font-size: 14px;
                    font-weight: 500;
                }.repurchase-count {
                    color: var(--secondary-color);
                }

                .repurchase-total {
                    color: var(--primary-color);
                }.repurchase-item {
                    margin-bottom: 24px;
                }

                @media (max-width: 768px) {
                    .summary-cards {
                        grid-template-columns: 1fr;
                    }
                    .items-grid {
                        grid-template-columns: 1fr;
                    }
                }</style>
        </head>
        <body>
            <div class="container">
                <div class="header"><h1>拼多多订单分析报告</h1>
                    <p>生成时间: ${new Date().toLocaleString('zh-CN')}</p>
                </div>
                <div class="summary-cards">
                    <div class="card">
                        <div class="card-title">总订单数</div>
                        <div class="card-value">${orderData.summary.totalOrders}</div>
                    </div>
                    <div class="card">
                        <div class="card-title">总消费金额</div><div class="card-value">${formatCurrency(orderData.summary.totalAmount)}</div>
                    </div><div class="card">
                        <div class="card-title">平均每单</div>
                        <div class="card-value">${formatCurrency(orderData.summary.averagePrice)}</div></div>
                <div class="card">
                        <div class="card-title">常购商品数</div>
                        <div class="card-value">${orderData.summary.repurchasedItems.length}</div></div>
                </div><div class="tab-container">
                    <div class="tab-nav">
                        <button class="tab-btn active" data-tab="overview">消费概览</button><button class="tab-btn" data-tab="category">品类分析</button><button class="tab-btn" data-tab="products">商品分析</button><button class="tab-btn" data-tab="orders">订单明细</button></div>

                    <div id="overview" class="tab-content active">
                        <h2>近期购买的商品</h2>
                        <div class="items-grid">
                            ${orderData.items.slice(0, 6).map(item => `
                                <div class="item-card">
                                    <div class="item-image">
                                        <img src="${item.imgUrl || 'https://img.pddpic.com/mms-material-img/2023-07-19/2c0b7d3b-a63e-42c9-8426-44ea5ed7e84d.png'}" alt="${item.productName}"></div>
                                    <div class="item-details">
                                        <div class="item-name">${item.productName}</div>
                                        <div class="item-shop">${item.shopName}</div>
                                        <div class="item-meta">
                                            <div>${item.orderTime}</div><div class="item-price">${formatCurrency(item.paid)}</div></div></div>
                                </div>
                            `).join('')}</div>
                    </div>
                    <div id="category" class="tab-content">
                        <h2>品类占比</h2>
                        <div class="chart-container">
                            <canvas id="categoryChart"></canvas>
                        </div><h2>店铺分布</h2><div class="chart-container">
                            <canvas id="shopChart"></canvas>
                        </div>
                    </div>    <div id="products" class="tab-content">
                        <h2>经常复购的商品</h2>
                        <div class="items-grid">
                            ${orderData.summary.repurchasedItems.map(item => {
                                // 获取该商品的最新一条订单项
                                const latestItem = item.items.sort((a, b) => {
                                    return new Date(b.orderTime).getTime() - new Date(a.orderTime).getTime();
                                })[0];
                return `
                <div class="item-card repurchase-item">
                                    <div class="item-image">
                                        <img src="${latestItem.imgUrl || 'https://img.pddpic.com/mms-material-img/2023-07-19/2c0b7d3b-a63e-42c9-8426-44ea5ed7e84d.png'}" alt="${item.name}">
                                    </div>
                                    <div class="item-details">
                                        <div class="item-name">${latestItem.productName}</div><div class="item-shop">${latestItem.shopName}</div>
                                        <div class="repurchase-stats">
                                            <div class="repurchase-count">购买${item.count}次</div><div class="repurchase-total">共${formatCurrency(item.totalSpent)}</div></div>
                <div class="item-meta"><div>最近: ${new Date(Math.max(...item.items.map(i => new Date(i.orderTime).getTime()))).toLocaleDateString()}</div>
                                            <div class="item-price">均价: ${formatCurrency(item.totalSpent / item.count)}</div>
                                        </div>
                                    </div></div>
                                `;
                            }).join('')}
                        </div></div>
                <div id="orders" class="tab-content">
                        <h2>订单明细</h2>
                        <table>
                            <thead>
                                <tr>
                                    <th>商品</th><th>店铺</th>
                                    <th>价格</th>
                                    <th>订单时间</th>
                                    <th>状态</th></tr>
                            </thead><tbody>
                                ${orderData.items.map(item => `<tr><td>${item.productName}</td><td>${item.shopName}</td>
                                        <td>${formatCurrency(item.paid)}</td><td>${item.orderTime}</td>
                                        <td>${item.status}</td></tr>
                                `).join('')}
                            </tbody></table>
                    </div>
                </div>

                <div class="footer">
                    <p>数据来源:拼多多订单 · 共${orderData.summary.totalOrders}条记录</p></div>
            </div>
            <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js"></script>
            <script>
                // 标签切换
                document.querySelectorAll('.tab-btn').forEach(button => {
                    button.addEventListener('click', () => {
                document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
                        document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
                        button.classList.add('active');
                        document.getElementById(button.getAttribute('data-tab')).classList.add('active');
                    });
                });

                // 消费趋势图
                const trendCtx = document.getElementById('trendChart').getContext('2d');
                new Chart(trendCtx, {
                    type: 'line',
                    data: {
                        labels: ${JSON.stringify(trendLabels)},
                        datasets: [
                            {
                                label: '消费金额',
                                data: ${JSON.stringify(trendAmounts)},
                                backgroundColor: 'rgba(226, 35, 26, 0.2)',
                                borderColor: 'rgba(226, 35, 26, 1)',
                                borderWidth: 2,tension: 0.3,
                                fill: true
                            },
                            {
                                label: '订单数量',
                                data: ${JSON.stringify(trendCounts)},
                                backgroundColor: 'rgba(245, 118, 42, 0.2)',
                                borderColor: 'rgba(245, 118, 42, 1)',
                                borderWidth: 2,
                                tension: 0.3,
                                yAxisID: 'y1'
                            }
                        ]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        scales: {
                            y: {
                                beginAtZero: true,
                                title: {
                                    display: true,
                                    text: '金额 (元)'
                                }
                            },
                            y1: {
                                beginAtZero: true,
                                position: 'right',
                                title: {
                                    display: true,
                                    text: '订单数'
                                },
                                grid: {
                                    drawOnChartArea: false
                                }
                            }
                        }
                    }
                });

                // 品类占比图
                const categoryCtx = document.getElementById('categoryChart').getContext('2d');
                new Chart(categoryCtx, {
                    type: 'doughnut',
                    data: {
                        labels: ${JSON.stringify(categoryLabels)},
                        datasets: [{
                            data: ${JSON.stringify(categoryData)},
                            backgroundColor: [
                                'rgba(226, 35, 26, 0.8)',
                                'rgba(245, 118, 42, 0.8)',
                                'rgba(255, 193, 7, 0.8)',
                                'rgba(76, 175, 80, 0.8)',
                                'rgba(33, 150, 243, 0.8)',
                                'rgba(156, 39, 176, 0.8)',
                                'rgba(233, 30, 99, 0.8)'
                            ],
                            borderWidth: 1
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: {
                                position: 'right'
                            }
                        }
                    }
                });

                // 店铺分布图
                const shopCtx = document.getElementById('shopChart').getContext('2d');
                new Chart(shopCtx, {
                    type: 'bar',
                    data: {
                        labels: ${JSON.stringify(shopLabels)},
                        datasets: [{
                            label: '订单数量',
                            data: ${JSON.stringify(shopData)},
                            backgroundColor: 'rgba(226, 35, 26, 0.7)',
                            borderWidth: 0
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        scales: {
                            y: {
                                beginAtZero: true
                            }
                        }
                    }
                });
            </script>
        </body>
        </html>
        `;

        // 创建下载
        const blob = new Blob([reportHTML], { type: "text/html;charset=utf-8;" });
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = `PDD_分析报告_${new Date().toISOString().slice(0,10)}.html`;
        document.body.appendChild(a);
        a.click();

        // 自动打开报告
        setTimeout(() => {
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
            window.open(url, '_blank');
        }, 100);

        logMessage("✅ 分析报告生成成功!");
    }

    // ===== 绑定点击事件 =====
    document.getElementById("exportOrdersBtn").addEventListener("click", function() {
        autoScrollUntilDone(() => {
            if (extractOrderData()) {
                calculateStatistics();
                downloadCSV();
            } else {
                logMessage("⚠️ 未找到有效订单数据", "error");
            }
        });
    });

    document.getElementById("generateReportBtn").addEventListener("click", function() {
        if (orderData.items.length > 0) {
            calculateStatistics();
            generateHTMLReport();
        } else {
            logMessage("⚠️ 请先导出订单数据", "error");
            autoScrollUntilDone(() => {
                if (extractOrderData()) {
                    calculateStatistics();
                    generateHTMLReport();
                }
            });
        }
    });

    // ===== 初始化提示 =====
    setTimeout(() => {
        logMessage("🛒 拼多多订单分析工具已加载,点击按钮开始导出/分析");
    }, 1000);
})();