UNPKG

bytefun

Version:

一个打通了原型设计、UI设计与代码转换、跨平台原生代码开发等的平台

2,052 lines 73.4 kB
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>枫叶小说APP 产品需求文档编辑器</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <script src="https://unpkg.com/mermaid@10/dist/mermaid.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        :root {
            --bg-primary: #1B1B1B;
            --bg-secondary: #232323;
            --bg-tertiary: #2C2C2C;
            --bg-text: #494949;
            --text-primary: #FFFFFF;
            --text-secondary: #8E8E93;
            --border-color: #2C2C2C;
            --input-bg: #232323;
            --light-title-bg: #373737;
        }

        [data-theme="light"] {
            --bg-primary: #FDFDFD;
            --bg-secondary: #F5F5F5;
            --bg-tertiary: #E8E8E8;
            --bg-text: #E8E8E8;
            --text-primary: #1C1C1E;
            --text-secondary: #6D6D70;
            --border-color: #D1D1D6;
            --input-bg: #FFFFFF;
            --light-title-bg: #00000000;
        }

        body {
            font-family: 'Poppins', 'Arial', sans-serif;
            background-color: var(--bg-primary);
            color: var(--text-primary);
            line-height: 1.6;
            transition: background-color 0.3s ease, color 0.3s ease;
            padding: 0px;
        }

        .container {
            margin-left: 120px;
            margin-right: 0;
            transition: all 0.3s ease;
            min-height: 100vh;
        }

        .container.sidebar-collapsed {
            margin-left: 0;
        }



        .section {
            background: var(--bg-secondary);
            padding-top: 30px;
            padding-left: 30px;
            padding-right: 10px;
        }

        .section-title {
            font-size: 18px;
            font-weight: 600;
            color: var(--text-primary);
            margin-bottom: 8px;
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .subsection {
            margin-bottom: 8px;
        }

        .subsection-title {
            font-size: 16px;
            font-weight: 500;
            color: var(--text-primary);
            margin-bottom: 8px;
            display: flex;
            align-items: center;
            gap: 6px;
        }



        .content-item-title {
            font-size: 14px;
            font-weight: 500;
            color: var(--text-primary);
            margin-bottom: 6px;
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .content-text {
            font-size: 14px;
            color: var(--text-secondary);
            line-height: 1.5;
        }

        .title-input {
            background: var(--input-bg);
            border: none;
            border-radius: 4px;
            padding: 5px;
            color: var(--text-primary);
            font-size: 14px;
            width: 100%;
            transition: background-color 0.3s ease;
        }

        .title-input:focus {
            outline: none;
        }

        .section-title .title-input {
            font-size: 17px;
            font-weight: 700;
        }

        .content-item-title .title-input {
            font-size: 15px;
            font-weight: 700;
        }

        .content-textarea {
            background: var(--input-bg);
            border: none;
            border-radius: 4px;
            padding: 8px 12px;
            color: var(--text-primary);
            font-size: 14px;
            width: 100%;
            resize: none;
            font-family: inherit;
            transition: background-color 0.3s ease;
            overflow: hidden;
            box-sizing: border-box;
        }

        .content-textarea:focus {
            outline: none;
        }



        .title-with-add {
            display: block;
        }

        .title-with-add .section-title {
            margin-bottom: 0;
            display: flex;
            align-items: center;
        }

        .title-with-add .content-item-title {
            display: flex;
            align-items: center;
        }

        .content-item {
            background: var(--bg-secondary);
            border-radius: 6px;
            padding-right: 12px;
            position: relative;
        }

        .content-item .title-with-add {
            padding-right: 0;
        }



        .save-button {
            position: fixed;
            top: 20px;
            right: 130px;
            background: var(--bg-primary);
            border: 1px solid var(--border-color);
            border-radius: 20px;
            padding: 6px 12px;
            cursor: pointer;
            font-size: 12px;
            color: var(--text-primary);
            transition: all 0.3s ease;
            z-index: 1000;
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .save-button:hover {
            background: var(--bg-tertiary);
        }

        .theme-toggle {
            position: fixed;
            top: 20px;
            right: 36px;
            background: var(--bg-primary);
            border: 1px solid var(--border-color);
            border-radius: 20px;
            padding: 6px 12px;
            cursor: pointer;
            font-size: 12px;
            color: var(--text-primary);
            transition: all 0.3s ease;
            z-index: 1000;
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .theme-toggle:hover {
            background: var(--bg-tertiary);
        }

        .nested-content {
            margin-left: 20px;
            border-left: 2px solid var(--border-color);
            padding-left: 12px;
        }

        /* Mermaid图表样式 */
        .mermaid-container {
            background: var(--bg-secondary);
            border-radius: 8px;
            padding: 0;
            margin: 12px 0;
            border: 1px solid var(--border-color);
            overflow: hidden;
        }

        /* Mermaid Tab样式 */
        .mermaid-tabs {
            display: flex;
            background: var(--bg-tertiary);
            border-bottom: 1px solid var(--border-color);
        }

        .mermaid-tab {
            padding: 12px 20px;
            background: transparent;
            border: none;
            color: var(--text-secondary);
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s ease;
            border-bottom: 2px solid transparent;
        }

        .mermaid-tab:hover {
            background: var(--bg-secondary);
            color: var(--text-primary);
        }

        .mermaid-tab.active {
            background: var(--bg-secondary);
            color: var(--text-primary);
        }

        .mermaid-content {
            padding: 0px;
        }

        .mermaid-tab-panel {
            display: none;
        }

        .mermaid-tab-panel.active {
            display: block;
        }

        .mermaid {
            border-radius: 6px;
            margin-bottom: 12px;
            text-align: center;
            transform-origin: center center;
            transition: transform 0.2s ease;
            overflow: hidden;
            position: relative;
            cursor: grab;
        }

        .mermaid:active {
            cursor: grabbing;
        }

        .mermaid svg {
            max-width: none;
            height: auto;
        }

        /* Mermaid代码显示样式 */
        .mermaid-code {
            background: #1e1e1e;
            color: #d4d4d4;
            padding: 16px;
            border-radius: 6px;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 13px;
            line-height: 1.5;
            white-space: pre-wrap;
            word-wrap: break-word;
            max-height: 400px;
            overflow-y: auto;
            border: 1px solid var(--border-color);
        }

        /* Mermaid代码编辑器样式 */
        .mermaid-code-editor {
            width: 100%;
            min-height: 300px;
            max-height: 500px;
            background: #1e1e1e;
            color: #d4d4d4;
            padding: 16px;
            border-radius: 6px;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 13px;
            line-height: 1.5;
            border: 1px solid var(--border-color);
            resize: vertical;
            outline: none;
            transition: border-color 0.3s ease;
        }

        .mermaid-code-editor:focus {
            border-color: var(--border-color);
            box-shadow: none;
        }

        .edit-mermaid-btn {
            background: #007AFF;
            color: white;
            border: none;
            border-radius: 4px;
            padding: 6px 12px;
            font-size: 12px;
            cursor: pointer;
            transition: background-color 0.3s ease;
            display: flex;
            align-items: center;
            gap: 4px;
        }

        .edit-mermaid-btn:hover {
            background: #0056CC;
        }

        /* 重置流程图按钮 */
        .reset-mermaid-btn {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #1d1d1d;
            color: white;
            border: none;
            border-radius: 25px;
            padding: 12px 20px;
            font-size: 11px;
            font-weight: 500;
            cursor: pointer;
            box-shadow: 0 4px 12px rgba(73, 73, 73, 0.3);
            transition: all 0.3s ease;
            z-index: 1000;
            display: none;
            align-items: center;
            gap: 6px;
        }

        .reset-mermaid-btn:hover {
            background: #202020;
            transform: translateY(-1px);
        }

        .reset-mermaid-btn.show {
            display: flex;
        }

        .item-controls {
            display: flex;
            gap: 8px;
            margin-top: 8px;
        }

        .item-controls button {
            font-size: 12px;
            padding: 4px 8px;
        }

        /* 自定义确认弹框样式 */
        .custom-confirm-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
            opacity: 0;
            visibility: hidden;
            transition: opacity 0.3s ease, visibility 0.3s ease;
        }

        .custom-confirm-overlay.show {
            opacity: 1;
            visibility: visible;
        }

        .custom-confirm-dialog {
            background: var(--bg-secondary);
            border-radius: 8px;
            padding: 24px;
            max-width: 400px;
            width: 90%;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
            border: 1px solid var(--border-color);
        }

        .custom-confirm-message {
            color: var(--text-primary);
            font-size: 16px;
            margin-bottom: 20px;
            text-align: center;
        }

        .custom-confirm-buttons {
            display: flex;
            gap: 12px;
            justify-content: center;
        }

        .custom-confirm-btn {
            padding: 8px 16px;
            border: none;
            border-radius: 6px;
            font-size: 14px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }

        .custom-confirm-btn.cancel {
            background: var(--bg-tertiary);
            color: var(--text-primary);
        }

        .custom-confirm-btn.cancel:hover {
            background: var(--bg-text);
        }

        .custom-confirm-btn.confirm {
            background: #FF3B30;
            color: white;
        }

        .custom-confirm-btn.confirm:hover {
            background: #E6342A;
        }

        /* 侧滑面板样式 */
        .sidebar {
            position: fixed;
            left: 0;
            top: 0;
            width: 130px;
            height: 100vh;
            background: var(--bg-secondary);
            border-right: 1px solid var(--border-color);
            z-index: 999;
            overflow-y: auto;
            transition: transform 0.3s ease;
            transform: translateX(0);
            /* 隐藏滚动条但保持滚动功能 */
            scrollbar-width: none;
            /* Firefox */
            -ms-overflow-style: none;
            /* IE and Edge */
        }

        /* 隐藏 Webkit 浏览器的滚动条 */
        .sidebar::-webkit-scrollbar {
            display: none;
        }

        .sidebar.collapsed {
            transform: translateX(-130px);
        }

        /* 收起状态下的圆形箭头图标 */
        .sidebar-expand-btn {
            position: fixed;
            left: 10px;
            top: 10px;
            width: 30px;
            height: 30px;
            background: var(--bg-secondary);
            border: 1px solid var(--border-color);
            border-radius: 50%;
            display: none;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            z-index: 1000;
            transition: all 0.3s ease;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        }

        .sidebar-expand-btn:hover {
            background: var(--bg-tertiary);
            transform: scale(1.05);
        }

        .sidebar-expand-btn i {
            color: var(--text-primary);
            font-size: 16px;
        }

        .sidebar.collapsed~.sidebar-expand-btn {
            display: flex;
        }

        .sidebar-header {
            padding: 16px;
            border-bottom: 1px solid var(--border-color);
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .sidebar-title {
            font-size: 16px;
            font-weight: 600;
            color: var(--text-primary);
        }

        .sidebar-toggle {
            background: none;
            border: none;
            color: var(--text-primary);
            cursor: pointer;
            padding: 4px;
            border-radius: 4px;
            transition: background-color 0.3s ease;
        }

        .sidebar-toggle:hover {
            background: var(--bg-tertiary);
        }

        .toc-container {
            padding: 0px;
        }

        .toc-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 4px 6px;
            color: var(--text-secondary);
            text-decoration: none;
            border-radius: 3px;
            margin-bottom: 1px;
            font-size: 11px;
            line-height: 1.3;
            cursor: pointer;
            transition: all 0.3s ease;
            position: relative;
        }

        .toc-item-text {
            flex: 1;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            min-width: 0;
        }

        .toc-item-buttons {
            display: none;
            gap: 2px;
            margin-left: 4px;
            flex-shrink: 0;
        }

        .toc-item:hover .toc-item-buttons {
            display: flex;
        }

        .toc-btn {
            width: 14px;
            height: 14px;
            border: none;
            border-radius: 2px;
            font-size: 8px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s ease;
        }

        .toc-add-btn {
            background: #34C759;
            color: white;
            margin-right: 2px;
            margin-bottom: 3px;
        }

        .toc-add-btn:hover {
            background: #30B050;
        }

        .toc-delete-btn {
            background: #FF3B30;
            color: white;
            margin-top: 1px;
        }

        .toc-delete-btn:hover {
            background: #E6342A;
        }

        .toc-item:hover {
            background: var(--bg-tertiary);
            color: var(--text-primary);
        }

        .toc-item.active {
            background: var(--light-title-bg);
            color: var(--text-primary);
        }

        .toc-item.level-1 {
            font-weight: 600;
            padding-left: 8px;
            font-size: 12px;
        }

        .toc-item.level-2 {
            padding-left: 15px;
            font-size: 11px;
        }

        .toc-item.level-3 {
            padding-left: 22px;
            font-size: 10px;
        }

        @media (max-width: 768px) {
            .container {
                margin-left: 120px;
            }

            .container.sidebar-collapsed {
                margin-left: 0;
            }

            .sidebar {
                width: 140px;
            }

            .sidebar.collapsed {
                transform: translateX(-140px);
            }

            .title-with-add {
                flex-direction: column;
                align-items: stretch;
            }

            .nested-content {
                margin-left: 10px;
                padding-left: 8px;
            }
        }
    </style>
</head>

<body>
    <!-- 侧滑面板 -->
    <div class="sidebar" id="sidebar">
        <div class="sidebar-header">
            <div class="sidebar-title">文档目录</div>
            <button class="sidebar-toggle" onclick="toggleSidebar()">
                <i class="fas fa-chevron-left"></i>
            </button>
        </div>
        <div class="toc-container" id="toc-container">
            <!-- 目录将通过JavaScript动态生成 -->
        </div>
    </div>

    <!-- 收起状态下的圆形箭头图标 -->
    <div class="sidebar-expand-btn" onclick="toggleSidebar()">
        <i class="fas fa-chevron-right"></i>
    </div>

    <!-- 自定义确认弹框 -->
    <div id="customConfirmOverlay" class="custom-confirm-overlay">
        <div class="custom-confirm-dialog">
            <div id="customConfirmMessage" class="custom-confirm-message"></div>
            <div class="custom-confirm-buttons">
                <button class="custom-confirm-btn cancel" onclick="hideCustomConfirm(false)">取消</button>
                <button class="custom-confirm-btn confirm" onclick="hideCustomConfirm(true)">确认</button>
            </div>
        </div>
    </div>

    <!-- 重置流程图按钮 -->
    <button id="resetMermaidBtn" class="reset-mermaid-btn" onclick="resetMermaidTransform()">
        <i class="fas fa-undo"></i>
        重置流程图
    </button>

    <div class="container">
        <div class="save-button" onclick="saveConfig()" style="position: fixed; z-index: 1000; margin: 0;">
            <i class="fas fa-save"></i>
            <span>保存</span>
        </div>
        <div class="theme-toggle" onclick="toggleTheme()" style="position: fixed; z-index: 1000; margin: 0;">
            <i class="fas fa-sun"></i>
            <span id="theme-text">亮色模式</span>
        </div>

        <!-- 动态生成的内容区域 -->
        <div id="content-container">
            <!-- 内容将通过JavaScript动态生成 -->
        </div>
    </div>

    <script>
        // PRD数据结构 - 完整的JSON数据
        let prdData = {
            "productRequirementDocument": {
                "title": "xxx产品需求文档",
                "sections": {
                    "projectBackground": {
                        "title": "一、项目的背景",
                        "content": [
                            {
                                "title": "1、项目概述",
                                "content": "xxx"
                            },
                            {
                                "title": "2、用户痛点分析",
                                "content": [
                                    {
                                        "title": "阅读体验差",
                                        "content": "现有应用广告干扰严重,影响沉浸式阅读体验"
                                    },
                                    {
                                        "title": "内容发现困难",
                                        "content": "缺乏精准的个性化推荐,用户难以找到喜欢的作品"
                                    }
                                ]
                            },
                            {
                                "title": "3、目标用户群体",
                                "content": [
                                    {
                                        "title": "主要用户",
                                        "content": "18-35岁的年轻人群,喜欢利用碎片时间阅读"
                                    },
                                    {
                                        "title": "次要用户",
                                        "content": "35岁以上的人群,对阅读有一定需求"
                                    }
                                ]
                            }
                        ]
                    },
                    "businessLogicFlow": {
                        "title": "二、功能模块业务逻辑流程图",
                        "content": "flowchart TD\n    A[启动应用] --> B{是否首次启动}\n"
                    },
                    "functionalRequirements": {
                        "title": "三、功能模块列表与需要描述",
                        "moduleList": [
                            {
                                "title": "1、启动模块",
                                "cnName": "启动模块",
                                "enName": "startup",
                                "content": [
                                    {
                                        "title": "1.1、xxx功能",
                                        "content": "xxx(描述该功能作用)"
                                    },
                                    {
                                        "title": "1.2、xxx功能",
                                        "content": "xxx(描述该功能作用)"
                                    }
                                ]
                            },
                            {
                                "title": "2、账号模块",
                                "cnName": "账号模块",
                                "enName": "account",
                                "content": [
                                    {
                                        "title": "2.1、xxx功能",
                                        "content": "xxx(描述该功能作用)"
                                    },
                                    {
                                        "title": "2.2、xxx功能",
                                        "content": "xxx(描述该功能作用)"
                                    }
                                ]
                            }
                        ]
                    }
                }
            }
        }

        // 记录数据来源,用于保存时确定保存路径
        let fromWhere = 'prd'

        // 获取数据根对象
        function getDataRoot() {
            if (prdData.productRequirementDocument) {
                return prdData.productRequirementDocument;
            } else if (prdData.moduleBusinessLogicDesign) {
                return prdData.moduleBusinessLogicDesign;
            }
            return null;
        }

        // 渲染所有内容
        function renderAll() {
            const container = document.getElementById('content-container');
            if (!container) {
                console.error('content-container element not found');
                return;
            }

            // 检查数据是否已加载
            const dataRoot = getDataRoot();
            if (!dataRoot || !dataRoot.sections) {
                console.warn('数据尚未加载,跳过渲染');
                return;
            }

            container.innerHTML = '';

            // 更新文档标题
            const titleElement = document.getElementById('document-title');
            if (titleElement) {
                titleElement.textContent = dataRoot.title;
            }

            // 渲染各个章节
            const sections = dataRoot.sections;
            Object.keys(sections).forEach(sectionKey => {
                const section = sections[sectionKey];
                const sectionElement = createSection(sectionKey, section);
                container.appendChild(sectionElement);
            });


        }



        // 创建章节
        function createSection(sectionKey, sectionData) {
            const section = document.createElement('div');
            section.className = 'section';
            section.dataset.sectionKey = sectionKey;

            // 检查不同的内容数组字段:pageList, moduleList, content
            const contentData = sectionData.pageList || sectionData.moduleList || sectionData.content;

            section.innerHTML = `
                <div class="title-with-add">
                    <h2 class="section-title">
                        <input type="text" class="title-input" value="${sectionData.title}" 
                               onchange="updateSectionTitle('${sectionKey}', this.value)">
                    </h2>
                </div>
                <div class="content-area" id="content-${sectionKey}">
                    <!-- 内容将动态生成 -->
                </div>
            `;

            // 渲染内容
            const contentArea = section.querySelector(`#content-${sectionKey}`);
            renderSectionContent(contentArea, sectionKey, contentData);

            return section;
        }

        // 渲染章节内容
        function renderSectionContent(container, sectionKey, content) {
            container.innerHTML = '';

            if (typeof content === 'string') {
                // 检查是否是mermaid图表代码
                if (content.trim().startsWith('flowchart') ||
                    content.trim().startsWith('graph') ||
                    content.trim().startsWith('sequenceDiagram') ||
                    content.trim().startsWith('gantt') ||
                    content.trim().startsWith('pie') ||
                    content.trim().startsWith('gitGraph')) {
                    // Mermaid图表内容
                    const mermaidContainer = document.createElement('div');
                    mermaidContainer.className = 'mermaid-container';

                    // 创建tab导航
                    const tabsDiv = document.createElement('div');
                    tabsDiv.className = 'mermaid-tabs';

                    const chartTab = document.createElement('button');
                    chartTab.className = 'mermaid-tab active';
                    chartTab.textContent = '流程图';
                    chartTab.onclick = () => switchMermaidTab(mermaidContainer, 'chart');

                    const codeTab = document.createElement('button');
                    codeTab.className = 'mermaid-tab';
                    codeTab.textContent = 'Mermaid代码';
                    codeTab.onclick = () => switchMermaidTab(mermaidContainer, 'code');

                    tabsDiv.appendChild(chartTab);
                    tabsDiv.appendChild(codeTab);

                    // 创建内容区域
                    const contentDiv = document.createElement('div');
                    contentDiv.className = 'mermaid-content';

                    // 流程图面板
                    const chartPanel = document.createElement('div');
                    chartPanel.className = 'mermaid-tab-panel active';
                    chartPanel.setAttribute('data-panel', 'chart');

                    const mermaidDiv = document.createElement('div');
                    mermaidDiv.className = 'mermaid';
                    mermaidDiv.textContent = content;
                    chartPanel.appendChild(mermaidDiv);

                    // 代码面板
                    const codePanel = document.createElement('div');
                    codePanel.className = 'mermaid-tab-panel';
                    codePanel.setAttribute('data-panel', 'code');

                    const codeTextarea = document.createElement('textarea');
                    codeTextarea.className = 'mermaid-code-editor';
                    codeTextarea.value = content;
                    codeTextarea.onchange = () => updateMermaidCode(sectionKey, codeTextarea.value, mermaidDiv);
                    codePanel.appendChild(codeTextarea);

                    contentDiv.appendChild(chartPanel);
                    contentDiv.appendChild(codePanel);

                    mermaidContainer.appendChild(tabsDiv);
                    mermaidContainer.appendChild(contentDiv);
                    container.appendChild(mermaidContainer);

                    // 初始化mermaid渲染
                    setTimeout(() => {
                        if (window.mermaid) {
                            window.mermaid.init(undefined, mermaidDiv);
                        }
                    }, 100);
                } else {
                    // 普通字符串内容
                    const textArea = document.createElement('textarea');
                    textArea.className = 'content-textarea';
                    textArea.value = content;
                    textArea.onchange = () => updateSectionContent(sectionKey, textArea.value);
                    container.appendChild(textArea);
                }
            } else if (Array.isArray(content)) {
                // 数组内容
                content.forEach((item, index) => {
                    const itemElement = createContentItem(sectionKey, item, index);
                    container.appendChild(itemElement);
                });
            } else if (typeof content === 'object' && content.mermaid) {
                // Mermaid图表内容
                const mermaidContainer = document.createElement('div');
                mermaidContainer.className = 'mermaid-container';

                const mermaidDiv = document.createElement('div');
                mermaidDiv.className = 'mermaid';
                mermaidDiv.textContent = content.mermaid;

                const editButton = document.createElement('button');
                editButton.className = 'edit-mermaid-btn';
                editButton.innerHTML = '<i class="fas fa-edit"></i> 编辑图表';
                editButton.onclick = () => editMermaidContent(sectionKey, content.mermaid);

                mermaidContainer.appendChild(mermaidDiv);
                mermaidContainer.appendChild(editButton);
                container.appendChild(mermaidContainer);

                // 初始化mermaid渲染
                setTimeout(() => {
                    if (window.mermaid) {
                        window.mermaid.init(undefined, mermaidDiv);
                    }
                }, 100);
            }
        }

        // 创建内容项
        function createContentItem(sectionKey, item, index) {
            const itemDiv = document.createElement('div');
            itemDiv.className = 'content-item';
            itemDiv.dataset.index = index;

            itemDiv.innerHTML = `
                <div class="title-with-add">
                    <h3 class="content-item-title" style="margin-left: 20px;">
                        <input type="text" class="title-input" value="${item.title}" style="background: var(--light-title-bg);"
                               onchange="updateContentItemTitle('${sectionKey}', ${index}, this.value)">
                    </h3>
                </div>
                <div class="content-area" id="nested-content-${sectionKey}-${index}">
                    <!-- 嵌套内容将动态生成 -->
                </div>
            `;

            // 渲染嵌套内容
            const nestedContentArea = itemDiv.querySelector(`#nested-content-${sectionKey}-${index}`);
            renderNestedContent(nestedContentArea, sectionKey, index, item.content);

            return itemDiv;
        }

        // 渲染嵌套内容
        function renderNestedContent(container, sectionKey, itemIndex, content) {
            container.innerHTML = '';

            if (typeof content === 'string') {
                // 字符串内容
                const textArea = document.createElement('textarea');
                textArea.className = 'content-textarea';
                textArea.value = content;
                textArea.onchange = () => updateContentItemContent(sectionKey, itemIndex, textArea.value);
                container.appendChild(textArea);
            } else if (Array.isArray(content)) {
                // 数组内容(嵌套)
                const nestedDiv = document.createElement('div');
                nestedDiv.className = 'nested-content';

                content.forEach((nestedItem, nestedIndex) => {
                    const nestedItemElement = createNestedContentItem(sectionKey, itemIndex, nestedItem, nestedIndex);
                    nestedDiv.appendChild(nestedItemElement);
                });

                container.appendChild(nestedDiv);
            }
        }

        // 创建嵌套内容项
        function createNestedContentItem(sectionKey, itemIndex, nestedItem, nestedIndex) {
            const nestedItemDiv = document.createElement('div');
            nestedItemDiv.className = 'content-item';
            nestedItemDiv.dataset.nestedIndex = nestedIndex;

            nestedItemDiv.innerHTML = `
                <div class="title-with-add">
                    <h4 class="content-item-title">
                        <input type="text" class="title-input" value="${nestedItem.title}" style="font-size: 13px;"
                               onchange="updateNestedContentItemTitle('${sectionKey}', ${itemIndex}, ${nestedIndex}, this.value)">
                    </h4>
                </div>
                <textarea class="content-textarea" 
                          onchange="updateNestedContentItemContent('${sectionKey}', ${itemIndex}, ${nestedIndex}, this.value)">${nestedItem.content}</textarea>
            `;

            return nestedItemDiv;
        }

        // 更新文档标题
        // 更新章节标题
        function updateSectionTitle(sectionKey, newTitle) {
            const dataRoot = getDataRoot();
            dataRoot.sections[sectionKey].title = newTitle;
        }

        // 获取章节内容数组的辅助函数
        function getSectionContentArray(sectionKey) {
            const dataRoot = getDataRoot();
            const section = dataRoot.sections[sectionKey];
            return section.pageList || section.moduleList || section.content;
        }

        // 设置章节内容数组的辅助函数
        function setSectionContentArray(sectionKey, contentArray) {
            const dataRoot = getDataRoot();
            const section = dataRoot.sections[sectionKey];
            if (section.pageList !== undefined) {
                section.pageList = contentArray;
            } else if (section.moduleList !== undefined) {
                section.moduleList = contentArray;
            } else {
                section.content = contentArray;
            }
        }

        // 更新章节内容
        function updateSectionContent(sectionKey, newContent) {
            const dataRoot = getDataRoot();
            const section = dataRoot.sections[sectionKey];
            if (section.pageList !== undefined) {
                section.pageList = newContent;
            } else if (section.moduleList !== undefined) {
                section.moduleList = newContent;
            } else {
                section.content = newContent;
            }
        }

        // 更新内容项标题
        function updateContentItemTitle(sectionKey, index, newTitle) {
            const contentArray = getSectionContentArray(sectionKey);
            contentArray[index].title = newTitle;
        }

        // 更新内容项内容
        function updateContentItemContent(sectionKey, index, newContent) {
            const contentArray = getSectionContentArray(sectionKey);
            contentArray[index].content = newContent;
        }

        // 更新嵌套内容项标题
        function updateNestedContentItemTitle(sectionKey, itemIndex, nestedIndex, newTitle) {
            const contentArray = getSectionContentArray(sectionKey);
            contentArray[itemIndex].content[nestedIndex].title = newTitle;
        }

        // 更新嵌套内容项内容
        function updateNestedContentItemContent(sectionKey, itemIndex, nestedIndex, newContent) {
            const contentArray = getSectionContentArray(sectionKey);
            contentArray[itemIndex].content[nestedIndex].content = newContent;
        }

        // 添加内容项
        function addContentItem(sectionKey) {
            const dataRoot = getDataRoot();
            const section = dataRoot.sections[sectionKey];

            // 根据章节类型创建不同的新项目结构
            let newItem;
            if (section.pageList !== undefined) {
                // 对于pageList类型,添加页面相关的默认字段
                newItem = {
                    title: '新页面',
                    content: []
                };
            } else {
                // 对于其他类型,使用标准结构
                newItem = {
                    title: '新内容项',
                    content: ''
                };
            }

            let contentArray = getSectionContentArray(sectionKey);
            if (!Array.isArray(contentArray)) {
                contentArray = [];
                setSectionContentArray(sectionKey, contentArray);
            }

            contentArray.push(newItem);
            renderAll();
        }

        // 添加嵌套内容项
        function addNestedContentItem(sectionKey, itemIndex) {
            const newNestedItem = {
                title: '新子内容项',
                content: ''
            };

            const contentArray = getSectionContentArray(sectionKey);
            const item = contentArray[itemIndex];
            if (!Array.isArray(item.content)) {
                item.content = [];
            }

            item.content.push(newNestedItem);
            renderAll();
        }

        // 删除内容项
        async function deleteContentItem(sectionKey, index) {
            const confirmed = await showCustomConfirm('确定要删除这个内容项吗?');
            if (confirmed) {
                const contentArray = getSectionContentArray(sectionKey);
                contentArray.splice(index, 1);
                renderAll();
            }
        }

        // 删除嵌套内容项
        async function deleteNestedContentItem(sectionKey, itemIndex, nestedIndex) {
            const confirmed = await showCustomConfirm('确定要删除这个子内容项吗?');
            if (confirmed) {
                const contentArray = getSectionContentArray(sectionKey);
                contentArray[itemIndex].content.splice(nestedIndex, 1);
                renderAll();
            }
        }

        // 删除章节
        async function deleteSection(sectionKey) {
            const confirmed = await showCustomConfirm('确定要删除整个章节吗?此操作不可撤销。');
            if (confirmed) {
                delete prdData.productRequirementDocument.sections[sectionKey];
                renderAll();
            }
        }

        // 添加新章节
        function addSection() {
            const sectionKey = 'newSection' + Date.now();
            const newSection = {
                title: '新章节',
                content: []
            };

            prdData.productRequirementDocument.sections[sectionKey] = newSection;
            renderAll();
        }

        // 保存配置功能
        function saveConfig() {
            try {
                const dataStr = JSON.stringify(prdData, null, 2);
                console.log('💾 [prdDesign.html] 准备保存配置数据到VSCode');

                // 通过VSCode webview API发送数据
                if (vsCodeApi) {
                    vsCodeApi.postMessage({
                        command: 'saveConfig',
                        data: dataStr,
                        fromWhere: fromWhere
                    });
                    console.log('✅ [prdDesign.html] 配置数据已发送到VSCode,fromWhere:', fromWhere);
                } else {
                    // 如果不在VSCode环境中,则下载文件作为备用方案
                    console.log('⚠️ [prdDesign.html] 不在VSCode环境中,使用下载备用方案');
                    const dataBlob = new Blob([dataStr], { type: 'application/json' });
                    const url = URL.createObjectURL(dataBlob);
                    const link = document.createElement('a');
                    link.href = url;
                    link.download = 'prd-design-config.json';
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    URL.revokeObjectURL(url);
                }

                // 显示保存成功提示
                const saveButton = document.querySelector('.save-button');
                const originalText = saveButton.innerHTML;
                saveButton.innerHTML = '<i class="fas fa-check"></i><span>已保存</span>';
                saveButton.style.background = '#34C759';

                setTimeout(() => {
                    saveButton.innerHTML = originalText;
                    saveButton.style.background = '';
                }, 2000);
            } catch (error) {
                console.error('保存配置失败:', error);
                // 保存失败时显示在按钮上
                const saveButton = document.querySelector('.save-button');
                const originalText = saveButton.innerHTML;
                saveButton.innerHTML = '<i class="fas fa-times"></i><span>保存失败</span>';
                saveButton.style.background = '#FF3B30';

                setTimeout(() => {
                    saveButton.innerHTML = originalText;
                    saveButton.style.background = '';
                }, 2000);
            }
        }

        // 主题切换功能
        function toggleTheme() {
            const body = document.body;
            const themeText = document.getElementById('theme-text');
            const themeIcon = document.querySelector('.theme-toggle i');

            if (body.getAttribute('data-theme') === 'light') {
                // 切换到暗色主题
                body.removeAttribute('data-theme');
                themeText.textContent = '亮色模式';
                themeIcon.className = 'fas fa-sun';
                localStorage.setItem('theme', 'dark');
            } else {
                // 切换到亮色主题
                body.setAttribute('data-theme', 'light');
                themeText.textContent = '暗色模式';
                themeIcon.className = 'fas fa-moon';
                localStorage.setItem('theme', 'light');
            }
        }

        // 初始化主题
        function initTheme() {
            const savedTheme = localStorage.getItem('theme');
            const themeText = document.getElementById('theme-text');
            const themeIcon = document.querySelector('.theme-toggle i');

            if (savedTheme === 'light') {
                document.body.setAttribute('data-theme', 'light');
                themeText.textContent = '暗色模式';
                themeIcon.className = 'fas fa-moon';
            } else {
                themeText.textContent = '亮色模式';
                themeIcon.className = 'fas fa-sun';
            }
        }

        // 自定义确认删除弹框
        let customConfirmCallback = null;

        function showCustomConfirm(message) {
            return new Promise((resolve) => {
                customConfirmCallback = resolve;
                document.getElementById('customConfirmMessage').textContent = message;
                const overlay = document.getElementById('customConfirmOverlay');
                overlay.classList.add('show');
            });
        }

        function hideCustomConfirm(result) {
            const overlay = document.getElementById('customConfirmOverlay');
            overlay.classList.remove('show');
            if (customConfirmCallback) {
                customConfirmCallback(result);
                customConfirmCallback = null;
            }
        }

        // 侧滑面板功能
        function toggleSidebar() {
            const sidebar = document.getElementById('sidebar');
            const container = document.querySelector('.container');
            const toggleIcon = document.querySelector('.sidebar-toggle i');

            sidebar.classList.toggle('collapsed');
            container.classList.toggle('sidebar-collapsed');

            if (sidebar.classList.contains('collapsed')) {
                toggleIcon.className = 'fas fa-chevron-right';
            } else {
                toggleIcon.className = 'fas fa-chevron-left';
            }
        }

        // 生成文档目录
        function generateTOC() {
            const tocContainer = document.getElementById('toc-container');
            if (!tocContainer) {
                console.error('toc-container element not found');
                return;
            }

            // 检查数据是否已加载
            const dataRoot = getDataRoot();
            if (!dataRoot || !dataRoot.sections) {
                console.warn('数据尚未加载,跳过目录生成');
                tocContainer.innerHTML = '';
                return;
            }

            tocContainer.innerHTML = '';

            let headingIndex = 0;

            // 根据JSON数据结构生成目录
            const sections = dataRoot.sections;
            Object.keys(sections).forEach(sectionKey => {
                const section = sections[sectionKey];

                // 1级标题:章节标题
                const sectionTocItem = createTocItem(section.title, 1, sectionKey, headingIndex++);
                tocContainer.appendChild(sectionTocItem);

                // 处理章节内容(支持pageList、moduleList和content)
                const contentArray = section.pageList || section.moduleList || section.content;
                if (Array.isArray(contentArray)) {
                    contentArray.forEach((item, itemIndex) => {
                        // 2级标题:内容项标题
                        const itemTocItem = createTocItem(item.title, 2, `${sectionKey}-${itemIndex}`, headingIndex++);
                        tocContainer.appendChild(itemTocItem);

                        // 处理嵌套内容
                        if (Array.isArray(item.content)) {
                            item.content.forEach((nestedItem, nestedIndex) => {
                                // 3级标题:嵌套内容项标题
                                const nestedTocItem = createTocItem(nestedItem.title, 3, `${sectionKey}-${itemIndex}-${nestedIndex}`, headingIndex++);
                                tocContainer.appendChild(nestedTocItem);
                            });
                        }
                    });
                }
            });
        }

        // 创建目录项
        function createTocItem(title, level, targetId, index) {
            const tocItem = document.createElement('div');
            tocItem.className = `toc-item level-${level}`;
            tocItem.dataset.targetId = targetId;

            // 创建文本部分
            const textSpan = document.createElement('span');
            textSpan.className = 'toc-item-text';
            textSpan.textContent = title;

            // 创建按钮容器
            const buttonsDiv = document.createElement('div');
            buttonsDiv.className = 'toc-item-buttons';

            // 根据层级决定显示哪些按钮
            const parts = targetId.split('-');
            const sectionKey = parts[0];

            // 1级标题(章节):只显示添加按钮
            if (level === 1) {
                const addBtn = document.createElement('button');
                addBtn.className = 'toc-btn toc-add-btn';
                addBtn.innerHTML = '<i class="fas fa-plus"></i>';
                addBtn.title = '添加内容项';
                addBtn.onclick = (e) => {
                    e.stopPropagation();
                    addContentItem(sectionKey);
                };
                buttonsDiv.appendChild(addBtn);
            }
            // 2级标题(内容项):显示添加和删除按钮
            else if (level === 2) {
                const addBtn = document.createElement('button');
                addBtn.className = 'toc-btn toc-add-btn';
                addBtn.innerHTML = '<i class="fas fa-plus"></i>';
                addBtn.title = '添加子内容';
                addBtn.onclick = (e) => {
                    e.stopPropagation();
                    const itemIndex = parseInt(parts[1]);
                    addNestedContentItem(sectionKey, itemIndex);
                };

                const deleteBtn = document.createElement('button');
                deleteBtn.className = 'toc-btn toc-delete-btn';
                deleteBtn.innerHTML = '<i class="fas fa-times"></i>';
                deleteBtn.title = '删除内容项';
                deleteBtn.onclick = (e) => {
                    e.stopPropagation();
                    const itemIndex = parseInt(parts[1]);
                    deleteContentItem(sectionKey, itemIndex);
                };

                buttonsDiv.appendChild(addBtn);
                buttonsDiv.appendChild(deleteBtn);
            }
            // 3级标题(嵌套内容项):只显示删除按钮
            else if (level === 3) {
                const deleteBtn = document.createElement('button');
                deleteBtn.className = 'toc-btn toc-delete-btn';
                deleteBtn.innerHTML = '<i class="fas fa-times"></i>';
                deleteBtn.title = '删除子内容项';
                deleteBtn.onclick = (e) => {
                    e.stopPropagation();
                    const itemIndex = parseInt(parts[1]);
                    const nestedIndex = parseInt(parts[2]);
                    deleteNestedContentItem(sectionKey, itemIndex, nestedIndex);
                };
                buttonsDiv.appendChild(deleteBtn);
            }

            tocItem.appendChild(textSpan);
            tocItem.appendChild(buttonsDiv);

            // 点击文本部分的事件
            textSpan.addEventListener('click', () => {
                const targetElement = findElementByDataPath(targetId);
                if (targetElement) {
                    scrollToHeading(targetElement);
                    setActiveTocItem(tocItem);
                }
            });

            return tocItem;
        }

        // 根据数据路径查找对应的DOM元素
        function findElementByDataPath(targetId) {
            const parts = targetId.split('-');
            const sectionKey = parts[0];

            if (parts.length === 1) {
                // 章节标题
                return document.querySelector(`[data-section-key="${sectionKey}"] .section-title`);
            } else if (parts.length === 2) {
                // 内容项标题
                const itemIndex = parts[1];
                return document.querySelector(`[data-section-key="${sectionKey}"] [data-index="${itemIndex}"] .content-item-title`);
            } else if (parts.length === 3) {
                // 嵌套内容项标题
                const itemIndex = parts[1];
                const nestedIndex = parts[2];
                return document.querySelector(`[data-section-key="${sectionKey}"] [data-index="${itemIndex}"] [data-nested-index="${nestedIndex}"] .content-item-title`);
            }

            return null;
        }

        // 滚动到指定标题
        function scrollToHeading(element) {
            const offsetTop = element.getBoundingClientRect().top + window.scrollY - 80;
            window.scrollTo({
                top: offsetTop,
                behavior: 'smooth'
            });
        }

        // 设置活动的目录项
        function setActiveTocItem(activeItem) {
            document.querySelectorAll('.toc-item').forEach(item => {
                item.classList.remove('active');
            });
            activeItem.classList.add('active');
        }

        // 监听滚动事件,高亮当前章节
        function initScrollSpy() {
            let ticking = false;

            function updateActiveTocItem() {
                const headings = document.querySelectorAll('[id^="heading-"]');
                const scrollTop = window.scrollY + 100;

                let activeHeading = null;

                headings.forEach(heading => {
                    const headingTop = heading.getBoundingClientRect().top + window.scrollY;
                    if (headingTop <= scrollTop) {
                        activeHeading = heading;
                    }
                });

                if (activeHeading) {
                    const targetId = activeHeading.id;
                    const activeTocItem = document.querySelector(`[data-target-id="${targetId}"]`);
                    if (activeTocItem) {
                        setActiveTocItem(activeTocItem);
                    }
                }

                ticking = false;
            }

            window.addEventListener('scroll', () => {
                if (!ticking) {
                    requestAnimationFrame(updateActiveTocItem);
                    ticking = true;
                }
            });
        }

        // 从字符串导入数据并初始化PRD编辑器
        function importDataFromString(jsonString) {
            try {
                const importedData = JSON.parse(jsonString);

                // 验证数据结构
                if (validateDataStructure(importedData)) {
                    prdData = importedData;
                    renderAll();
                    console.log('PRD数据导入成功');
                    return true;
                } else {
                    console.error('导入失败:JSON格式不正确');
                    return false;
                }
            } catch (error) {
                console.error('导入失败:', error.message);
                return false;
            }
        }

        // 验证数据结构
        function validateDataStructure(data) {
            // 验证产品需求文档结构
            if (data && data.productRequirementDocument &&
                data.productRequirementDocument.title &&
                data.productRequirementDocument.sections) {
                return true;
            }

            // 验证模块业务逻辑设计结构
            if (data && data.moduleBusinessLogicDesign &&
                data.moduleBusinessLogicDesign.title &&
                data.moduleBusinessLogicDesign.sections) {
                return true;
            }

            return false;
        }



        // 自动调整textarea高度
        function autoResizeTextarea(textarea) {
            textarea.style.height = 'auto';
            textarea.style.height = textarea.scrollHeight + 'px';
        }

        // 初始化所有textarea的自动高度调整
        function initTextareaAutoResize() {
            const textareas = document.querySelectorAll('.content-textarea');
            textareas.forEach(textarea => {
                // 初始化高度
                autoResizeTextarea(textarea);

                // 绑定输入事件
                textarea.addEventListener('input', function () {
                    autoResizeTextarea(this);
                });

                // 绑定粘贴事件
                textarea.addEventListener('paste', function () {
                    setTimeout(() => {
                        autoResizeTextarea(this);
                    }, 0);
                });
            });
        }

        // 重新调整所有textarea的高度
        function resizeAllTextareas() {
            const textareas = document.querySelectorAll('.content-textarea');
            textareas.forEach(textarea => {
                autoResizeTextarea(textarea);
            });
        }

        // 监听窗口大小变化和侧滑面板状态变化
        function initResizeListeners() {
            let resizeTimeout;

            // 监听窗口大小变化
            window.addEventListener('resize', function () {
                clearTimeout(resizeTimeout);
                resizeTimeout = setTimeout(() => {
                    resizeAllTextareas();
                }, 100);
            });

            // 监听侧滑面板状态变化
            const container = document.querySelector('.container');
            if (container) {
                const observer = new MutationObserver(function (mutations) {
                    mutations.forEach(function (mutation) {
                        if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                            setTimeout(() => {
                                resizeAllTextareas();
                            }, 300); // 等待CSS过渡完成
                        }
                    });
                });

                observer.observe(container, {
                    attributes: true,
                    attributeFilter: ['class']
                });
            }
        }

        // 编辑Mermaid图表内容(对象格式)
        function editMermaidContent(sectionKey, currentMermaid) {
            const newMermaid = prompt('编辑Mermaid图表代码:', currentMermaid);
            if (newMermaid !== null && newMermaid !== currentMermaid) {
                const section = prdData.productRequirementDocument.sections[sectionKey];
                if (section.content && typeof section.content === 'object' && section.content.mermaid) {
                    section.content.mermaid = newMermaid;
                }
                renderAll();
            }
        }

        // 编辑Mermaid图表内容(字符串格式)
        function editMermaidStringContent(sectionKey, currentMermaid) {
            const newMermaid = prompt('编辑Mermaid图表代码:', currentMermaid);
            if (newMermaid !== null && newMermaid !== currentMermaid) {
                const section = prdData.productRequirementDocument.sections[sectionKey];
                if (typeof section.content === 'string') {
                    section.content = newMermaid;
                }
                renderAll();
            }
        }

        // 初始化Mermaid
        function initMermaid() {
            if (window.mermaid) {
                window.mermaid.initialize({
                    startOnLoad: true,
                    theme: 'base',
                    securityLevel: 'loose',
                    themeVariables: {
                        // 流程图节点样式
                        primaryColor: '#333333',
                        primaryTextColor: '#d3d3d3',
                        primaryBorderColor: '#676767',
                        lineColor: '#676767',

                        // 矩形节点
                        nodeTextColor: '#d3d3d3',
                        mainBkg: '#333333',
                        nodeBorder: '#676767',

                        // 菱形决策节点
                        altBackground: '#333333',

                        // 圆形节点
                        tertiaryColor: '#333333',

                        // 背景
                        background: 'white',

                        // 边和箭头
                        edgeLabelBackground: 'transparent',
                        clusterBkg: 'white'
                    }
                });
            }
        }

        // 初始化Mermaid缩放功能
        function initMermaidZoom() {
            document.addEventListener('wheel', function (e) {
                // 检查是否在mermaid元素上
                const mermaidElement = e.target.closest('.mermaid');
                if (!mermaidElement) return;

                // 检查是否按下Ctrl键
                if (e.ctrlKey || e.metaKey) {
                    e.preventDefault();

                    // 获取当前transform值
                    const currentTransform = mermaidElement.style.transform || '';
                    const scaleMatch = currentTransform.match(/scale\(([^)]+)\)/);
                    const translateMatch = currentTransform.match(/translate\(([^,)]+),\s*([^)]+)\)/);

                    const currentScale = scaleMatch ? parseFloat(scaleMatch[1]) : 1;
                    const currentTranslateX = translateMatch ? parseFloat(translateMatch[1]) : 0;
                    const currentTranslateY = translateMatch ? parseFloat(translateMatch[2]) : 0;

                    // 计算新的缩放比例(3%变化)
                    const zoomFactor = e.deltaY > 0 ? 0.97 : 1.03;
                    const newScale = Math.max(0.3, Math.min(3, currentScale * zoomFactor));

                    // 应用缩放(保持当前的translate值)
                    mermaidElement.style.transform = `translate(${currentTranslateX}px, ${currentTranslateY}px) scale(${newScale})`;

                    // 检查是否需要显示重置按钮
                    checkResetButtonVisibility();
                }
            }, { passive: false });

            // 触摸板双指缩放支持
            document.addEventListener('gesturestart', function (e) {
                const mermaidElement = e.target.closest('.mermaid');
                if (mermaidElement) {
                    e.preventDefault();
                    mermaidElement.dataset.initialScale = mermaidElement.style.transform || 'scale(1)';
                }
            }, { passive: false });

            document.addEventListener('gesturechange', function (e) {
                const mermaidElement = e.target.closest('.mermaid');
                if (mermaidElement) {
                    e.preventDefault();

                    const initialScale = parseFloat(mermaidElement.dataset.initialScale?.match(/scale\(([^)]+)\)/)?.[1] || 1);
                    const newScale = Math.max(0.3, Math.min(3, initialScale * e.scale));

                    mermaidElement.style.transform = `scale(${newScale})`;
                }
            }, { passive: false });

            document.addEventListener('gestureend', function (e) {
                const mermaidElement = e.target.closest('.mermaid');
                if (mermaidElement) {
                    delete mermaidElement.dataset.initialScale;
                }
            });
        }

        // 初始化Mermaid拖动功能
        function initMermaidDrag() {
            let isDragging = false;
            let dragStartX = 0;
            let dragStartY = 0;
            let initialTransformX = 0;
            let initialTransformY = 0;
            let currentMermaidElement = null;

            document.addEventListener('mousedown', function (e) {
                const mermaidElement = e.target.closest('.mermaid');
                if (!mermaidElement) return;

                // 只有在不按Ctrl键时才启用拖动(避免与缩放冲突)
                if (e.ctrlKey || e.metaKey) return;

                isDragging = true;
                currentMermaidElement = mermaidElement;
                dragStartX = e.clientX;
                dragStartY = e.clientY;

                // 获取当前的transform值
                const currentTransform = mermaidElement.style.transform || '';
                const scaleMatch = currentTransform.match(/scale\(([^)]+)\)/);
                const translateMatch = currentTransform.match(/translate\(([^,)]+),\s*([^)]+)\)/);

                const currentScale = scaleMatch ? parseFloat(scaleMatch[1]) : 1;
                initialTransformX = translateMatch ? parseFloat(translateMatch[1]) : 0;
                initialTransformY = translateMatch ? parseFloat(translateMatch[2]) : 0;

                mermaidElement.style.cursor = 'grabbing';
                e.preventDefault();
            });

            document.addEventListener('mousemove', function (e) {
                if (!isDragging || !currentMermaidElement) return;

                const deltaX = e.clientX - dragStartX;
                const deltaY = e.clientY - dragStartY;

                // 提升拖动灵敏度(1.5倍响应)
                const newTransformX = initialTransformX + deltaX * 1.5;
                const newTransformY = initialTransformY + deltaY * 1.5;

                // 获取当前缩放比例
                const currentTransform = currentMermaidElement.style.transform || '';
                const scaleMatch = currentTransform.match(/scale\(([^)]+)\)/);
                const currentScale = scaleMatch ? parseFloat(scaleMatch[1]) : 1;

                // 应用新的transform(保持缩放,更新位移)
                currentMermaidElement.style.transform = `translate(${newTransformX}px, ${newTransformY}px) scale(${currentScale})`;

                // 检查是否需要显示重置按钮
                checkResetButtonVisibility();

                e.preventDefault();
            });

            document.addEventListener('mouseup', function (e) {
                if (isDragging && currentMermaidElement) {
                    currentMermaidElement.style.cursor = 'grab';
                    isDragging = false;
                    currentMermaidElement = null;
                }
            });

            // 处理鼠标离开窗口的情况
            document.addEventListener('mouseleave', function (e) {
                if (isDragging && currentMermaidElement) {
                    currentMermaidElement.style.cursor = 'grab';
                    isDragging = false;
                    currentMermaidElement = null;
                }
            });
        }

        // 更新Mermaid代码并重新渲染图表
        function updateMermaidCode(sectionKey, newCode, mermaidDiv) {
            // 更新数据
            const section = prdData.productRequirementDocument.sections[sectionKey];
            if (typeof section.content === 'string') {
                section.content = newCode;
            }

            // 更新图表显示
            mermaidDiv.textContent = newCode;

            // 重新渲染mermaid图表
            setTimeout(() => {
                if (window.mermaid) {
                    // 清除之前的渲染
                    mermaidDiv.removeAttribute('data-processed');
                    mermaidDiv.innerHTML = '';
                    mermaidDiv.textContent = newCode;

                    // 重新初始化
                    window.mermaid.init(undefined, mermaidDiv);
                }
            }, 100);
        }

        // Mermaid Tab切换功能
        function switchMermaidTab(container, tabType) {
            // 更新tab按钮状态
            const tabs = container.querySelectorAll('.mermaid-tab');
            tabs.forEach(tab => {
                tab.classList.remove('active');
                if ((tabType === 'chart' && tab.textContent === '流程图') ||
                    (tabType === 'code' && tab.textContent === 'Mermaid代码')) {
                    tab.classList.add('active');
                }
            });

            // 更新面板显示状态
            const panels = container.querySelectorAll('.mermaid-tab-panel');
            panels.forEach(panel => {
                panel.classList.remove('active');
                if (panel.getAttribute('data-panel') === tabType) {
                    panel.classList.add('active');
                }
            });
        }

        // 重置流程图功能
        function resetMermaidTransform() {
            const mermaidElements = document.querySelectorAll('.mermaid');
            mermaidElements.forEach(element => {
                element.style.transform = '';
            });
            hideResetButton();
        }

        // 显示重置按钮
        function showResetButton() {
            const resetBtn = document.getElementById('resetMermaidBtn');
            if (resetBtn) {
                resetBtn.classList.add('show');
            }
        }

        // 隐藏重置按钮
        function hideResetButton() {
            const resetBtn = document.getElementById('resetMermaidBtn');
            if (resetBtn) {
                resetBtn.classList.remove('show');
            }
        }

        // 检查是否需要显示重置按钮
        function checkResetButtonVisibility() {
            const mermaidElements = document.querySelectorAll('.mermaid');
            let shouldShow = false;

            mermaidElements.forEach(element => {
                const transform = element.style.transform;
                if (transform && transform !== '' && transform !== 'scale(1)' && transform !== 'translate(0px, 0px) scale(1)') {
                    shouldShow = true;
                }
            });

            if (shouldShow) {
                showResetButton();
            } else {
                hideResetButton();
            }
        }

        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function () {
            console.log('PRD编辑器页面加载完成');
            initTheme();
            initMermaid();
            initMermaidZoom();
            initMermaidDrag();
            renderAll();
            // 延迟初始化textarea自动调整,确保DOM已完全渲染
            setTimeout(() => {
                initTextareaAutoResize();
                generateTOC();
                initScrollSpy();
                initResizeListeners();
            }, 200);
        });

        // 在renderAll函数执行后重新初始化textarea自动调整和目录
        const originalRenderAll = renderAll;
        renderAll = function () {
            originalRenderAll();
            setTimeout(() => {
                initTextareaAutoResize();
                generateTOC();
                // 重新初始化所有mermaid图表
                if (window.mermaid) {
                    const mermaidElements = document.querySelectorAll('.mermaid');
                    mermaidElements.forEach(element => {
                        if (!element.getAttribute('data-processed')) {
                            window.mermaid.init(undefined, element);
                        }
                    });
                }
            }, 200);
        };

        // 全局VSCode API实例
        let vsCodeApi = null;

        // VSCode webview消息监听器
        if (typeof acquireVsCodeApi !== 'undefined') {
            vsCodeApi = acquireVsCodeApi();
            window.addEventListener('message', event => {
                const message = event.data;
                console.log('📨 [prdDesign.html] 收到VSCode消息:', message);

                switch (message.command) {
                    case 'importPrdJsonData':
                        try {
                            console.log('📥 [prdDesign.html] 开始导入配置数据');
                            console.log('📥 [prdDesign.html] fromWhere参数:', message.fromWhere);

                            // 保存fromWhere参数
                            if (message.fromWhere) {
                                fromWhere = message.fromWhere;
                                console.log('📥 [prdDesign.html] 已设置fromWhere为:', fromWhere);
                            }

                            if (typeof importDataFromString === 'function' && message.data) {
                                importDataFromString(message.data);
                                console.log('✅ [prdDesign.html] 配置数据导入成功');
                            } else {
                                console.warn('⚠️ [prdDesign.html] importDataFromString方法不存在或数据为空');
                            }
                        } catch (error) {
                            console.error('❌ [prdDesign.html] 导入配置数据失败:', error);
                        }
                        break;
                }
            });
        }
    </script>
</body>

</html>