<template>
  <div style="height:100%;width:100%;">
  <el-container style="height:100%;width:100%;">
    <el-aside 
      :width="leftWidth + 'px'" 
      style="position: relative; overflow: hidden;"
    >
    <div class="drag-handle" @mousedown="startDrag"></div>
        <div  class="leftDiv" v-if='isLoadXml' style="width:100%;"  > 
      <div id='navMain'>
        <!-- 操作栏 -->
       <div class="operation-buttons">
          <!-- 节点搜索框 -->
          <div style="margin:5px auto;width:100%;">
              <el-input
              placeholder="输入节点名称搜索"
              v-model="searchText"
              class="search-input"
              clearable
              @clear="handleSearchClear"
              @keyup.enter="handleSearch">
              <el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
            </el-input>
          </div>
          <!-- 操作栏按钮 -->
          <div style="display:flex;margin-bottom: 5px;">
            <div style="width:25%;height:30px;" class="iconImgDiv" @click="showAddDialog('create')"  title='新建' v-if='isLoadXml'><img class='iconImg' title='新建' src="../assets/img/addIcon.png"   alt=""></div>
            <div style="width:25%;height:30px;" class="iconImgDiv" @click="showAddDialog('edit')" title='编辑' v-if='currentNode'><img class='iconImg' title='编辑' src="../assets/img/editIcon.png"  alt=""></div>
            <div style="width:25%;height:30px;" class="iconImgDiv" @click="saveNowDmcClick" title='保存' v-if='currentNode' ><img class='iconImg' title='保存' src="../assets/img/saveIcon.png"  alt=""></div>
            <div style="width:25%;height:30px;" class="iconImgDiv" @click="deleteDialog" title='删除' v-if='currentNode'><img class='iconImg' title='删除' src="../assets/img/delIcon.png"   alt=""></div>
          </div>
        </div>
        <!-- 'maxHeight':leftHeight+'px', -->
        <div class="tree-container" :style="{'minHeight':'100px'}">
          <div class="navTitle"  >
            <p @click='clearNodeState' :title="getBookName">{{getBookName}}</p>
            <img @click='editBookName' class='iconImgMulu' title='编辑书名' src="../assets/img/bianji.png"   alt="">
          </div>

          <el-scrollbar style="">
            <!-- 滚动内容区域 -->
            <div class="scroll-content">
                 <!-- 目录结构树 -->
            <el-tree
              class="elTree elTreeMain gd"
              ref="tree"
              :data="treeData"
              node-key="id"
              icon-class="el-icon-arrow-right"
              :default-expand-all="true"
              :props="defaultProps"
              :filter-node-method="filterNode"
              @node-click="handleNodeClick"
              @node-drag-end="handleDragEnd"
              @node-contextmenu="handleNodeContextMenu"
              :expand-on-click-node="false"
              :highlight-current="true"
              draggable
            >
            <!-- 节点自定义渲染插槽 -->
            <span slot-scope="{ data }">
              <!-- （1）原有节点图标+名称渲染逻辑 -->
              <template v-if="data.children && data.children.length > 0">
                <!-- 父节点（有子节点） -->
                <div>
                  <i class="el-icon-folder" :style="'font-size: 14px; padding: 0 5px 0 5px'"/>
                  <i class="el-icon-warning changeState" @click.stop="handleModify(data)"   v-if="showModifyBtn && hasMinorVersion01(data)" :style="'font-size: 14px; padding: 0 5px 0 5px'"/>
                  <span :title="data.id + '-' + data.name" :class="{ 'highlight': isHighlight(data) }">
                    {{ data.name }}
                  </span>
                  <!-- （关键）条件显示【修改】：检查状态开启 + 当前节点/子节点有minorVersion:01 -->
                  <!-- <span 
                    class="modify-btn"
                    v-if="showModifyBtn && hasMinorVersion01(data)"
                    @click.stop="handleModify(data)" 
                  >
                    【修改】
                  </span> -->
                </div>
              </template>
              <template v-else>
                <!-- 叶子节点（无子节点） -->
                <div style="margin-left: 0px;">
                  <i class="leaf-node-line"></i>
                  <i class="el-icon-document" :style="'padding: 0 5px 0 5px'"></i>
                    <!-- <svg viewBox="64 64 896 896" data-icon="deployment-unit" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class="">
                      <path d="M888.3 693.2c-42.5-24.6-94.3-18-129.2 12.8l-53-30.7V523.6c0-15.7-8.4-30.3-22-38.1l-136-78.3v-67.1c44.2-15 76-56.8 76-106.1 0-61.9-50.1-112-112-112s-112 50.1-112 112c0 49.3 31.8 91.1 76 106.1v67.1l-136 78.3c-13.6 7.8-22 22.4-22 38.1v151.6l-53 30.7c-34.9-30.8-86.8-37.4-129.2-12.8-53.5 31-71.7 99.4-41 152.9 30.8 53.5 98.9 71.9 152.2 41 42.5-24.6 62.7-73 53.6-118.8l48.7-28.3 140.6 81c6.8 3.9 14.4 5.9 22 5.9s15.2-2 22-5.9L674.5 740l48.7 28.3c-9.1 45.7 11.2 94.2 53.6 118.8 53.3 30.9 121.5 12.6 152.2-41 30.8-53.6 12.6-122-40.7-152.9zm-673 138.4a47.6 47.6 0 0 1-65.2-17.6c-13.2-22.9-5.4-52.3 17.5-65.5a47.6 47.6 0 0 1 65.2 17.6c13.2 22.9 5.4 52.3-17.5 65.5zM522 463.8zM464 234a48.01 48.01 0 0 1 96 0 48.01 48.01 0 0 1-96 0zm170 446.2l-122 70.3-122-70.3V539.8l122-70.3 122 70.3v140.4zm239.9 133.9c-13.2 22.9-42.4 30.8-65.2 17.6-22.8-13.2-30.7-42.6-17.5-65.5s42.4-30.8 65.2-17.6c22.9 13.2 30.7 42.5 17.5 65.5z"></path>
                    </svg>   -->
                  <!-- <i :style="'font-size: 13px; padding: 0 5px 0 5px'">
                  
                  </i> -->
                  <i class="el-icon-warning changeState" @click.stop="handleModify(data)"   v-if="showModifyBtn && hasMinorVersion01(data)" :style="'font-size: 14px; padding: 0 5px 0 5px'"/>
                  <span :title="data.id + '-' + data.name" :class="{ 'highlight': isHighlight(data) }">
                    {{ data.name }}
                  </span> 
                </div>
              </template>
            </span>
          </el-tree> 
            </div>
          </el-scrollbar>
         
        </div>
      </div>
      <!-- <div id='nav'>
        <nav-temp />
      </div> -->
    </div>
    </el-aside>
    <el-main style="">
        <div class="rightDiv">
        <div class="bName" :title="getBookName">{{getBookName}}</div>    
        <!-- 编辑框 -->
        <!-- :style="{height:editorHeight+'px'}" -->
         <!-- <el-button 
          type="primary" 
          icon="el-icon-s-data" 
          @click="countDomNodes"
          style="margin: 5px;"
        >
          统计DOM节点数量
        </el-button> -->
        <!-- :class="{ editor2Opacity: dialogVisibleNav||dialogVisibleNavDel|| dialogVisible||dialogVisibleImg||dialogVisibleRight||dialogVisibleTips||dialogVisibleBland||dialogVisibleHistory||dialogVisibleTips2||editBookNameDialog }" -->
        <div id="editor" v-show='currentNode' :class="{ editor2Opacity: dialogVisibleNav||dialogVisibleNavDel|| dialogVisible||dialogVisibleImg||dialogVisibleRight||dialogVisibleTips||dialogVisibleBland||dialogVisibleHistory||dialogVisibleTips2||editBookNameDialog }"  ref="editor" ></div>
         <!-- 提示信息 -->
        <!-- <div class="paAutoStyle" v-show="!currentNode && isLoadXml">请打开所要编辑的的章节目录</div>
        <div class="paAutoStyle" v-show="!isLoadXml">请加载所要编辑的文档目录</div> -->
    </div>
    </el-main>
  </el-container>
  <div class="paAuto paAutoStyle" v-show="!isLoadMsg">请加载有需编辑的项目</div>
 

  <!-- 统计结果弹窗 -->
  <el-dialog
    title="DOM节点统计结果"
    :visible.sync="countDialogVisible"
    width="40%"
  >
    <div class="statistics-result">
      <p>目标容器: {{ countTarget }}</p>
      <p>总DOM节点数量: <span class="count-number">{{ domCount }}</span></p>
      <p>元素节点数量: <span class="count-number">{{ elementCount }}</span></p>
      <p>文本节点数量: <span class="count-number">{{ textCount }}</span></p>
      <p>注释节点数量: <span class="count-number">{{ commentCount }}</span></p>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="countDialogVisible = false">关闭</el-button>
    </span>
  </el-dialog>

    <!-- 历史弹窗 -->
    <el-dialog
      title="历史版本"
      :visible.sync="dialogVisibleHistory"
      width='80%'
      class="custom-dialog"
      :before-close="handleClose">
      <div class="attribute-selection" v-if='historyData'>
          <div class='zyBox' style="text-align: left;" v-for="(item,index) in historyData" :key="index">
            <p>版本名称：{{item.Name}}</p>
            <p>修改时间：{{timeChange(item.CreationTime)}}</p>
            <p>文件路径：{{item.Path}}</p>
            <el-button @click='lookHistoryFile(item.Path)'>查看历史版本</el-button>
          </div>
      </div>
      <div class="attribute-selection" v-if='historyData.length == 0'>
        暂无历史版本
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisibleHistory = false">关闭</el-button>
        <!-- <el-button type="primary"  @click="catalogueAnalysis(treeData)">选择绑定资源</el-button> -->
      </span>
    </el-dialog>


    <!-- 绑定资源弹窗 -->
    <el-dialog
      title="绑定资源"
      class="custom-dialog"
      :visible.sync="dialogVisibleBland"
      width="50%"
      :before-close="handleClose">
      <div class="attribute-selection" v-if="currentNode&&currentNode.attributes.length > 0">
        <p>已绑资源：</p>
         <!-- 属性展示区域 -->
         <div v-if='currentNode' class='bindMain'>
            <div class="zyBox"  v-for="(item,index) in currentNode.attributes" :key="index">
                <p>{{item}}</p>
                <el-button type="danger" size="mini" @click="deleteAttr(item,index)" :disabled="!currentNode">删除</el-button>
            </div>
         </div>
        
      </div>
      <div  v-else>暂未绑定资源</div>
      <span slot="footer" class="dialog-footer">
        <el-button @click='saveAttributes'>选择绑定资源</el-button>
        <el-button @click="dialogVisibleBland = false">关闭</el-button>
        <!-- <el-button type="primary"  @click="catalogueAnalysis(treeData)">选择绑定资源</el-button> -->
      </span>
    </el-dialog> 


    
 

    <!-- 新建，编辑目录弹窗 -->
   <el-dialog
      :title="navIsAdd=='create'?'新建章节':'编辑章节'"
      :visible.sync="dialogVisibleNav"
      width="80%"
      class="custom-dialog"
      :before-close="handleClose"
      > 
       <el-form label-position="left" label-width="120px" :model="form" :rules="rules" ref="form">
  <!-- 按钮区域 -->
    <div style="margin-bottom: 15px;">
      <el-button type="info" icon="el-icon-folder-opened" v-if='navIsAdd == "create"' @click="loadFileBtn">加载文件</el-button>
      <el-button type="info" icon="el-icon-data-analysis" v-if='showView' @click="viewLoadDMFile">预览文件</el-button>
  </div>
  
  <!-- 两列布局容器 -->
  <el-row :gutter="20">
    <!-- 第一列 -->
    <el-col :span="24">
      <div class="colStyle colStyle1">
        <img title='章节名称' src="../assets/img/wenjian.png" >
        <span>章节名称</span>
      </div>
      <el-input v-model="form.name" autocomplete="off"></el-input>
    </el-col>
    
    <!-- 第二列 -->
    <el-col :span="12">
        <div class="colStyle">
          <img title='责任合作单位' src="../assets/img/danwei.png" >
          <span>责任合作单位</span>
        </div>
        <el-input v-model="form.contributor" autocomplete="off"></el-input>
    </el-col>
    
    <!-- 第一列 -->
    <el-col :span="12">
       <div class="colStyle">
          <img title='创作单位' src="../assets/img/hezuodanwei.png" >
          <span>创作单位</span>
        </div>
        <el-input v-model="form.creator" autocomplete="off"></el-input>
    </el-col>
    
    <!-- 第二列 -->
    <el-col :span="12">
        <div class="colStyle">
          <img title='适用性信息' src="../assets/img/xinxi.png" >
          <span>适用性信息</span>
        </div>
        <el-input v-model="form.applicabilityInformation" autocomplete="off"></el-input>
     </el-col>
    
    <!-- 第一列 -->
    <el-col :span="12">
      <div class="colStyle">
          <img title='质量验证' src="../assets/img/xinxi.png" >
          <span>质量验证</span>
        </div>
        <el-input v-model="form.qualityVerification" autocomplete="off"></el-input>
    </el-col>
    
    <!-- 第二列 -->
    <el-col :span="12">
       <div class="colStyle">
          <img title='权限' src="../assets/img/quanxian.png" >
          <span>权限</span>
        </div>
        <!-- <el-input v-model="form.permission" autocomplete="off"></el-input> -->
         <el-select v-model="form.permission" style="width:100%;" placeholder="请选择">
          <el-option
            v-for="item in optionsPermission"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
    </el-col>
    
    <!-- 第一列 -->
    <el-col :span="12">
       <div class="colStyle">
          <img title='版本信息' src="../assets/img/jurassic_version.png" >
          <span>版本信息</span>
        </div>
        <el-input v-model="form.version" disabled autocomplete="off"></el-input>
    </el-col>
    
    <!-- 第二列 -->
    <el-col :span="12">
      <div class="colStyle">
          <img title='发布时间' src="../assets/img/fabushijian.png" >
          <span>发布时间</span>
        </div>
        <el-date-picker
        style="width:100%;"
            v-model="form.date"
            type="date"
            placeholder="选择日期">
          </el-date-picker>
        <!-- <el-input v-model="form.date" autocomplete="off"></el-input> -->
    </el-col>
    
    <!-- 第一列 -->
    <el-col :span="12">
      <div class="colStyle">
          <img title='语言' src="../assets/img/duoyuyan.png" >
          <span>语言</span>
        </div>
        <el-input v-model="form.language" autocomplete="off"></el-input>
    </el-col>
    
    <!-- 第二列 -->
    <el-col :span="12">
       <div class="colStyle">
          <img title='密级' src="../assets/img/miji.png" >
          <span>密级</span>
        </div>

         <el-select v-model="form.level" style="width:100%;" placeholder="请选择">
          <el-option
            v-for="item in optionsLevel"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
        <!-- <el-input v-model="form.level" autocomplete="off"></el-input> -->
    </el-col>
    
    <!-- 单独占满一行的表单项 -->
    <el-col :span="12" v-if='showView'> 
      <div class="colStyle">
          <img title='使用加载数据' src="../assets/img/xinxi.png" >
          <span>使用加载数据</span>
        </div>
      <div>

         <el-select v-model="isLoadOldDmc" style="width:100%;" placeholder="请选择">
          <el-option
            v-for="item in options2"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
          <!-- <el-radio v-model="isLoadOldDmc" label="1">使用</el-radio> -->
          <!-- <el-radio v-model="isLoadOldDmc" label="2">不使用</el-radio>  -->
        </div>
    </el-col>
  </el-row>
</el-form>
    
      <span slot="footer" class="dialog-footer"> 
        <el-button @click="dialogVisibleNav = false">取 消</el-button>
        <el-button  type="primary" v-if='navIsAdd == "create"&&isLoadOldDmc == "1"' @click="confirmAdd(false)">确 定</el-button>
        <el-button  v-if='navIsAdd == "create"&&isLoadOldDmc == "2"' type="primary" @click="confirmAdd(true)">确 定</el-button>
        <el-button  v-if='navIsAdd == "edit"' type="primary" @click="confirmEdit()">确 定</el-button>
      </span>
    </el-dialog>


  <!-- 删除目录确认弹窗 -->
    <el-dialog
      title="删除章节"
      :visible.sync="dialogVisibleNavDel"
      width="50%"
      class="custom-dialog"
      >
      <div>
        是否确定删除【{{currentNode?currentNode.name:''}}】?
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisibleNavDel = false">取 消</el-button>
        <el-button type="primary" @click="deleteNode">确 定</el-button>
      </span>
    </el-dialog>


    

  <!-- 删除资源确认弹窗 -->
    <el-dialog
      title="删除资源"
      :visible.sync="dialogVisibleAttrDel"
      width="50%"
      class="custom-dialog"
      >
      <div>
        是否确定删除【{{nowAttr.name}}】的绑定?
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisibleAttrDel = false">取 消</el-button>
        <el-button type="primary" @click="deleteAttrSure">确 定</el-button>
      </span>
    </el-dialog>


  <!--操作目录时候未保存提示 -->
    <el-dialog
      title="提示"
      :visible.sync="dialogVisibleTips"
      width="50%"
      class="custom-dialog"
      :before-close="handleClose2">
      <span>是否保存当前编辑内容</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="saveNowDmc('noSave')">不保存</el-button>
        <el-button type="primary" @click="saveNowDmc('save')">保存</el-button>
      </span>
    </el-dialog>

  <!-- 切换目录时候未保存提示 -->
    <el-dialog
      title="提 示"
      :visible.sync="dialogVisibleTips2"
      width="50%"
      class="custom-dialog"
      :before-close="saveNowDmc2">
      <span>是否保存当前编辑内容</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="saveNowDmc2('noSave')">不保存</el-button>
        <el-button type="primary" @click="saveNowDmc2('save')">保存</el-button>
      </span>
    </el-dialog>


  <!-- 邮件弹窗 -->
  <div 
    v-if="contextMenuVisible"
    class="custom-context-menu"
    :style="{ left: contextMenuLeft + 'px', top: contextMenuTop + 'px' }"
  > 
    <div class='nowRightHint' :title="nowRightHint">{{nowRightHint}}</div>
    <div class="menu-item" @click="handleMenuClick('a')"><img title='编辑章节'  src="../assets/img/bianji1.png" ><span>编辑章节</span></div>
    <div class="menu-item" @click="handleMenuClick('b')"><img title='绑定资源' src="../assets/img/bangdingziyuanchi.png" ><span>绑定资源</span></div>
    <div class="menu-item" @click="handleMenuClick('c')"><img title='版本定稿' src="../assets/img/dinggao.png" ><span>版本定稿</span></div>
    <div class="menu-item" @click="handleMenuClick('d')"><img title='历史版本' src="../assets/img/gaojisousuo.png" ><span>历史版本</span></div>
    <div class="menu-item" @click="handleMenuClick('e')"><img title='删除章节' src="../assets/img/shanchu-copy.png" ><span>删除章节</span></div>
    <!-- <div class="menu-divider"></div> -->
    <!-- <div class="menu-item" @click="contextMenuVisible = false">关闭</div> -->
  </div>

      <!-- 文件预览弹窗 -->
    <el-dialog
      title="文件预览"
      :visible.sync="maskViewShow"
      width="90%"
      class="custom-dialog viewDialog"
      :before-close="handleCloseMask"
    >
     <el-descriptions class="margin-top" v-if='viewXml' title="章节信息" :column="3" border>
        <template slot="extra">
          <el-button @click='dmcTable' type="primary" size="small">{{dmcHint?"收起":"展开"}}</el-button>
        </template>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            章节名称
          </template>
          {{rdfDescriptions[0].children[0].text}}
        </el-descriptions-item>
        <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            创作单位
          </template>
          {{rdfDescriptions[0].children[1].text}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            权限
          </template>
          {{formatOther('permission',rdfDescriptions[0].children[2].text).label}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            合作单位
          </template>
          {{rdfDescriptions[0].children[5].text}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            版本号
          </template>
          {{rdfDescriptions[0].children[6].text}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            密级
          </template>
          {{formatOther('level',this.rdfDescriptions[0].children[7].text).label}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            发布日期
          </template>
          {{formatDate(rdfDescriptions[0].children[8].text)}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            适用性信息
          </template>
          {{rdfDescriptions[0].children[9].text}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            质量验证
          </template>
          {{rdfDescriptions[0].children[10].text}}
        </el-descriptions-item>
            <el-descriptions-item v-if='dmcHint'>
          <template slot="label">
            语言
          </template>
          {{rdfDescriptions[0].children[14].text}}
        </el-descriptions-item>
      </el-descriptions>
        <div class="loadContent" v-html="neirong"> 
       </div>
    </el-dialog> 

    <el-dialog
      title="修改书名"
      :visible.sync="editBookNameDialog"
      width="60%"
      class="custom-dialog viewDialog2"
      :before-close="handleCloseEditBookName"
    >
      <el-input v-model="getBookName"  autocomplete="off"></el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editBookFun(false)">取消</el-button>
        <el-button type="primary" @click="editBookFun(true)">修改</el-button>
      </span>
    </el-dialog> 
  </div>
</template>

<script> 
import WangEditor from 'wangeditor'; 
import brImg from '../assets/img/br.png'; 
import '../assets/css/style.css'
export default {
  name: 'WangEditor',
  components: {
  },
  data() {
    return {
      countDialogVisible: false,
      domCount: 0,
      elementCount: 0,
      textCount: 0,
      commentCount: 0,
      countTarget: '',
      leftWidth: 380,
      isDragging: false,
      isLoadMsg:false,
      minLevel:'',
      maxLevel:'',
      maxPermission:'',
      minPermission:'',
      nowRightHint:'',
      dmcHint:false,
      rdfDescriptions:[],
      editBookNameDialog:false,
      getBookName:'',
      getBookNameDf:'',
      pickerOptions: {
          disabledDate(time) {
            return time.getTime() > Date.now();
          },
          shortcuts: [{
            text: '今天',
            onClick(picker) {
              picker.$emit('pick', new Date());
            }
          }, {
            text: '昨天',
            onClick(picker) {
              const date = new Date();
              date.setTime(date.getTime() - 3600 * 1000 * 24);
              picker.$emit('pick', date);
            }
          }, {
            text: '一周前',
            onClick(picker) {
              const date = new Date();
              date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit('pick', date);
            }
          }]
        },
      optionList:[
        {
          label:'使用',
          value:"1"
        },
        
        {
          label:'不使用',
          value:"2"
        }
      ],
      optionsPermission:[
       {label:'一级',value:'1'},
       {label:'二级',value:'2'},
       {label:'三级',value:'3'},
       {label:'四级',value:'4'},
       {label:'五级',value:'5'},
       {label:'六级',value:'6'},
       {label:'七级',value:'7'},
       {label:'八级',value:'8'},
       {label:'九级',value:'9'},
       {label:'十级',value:'10'},
      ],
      optionsLevel: [
        {value: '1',label: '公开'},
        {value: '2',label: '秘密'},
        {value: '3',label: '机密'},
        {value: '4',label: '绝密'}
        ],
      brImg:brImg,
      imgUrlJg: require('../assets/img/jgIcon.png'),//警告Icon
      imgUrlJs: require('../assets/img/jsIcon.png'),//警示Icon
      editorHeight:'',//编辑器高度
      historyVsPath:'',//查看历史文件路径
      leftHeight:'0',//左边容器高度
      isLoadXml:false,//是否加载DMC
      neirong:'',//预览内容
      isLoadOldDmc: "1", // 初始值需与 options 中的 value 类型一致
      options2:[
        {
          value:"1",
          label:"使用",
        },
        {
          value:"2",
          label:"不使用",
        }
      ], 
      showView:false,//是否显加载原文档
      tempDivData1:'',//模板文件容器
      viewLis:'',//预览时候端口号
      viewXml:'',//预览时候的XML内容
      maskViewShow:false,//文件预览弹窗是否显示
       // 屏幕整体尺寸（设备屏幕尺寸）
      screenWidth: 0,
      screenHeight: 0,
      // 浏览器窗口尺寸
      windowW: 0,
      windowH: 0,
      // 用于防抖的定时器
      resizeTimer: null,
      // 保存对新窗口的引用
      wangG2Window: null,
      // 用于检查窗口状态的定时器
      checkWindowTimer: null, 
      showModifyBtn: false, // 控制是否显示【修改】的开关（按钮点击后设为true）
      mId:'',//当前最大ID
      loadFileDMC:'',//加载的DMC文件里面的content内容
      loadFileXML:'',//加载的DMC文件内容
      historyData:[],//历史版本列表信息
      contextMenuVisible: false,  // 右键菜单是否可见
      contextMenuLeft: 0,         // 右键菜单left位置
      contextMenuTop: 0,          // 右键菜单top位置
      contextMenuNode: null,       // 右键点击的节点数据
      nowAttr:{//当前操作的资源
        name:'',
        index:''
      },
      dialogVisibleAttrDel:false,//删除弹窗
      dialogVisibleTips2:false,//切换目录时候未保存提示弹窗是否显示
      dialogVisibleTips:false,//操作目录时候未保存提示弹窗是否显示
      contentXmlStr:'',//当前富文本字符串
      getDmName:'',//当前DM文件名。
      isNavEdit:false,//是否在目录编辑状态。
      allImgType://暂定当前的图片类型
      new Set([
        "bmp", "jpg", "jpeg", "png", "tif", "gif", "pcx", "tga", "exif", "fpx", "svg", "psd", "cdr", "pcd", "dxf", "ufo", "eps", "ai", "raw", "WMF", "webp", "avif", "apng"
      ]),
      allMusicType:new Set([//暂定当前的音频类型
        "mp3", "aac", "wav", "flac", "alac", "wma"
       ]),
      allVideoType:new Set([//暂定当前的视频类型
        "mp4", "avi", "mkv", "mov", "flv", "wmv", "webm", "mpeg"
      ]),
      otherType:new Set(['wrl','jltf']),
      lisenPath:'',//当前内置服务器端口
      //目录
      domNameStr:[//拼接文档名
        'DMC-','test2','-A-P4-20-00-00A-','A-A_000_00','_zh_cn'
        ],
      lastClick:'',//上一次点击的目录id
      nowClick:'',//当前点击的目录id
      nowMaxId:'',//最大文档id
      catalogueString:'',//目录字符串
      navIsAdd:'',//判断当前目录操作类型
      searchText:'',//搜索目录章节
      dialogVisibleNav:false,//目录弹窗
      dialogVisibleRight:false,//右键绑定弹窗
      dialogVisibleBland:false,//绑定源弹窗
      dialogVisibleHistory:false,//历史版本弹窗
      dialogVisibleNavDel:false,//删除弹窗
      selectedAttributes: [], // 当前选中的属性
      treeData: [//基础目录数据
        // { id: '00001', name: '根节点1根节点1根节点1根节点1根节点1根节点1', children: [
        //   {
        //     id: '00003', name: '根节点3根节点3根节点3根节点3根节点3', children: [{
        //       id: '00004', name: '根节点4根节点4根节点4根节点4根节点4', children: [],
        //       attributes: [] // 示例：已绑定的属性
        //     }]
        //   }
        // ], attributes: [] // 示例：已绑定的属性
        // },
        // { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
        //   {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: [ { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
        //   {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: [ { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
        //   {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: [ { id:'00002', name: '根节点2根节点2根节点2根节点2根节点2', children: [
        //   {id: '00005', name: '根节点5根节点5根节点5根节点5根节点5', children: []}
        // ] }]}
        // ] }]}
        // ] }]}
        // ] }
      ],
      treeData2:[
  {
    id: '00001',
    name: '装备概况',
    attributes: ['金', '木', '水'],
    formMes: {},
    lagreVersion: '001',
    minorVersion: '01',
    children: [
      {
        id: '00002',
        name: '方舱概述',
        attributes: [],
        lagreVersion: '001',
        minorVersion: '01',
        children: [
          {
            id: '00003',
            name: '功能介绍',
            attributes: [],
            formMes: {},
            lagreVersion: '001',
            minorVersion: '01',
            children: []
          },
          {
            id: '00004',
            name: '规格介绍',
            attributes: ['水'],
            formMes: {},
            lagreVersion: '001',
            minorVersion: '01',
            children: []
          }
        ]
      },
      {
        id: '00005',
        name: '舱体',
        attributes: ['火', '土'],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: []
      },
      {
        id: '00006',
        name: '机身转运小车',
        attributes: [],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: []
      },
      {
        id: '00007',
        name: '无人机部件存储装置',
        attributes: [],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: []
      },
      {
        id: '00008',
        name: '机身转运小车',
        attributes: [],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: []
      },
      {
        id: '00009',
        name: '附件及工具',
        attributes: [],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: [
          {
            id: '00010',
            name: '灭火器',
            attributes: [],
            formMes: {},
            lagreVersion: '001',
            minorVersion: '01',
            children: []
          },
          {
            id: '00011',
            name: '应急灯',
            attributes: [],
            formMes: {},
            lagreVersion: '001',
            minorVersion: '01',
            children: []
          },
          {
            id: '00012',
            name: '土木工具',
            attributes: [],
            formMes: {},
            lagreVersion: '001',
            minorVersion: '01',
            children: []
          },
          {
            id: '00013',
            name: '机械工具',
            attributes: [],
            formMes: {},
            lagreVersion: '001',
            minorVersion: '01',
            children: []
          }
        ]
      }
    ]
  },
  {
    id: '00013',
    name: '使用说明',
    attributes: [],
    formMes: {},
    lagreVersion: '001',
    minorVersion: '01',
    children: [
      {
        id: '00014',
        name: '无人机出舱',
        attributes: [],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: []
      },
      {
        id: '00015',
        name: '无人机入舱',
        attributes: [],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: []
      },
      {
        id: '00016',
        name: '灭火器使用',
        attributes: [],
        formMes: {},
        lagreVersion: '001',
        minorVersion: '01',
        children: []
      }
    ]
  }
      ],
      defaultProps: {//树结构
        children: 'children',
        label: 'name'
      },
      currentNode: null,//当前节点
      form: {//默认目录信息
        name: '',
        version:'000',
        date:'',
        language:'',
        level:'1',
        contributor:'',
        creator:'四威高科',
        applicabilityInformation:'',
        qualityVerification:'',
        permission:'1'
        // version:'001',
        // date:'2046-12-12',
        // language:'zn_cn',
        // level:'公开',
        // contributor:'责任合作单位',
        // creator:'创作单位',
        // applicabilityInformation:'适用性信息',
        // qualityVerification:'质量验证',
        // permission:'10'
      },
      rules: {//规则
        name: [
          { required: true, message: '请输入节点名称', trigger: 'blur' },
          { min: 1, max: 40, message: '长度在 1 到 40 个字符', trigger: 'blur' }
        ]
      },
      //弹窗
      dialogVisible:false,//自定义弹窗
      idLength:10,//暂无用
      contextMenu: {//暂无用
        visible: false,
        x: 0,
        y: 0,
        selectedElement: null,
        selectedParam: ''
      },
      isContextMenuEnabled: false,//暂无用
      itemParams: {}, //暂无用
      // 存储元素的参数 {elementId: param}
          // 模拟弹框参数
       //查看图片begin
      dialogVisibleImg:false,//暂无用
      images: [//暂无用
          'https://ww2.sinaimg.cn/mw690/007ut4Uhly1hx4v37mpxcj30u017cgrv.jpg',
          'https://example.com/image2.jpg'
        ],
      currentImage: '',//暂无用
      scale: 1,//暂无用
      rotation: 0,//暂无用
      startX: 0,//暂无用
      startY: 0,//暂无用
      translateX: 0,//暂无用
      translateY: 0,//暂无用
      containerHeight: '90vh', //暂无用 动态控制高度
      //查看图片end
      // oldSelector:[//基础标签模块
      //   'div','code','hr','br','h1,h2,h3,h4','p','img','table','a','ul','ol','blockquote','pre',
      // ],
      // newSelector:[//替换后的标签模块
      //   'pDiv','pCode','pHr','pBr','pTitle','pDiv','pImg','pTable','pA','pUl','pOl','pBlockquote','pPre',
      // ],
      newSelector:[],
      oldSelector:[],
      tempDivData:{//当前富文本str
        innerHTML:'五'
      },
      colors:'',//暂无用
      val1:'',//暂无用
      val2:'',//暂无用
      message: '',//暂无用
      editor: null, //编辑器
      editorContent: '',//富文本内容 
    }
  },
  computed: {  
  },
  mounted() {
        // 初始化尺寸
    this.getWindowSize()
    // 绑定 resize 事件
    window.addEventListener('resize', this.handleResize)
   
   
    //   // 确保DOM已加载
    // this.$nextTick(() => {
    //   this.initEditor()
    // })

    this.$nextTick(() => {
      // 初始时如果容器不可见，等待 currentNode 变化后再初始化
      if (this.currentNode) {
        this.initEditor();
      }
    });
   
    console.log('chrome对象是否存在:', !!window.chrome);
    console.log('webview对象是否存在:', !!window.chrome?.webview);

     window.removeEventListener('SelectFilePathSend', this.handleFilePathSend);
      // 再绑定新的监听器
      window.addEventListener('SelectFilePathSend', this.handleFilePathSend);

      window.addEventListener('SelectFilePathSend', this.SendLisentPathFun);
  },
  beforeDestroy() {
    // 销毁编辑器
    if (this.editor) {
      this.editor.destroy()
    }
    // 清理定时器
    if (this.checkWindowTimer) {
      clearInterval(this.checkWindowTimer)
    }
    console.log('监听器开始移除：', Date.now()) // 打印移除时间戳
    window.removeEventListener('resize', this.handleResize)
    window.removeEventListener('FrontLoadDM', this.FrontLoadDM_g1)
    window.removeEventListener('handleMessageFromDotNet', this.fun1)
    window.removeEventListener('SelectFilePathSend', this.SendLisentPathFun)
     
  },
  methods: { 
    //清除节点选中 
    clearNodeState() {
      this.currentNode = '';
      // 通过ref获取el-tree实例
      const tree = this.$refs.tree;
      
      if (tree) {
        // 取消当前选中状态
        tree.setCurrentKey(null);
        
        // 如果需要清除所有节点的选中状态（包括多选情况）
        // 先获取所有选中的节点
        const selectedNodes = tree.getCheckedNodes();
        // 取消所有节点的选中状态
        selectedNodes.forEach(node => {
          tree.setChecked(node.id, false);
        });
        
        // 可选：触发节点点击事件的回调，传递null表示无选中节点
        // this.handleNodeClick(null);
      }
    },
    // 测试接收数据
    fun1(e) {
      console.log("方法1",e,e.detail)
    },
    // 获取服务端口地址
    SendLisentPathFun(e) {
      console.log('服务端口地址信息1:',e,e.detail)
      this.lisenPath = e.detail;
    },


    FrontLoadDM_g2(e) {
       // 加载目录 
      console.log('FrontLoadProjectNew111 参数接收:')
      
      this.isLoadXml = true;
      this.currentNode = '';
      //获取目录字段拼接，暂不用
      // this.extractDmCode(e.detail) 
      // 去除首尾的双引号
      let processed = e.detail.trim(); 
      // 检查并去除开头的双引号
      if (processed.startsWith('"')) {
        processed = processed.substring(1);
      } 
      // 检查并去除结尾的双引号
      if (processed.endsWith('"')) {
        processed = processed.substring(0, processed.length - 1);
      } 
      // this.outputXml = processed; 
      this.generateTreeData(processed);
      // this.parseXml(processed);
      // this.parseToTreeData(processed)
    },






    //接收富文本内容信息
    FrontLoadDM_g1(e) {
         console.log("加载文档数据 1111")
      // console.log('FrontLoadDM 参数接收111:',e,e.detail)
      // this.editorShow = true;

      let xmlContent = e.detail.trim();

      if (xmlContent.startsWith('"')) {
        xmlContent = xmlContent.substring(1);
      } 
      // 检查并去除结尾的双引号
      if (xmlContent.endsWith('"')) {
        xmlContent = xmlContent.substring(0, xmlContent.length - 1);
      } 
      // console.log("xmlContent",xmlContent)
      const parser = new DOMParser()
      const xmlDoc = parser.parseFromString(xmlContent, "text/xml")
      // console.log("xmlDoc",xmlDoc)
      const contentNodes = xmlDoc.getElementsByTagName('content')[0];
      // console.log("xmlDoc.getElementsByTagName('content')",xmlDoc.getElementsByTagName('content'))
      // console.log("contentNodes",contentNodes)
      

       const rdfDescription = xmlDoc.querySelector('rdf\\:Description, Description');
        
        if (rdfDescription) {
          // 填充表单数据 - 映射关系：form字段 -> XML标签
          this.form = {
            name: this.getNodeValue(rdfDescription, 'dc\\:title, title'),
            version: this.getNodeValue(rdfDescription, 'dc\\:version, version'),
            date: this.getNodeValue(rdfDescription, 'dc\\:date, date'),
            language: this.getNodeValue(rdfDescription, 'dc\\:language, language'),
            level: this.getNodeValue(rdfDescription, 'dc\\:level, level'),
            contributor: this.getNodeValue(rdfDescription, 'dc\\:contributor, contributor'),
            creator: this.getNodeValue(rdfDescription, 'dc\\:creator, creator'),
            applicabilityInformation: this.getNodeValue(rdfDescription, 'dc\\:applicabilityInformation, applicabilityInformation'),
            qualityVerification: this.getNodeValue(rdfDescription, 'dc\\:qualityVerification, qualityVerification'),
            permission: this.getNodeValue(rdfDescription, 'dc\\:permission, permission')
          };
          // console.log('XML解析成功', this.form);
        }else{
          this.form = {
              name: '',
              version:'000',
              date:'',
              language:'',
              level:'1',
              contributor:'',
              creator:'四威高科',
              applicabilityInformation:'',
              qualityVerification:'',
            };
            console.log("目录解析不成功 置空",this.form)
        }
      if (contentNodes) {
        // console.log("处理前",contentNodes.innerHTML)
        let htmlContent = this.convertXmlContentToHtml(contentNodes.innerHTML)
       let htmlContent2 = this.completeModel3DTags(htmlContent)
      //  console.log("处理后",htmlContent2)
       const htmlContent3 = this.replaceModel3dToImg(htmlContent2);
       // this.editor.txt.html(htmlContent)
        //处理过后再导入
        // this.restoreContent(htmlContent)
        this.restoreContentXh(htmlContent3)
      }
    },
    //测试发送给后端信息
    sendMessageToHost() {
      //调用后端 sendToDotNet
      this.$sendToDotNet(this.val1,this.val2);
      
    }, 
    initEditor() {//初始化编辑器配置
      this.editor = new WangEditor(this.$refs.editor)
      const editorEl = this.$refs.editor;
      if (!editorEl) {
        console.warn('编辑器容器不存在');
        return;
      }
      // 配置编辑器
      this.editor.config.uploadImgShowBase64 = true // 使用 base64 保存图片
      this.editor.config.onchange = (html) => {
        this.editorContent = html;
      }
      let dm = this.editor.config.menus;
      console.log("默认菜单",dm)
 



      // 启用颜色选择功能
    this.editor.config.colors = [
      '#000000', '#ffffff', '#eeeef1', 
      '#ff0000', '#ff5e5e', '#ffbbbb',
      '#0033ff', '#0055ff', '#3d7eff',
      'red',"#096","#9cf"
    ]
      // 完全自定义菜单
  this.editor.config.menus = [
    'image',    // 图片
    'video',    // 视频
    // 'head',    // 标题
    'bold',    // 粗体
    'fontSize',//字号
    // 'fontName',//字体
    'italic',  // 斜体
    'underline', // 下划线
    'strikeThrough', // 删除线
    // 'line',//行高
    'lineHeight',//
    'foreColor', // 文字颜色
    'backColor', // 背景颜色
    'link',     // 链接
    'list',     // 列表
    // 'todo',//
    'justify',  // 对齐方式
    'quote',    // 引用
    // 'emoticon',//表情
    'table',    // 表格
    'code',     // 代码
    'splitLine',//分割线
    'undo',     // 撤销
    'redo',      // 重做 
  ]
 
  console.log("自定义菜单",this.editor.config)


  // 自定义处理拖拽事件
      this.editor.config.customUpload = true
      
      // 监听拖拽事件
      this.editor.config.uploadImgShowBase64 = false
      this.editor.config.uploadVideoShowBase64 = false
      this.editor.config.uploadAudioShowBase64 = false
      // 设置自定义拖拽处理
      // this.setupDragHandler()
      


       // 保存原始的创建方法
      const originalCreate = this.editor.create
      
      // 重写创建方法，在创建完成后立即添加按钮
      this.editor.create = () => {
        // 执行原始创建方法
        originalCreate.call(this.editor)
        
        // 尝试获取工具栏
        // 📌🔖
        // 
        this.addCustomButton('警示', '<img src="'+this.imgUrlJs+'" alt="按钮图标" style="width: 20px; height: 20px; object-fit: contain;">',1)  // 第一个按钮，弹出123，使用图钉图标
        this.addCustomButton('警告', '<img src="'+this.imgUrlJg+'" alt="按钮图标" style="width: 20px; height: 20px; object-fit: contain;">',2)  // 第一个按钮，弹出123，使用图钉图标
      }







      // 创建编辑器
      this.editor.create();
      // 特别注意：需要在编辑器创建完成后绑定事件
      this.$nextTick(() => {
      console.log("初始化 setupDragHandler")
        this.setupDragHandler()
      })
 

      //   this.editor2 = new WangEditor(this.$refs.editor2)
      // // 配置编辑器
      // this.editor2.config.uploadImgShowBase64 = true // 使用 base64 保存图片
      // this.editor2.config.onchange = (html) => {
      //   console.log("22222",html)
      //   // this.editorContent2 = html
      // }
      //  this.editor2.create()



    },
    //编辑书名  
    editBookName() {
      console.log("编辑书名")
      const getBookNameDf = this.getBookName;
      this.getBookNameDf = getBookNameDf;
      this.editBookNameDialog = true;
    },
    editBookFun(type) { 
      if(type){
       this.catalogueAnalysis(this.treeData);
       this.editBookNameDialog = false;
      }else{
        this.getBookName = this.getBookNameDf;
        this.editBookNameDialog = false;
      }
    },

// 通用的添加自定义按钮方法，接收两个参数：提示内容和图标
    addCustomButton(alertContent, icon,type) {
      let toolbarElem = null
      
      // 方式1: 通过编辑器内部属性获取工具栏
      if (this.editor.$toolbarElem && this.editor.$toolbarElem[0]) {
        toolbarElem = this.editor.$toolbarElem[0]
        console.log('通过$toolbarElem获取到工具栏')
      }
      
      // 方式2: 直接通过容器查找
      if (!toolbarElem) {
        toolbarElem = this.$refs.editor.querySelector('.w-e-toolbar')
        if (toolbarElem) {
          console.log('通过容器查询获取到工具栏')
        }
      }
      
      // 方式3: 全局查找
      if (!toolbarElem) {
        toolbarElem = document.querySelector('.w-e-toolbar')
        if (toolbarElem) {
          console.log('通过全局查询获取到工具栏')
        }
      }
      
      // 如果还是找不到工具栏，直接创建一个简单的按钮放在编辑器上方
      if (!toolbarElem) {
        console.warn('仍然未找到工具栏，创建独立按钮')
        this.createFallbackButton(alertContent, icon,type)
        return
      }
      
      // 查找或创建菜单容器
      let menuBar = toolbarElem.querySelector('.w-e-menu-bar')
      if (!menuBar) {
        menuBar = document.createElement('div')
        menuBar.className = 'w-e-menu-bar'
        menuBar.style.cssText = 'padding: 5px; border-bottom: 1px solid #e8e8e8;'
        toolbarElem.appendChild(menuBar)
      }
      
      // 创建自定义按钮
      const customBtn = document.createElement('div')
      customBtn.className = 'w-e-menu'
      customBtn.style.cssText = `
        width: 32px;
        height: 32px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        margin: 0 2px;
        background: #fff;
        border-radius: 2px;
        color: #333;
        font-size: 18px;
      `
      customBtn.innerHTML = icon
      customBtn.title = `${alertContent}`
      
      // 绑定点击事件，使用传入的提示内容
      customBtn.onclick = () => {
        console.log("点击了111",type)
          switch (type){
            case 1:
            case '1':
              

//               this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style='
// padding: 20px;
// margin: 20px;
//  background-image:url("`+this.brImg+`");
// '><p class='teshu' style="border-radius: 4px;padding: 10px;border: 3px solid #000;"></p></div>
// <p data-we-empty-p=""><br></p>`)


              // this.editor.cmd.do('insertHTML', `<p class='jg'>[[]]</p>`)

    //           this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style='margin: 10px auto;
    // padding: 10px;
    // border: 10px solid;
    // background:#fff;
    // border-image: linear-gradient(45deg, 
    //     #ffcc00 0%, #ffcc00 10%, 
    //     #000000 10%, #000000 20%,
    //     #ffcc00 20%, #ffcc00 30%,
    //     #000000 30%, #000000 40%,
    //     #ffcc00 40%, #ffcc00 50%,
    //     #000000 50%, #000000 60%,
    //     #ffcc00 60%, #ffcc00 70%,
    //     #000000 70%, #000000 80%,
    //     #ffcc00 80%, #ffcc00 90%,
    //     #000000 90%, #000000 100%
    // ) 1;' class='teshu2'></div><p data-we-empty-p=""><br></p>`)

    
              this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style='margin: 10px auto;
    padding: 10px;
    background:#fff;' class='teshu2 borderStyle_yellow'></div><p data-we-empty-p=""><br></p>`)
              break;
            case 2:
            case '2':
              // this.editor.cmd.do('insertHTML', `<p class='js'><<>></p>`)
              // this.editor.cmd.do('insertHTML', `<div class='jg' style='border:1px solid red;padding:10px;'></div>`)

    //           this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style="margin: 50px auto;
    // padding: 20px;
    // border: 12px solid;
    // background:#fff;
    // border-image: linear-gradient(-45deg, 
    //     #ff0000 0%, #ff0000 10%, 
    //     #000000 10%, #000000 20%,
    //     #ff0000 20%, #ff0000 30%,
    //     #000000 30%, #000000 40%,
    //     #ff0000 40%, #ff0000 50%,
    //     #000000 50%, #000000 60%,
    //     #ff0000 60%, #ff0000 70%,
    //     #000000 70%, #000000 80%,
    //     #ff0000 80%, #ff0000 90%,
    //     #000000 90%, #000000 100%
    // ) 1;" class='teshu'></div><p data-we-empty-p=""><br></p>`)

     this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><br></p><div style="margin: 10px auto;
    padding: 10px;
    background:#fff;" class='teshu borderStyle_red'></div><p data-we-empty-p=""><br></p>`)
              break;
          }
      }
      
      // 添加悬停效果
      customBtn.onmouseover = () => {
        customBtn.style.background = '#f0f0f0'
      }
      customBtn.onmouseout = () => {
        customBtn.style.background = '#fff'
      }
      
      // 添加到菜单最前面
      menuBar.insertBefore(customBtn, menuBar.firstChild)
      console.log(`自定义按钮(弹出${alertContent})已成功添加到菜单栏`)
    },
    
    // 备用方案：如果找不到工具栏，直接在编辑器上方创建一个按钮
    createFallbackButton(alertContent, icon,type) {
      const fallbackBtn = document.createElement('div')
      fallbackBtn.style.cssText = `
        padding: 8px 15px;
        background: #409eff;
        color: white;
        border-radius: 4px;
        cursor: pointer;
        display: inline-block;
        margin: 0 5px 10px 0;
      `
      fallbackBtn.innerHTML = `${icon} 点击弹出${alertContent}`
      fallbackBtn.onclick = () => {
        console.log("点击了222",type)
        switch (type){
          case 1:
            this.editor.cmd.do('insertHTML', `<p class="fine-stripe-border1"><div></div></p>`)
            break;
          case 2:
            this.editor.cmd.do('insertHTML', `<p class="fine-stripe-border2"><div></div></p>`)
            break;
        }
      }
      
      // 添加到编辑器容器的最前面
      this.$refs.editor.insertBefore(fallbackBtn, this.$refs.editor.firstChild)
      console.log(`已创建备用按钮(弹出${alertContent})`)
    },















    setupDragHandler() {
      console.log("进入setupDragHandler")
      const editor = this.editor
      const editorContainer = editor.$textElem.elems[0]
      let that = this;
      // console.log("进入参数",editor,editorContainer)
      // // 阻止默认拖拽行为
      editorContainer.addEventListener('dragover', (e) => {
        // console.log("进入 dragover",e)
        e.preventDefault()
        e.stopPropagation()
      })
      
      editorContainer.addEventListener('drop', (e) => {
        //  console.log("进入 drop",)
        e.preventDefault()
        e.stopPropagation()
        that.$sendToDotNet('GetMaterialPath');
      //   // 检查拖拽的文件类型
      //   const items = e.dataTransfer.items
      //   for (let i = 0; i < items.length; i++) {
      //     const item = items[i]
      //     if (item.kind === 'file') {
      //       const file = item.getAsFile()
      //       const fileType = file.type.split('/')[0]
            
      //       // 根据文件类型显示不同的提示
      //       switch(fileType) {
      //         case 'image':
      //           alert('检测到图片文件，已阻止上传')
      //           break
      //         case 'video':
      //           alert('检测到视频文件，已阻止上传')
      //           break
      //         case 'audio':
      //           alert('检测到音频文件，已阻止上传')
      //           break
      //         default:
      //           alert(`检测到${fileType}类型文件，已阻止上传`)
      //       }
      //     }
      //   }
      })
    },
    
    
    // 上传图片
    insertImage(src) {
      if (!this.editor) {
        console.error('编辑器未初始化，无法插入图片');
        return;
      }else{
        // src = 'http://localhost:54610/a1.jpg';
          // const imgUrl = 'http://youneed.top:10017/uploads/1.jpg'
          // const imgUrl = 'https://ww2.sinaimg.cn/mw690/007ut4Uhly1hx4v37mpxcj30u017cgrv.jpg';
        if(src){
          const imgUrl = src?src:'http://localhost:5432/DM_Material/a1.jpg';
          console.log("地址",src,imgUrl)
          this.editor.cmd.do('insertHTML', `<img src="${imgUrl}" width="50%" alt="图片">`)
        }
      } 
    },
    // 上传3D资源模拟占位
    insert3d(imgUrl) {
      this.editor.cmd.do('insertHTML', `<img src="${imgUrl}" class='model3d' style="width: 100%;" alt="图片"><p data-we-empty-p=""><br></p>`)
      // this.editor.cmd.do('insertHTML', `<div>3D模型<model3d src="http://www.baidu.com" controls="controls" style="max-width: 100%"></model3d></div>`)
    },
    //上传3D资源模设置标识
   replacemodel3dImages(htmlString) {
       if (!htmlString) return '';
      
      const regex = /<img([^>]*?)class="model3d"([^>]*?)\/?>/gi;
      
      return htmlString.replace(regex, (match, prefix, suffix) => {
        const attributes = (prefix || '') + (suffix || '');
        return `<model3d class="model3d" ${attributes}></model3d>`;
      });
    },
    //解析3d资源标识
    modelToImg(htmlString) {
      // 匹配<model3d>标签且class中包含model3d
      const regex = /<model3d([^>]*?)class="([^"]*?)model3d([^"]*?)"([^>]*?)>/gi;
      
      // 替换标签名，保留所有属性
      return htmlString.replace(regex, '<img$1class="$2model3d$3"$4>');
    },
 
     dmcTable() {
      if(this.dmcHint){
        this.dmcHint = false;
      }else{
        this.dmcHint = true;
      }
    },


    formatOther(type,data){
      let textStr = null;
      console.log("内容",type,data)
      switch(type){
        case "level":
          textStr = this.optionsLevel.find(item => {
            return item.value === data;
          });
          break;
        case "permission":
          textStr = this.optionsPermission.find(item => {
            return item.value === data;
          });
          break;
      }
      console.log('内容',data,textStr)
      return textStr;
    },

      formatDate(dateStr) {
      if (!dateStr) return "";
      
      try {
        // 将字符串转换为Date对象
        const date = new Date(dateStr);
        
        // 获取年、月、日
        const year = date.getFullYear();
        // 月份从0开始，需要+1，并用padStart补零确保两位数
        const month = String(date.getMonth() + 1).padStart(2, "0");
        // 日期补零确保两位数
        const day = String(date.getDate()).padStart(2, "0");
        
        // 返回格式化后的字符串（格式：YYYY-MM-DD）
        return `${year}-${month}-${day}`;
      } catch (error) {
        console.error("日期格式化失败：", error);
        return "无效日期";
      }
    },
    parseRdfDescriptions() {
      try {
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(this.viewXml, 'text/xml');
        
        // 定义RDF命名空间（关键：必须与XML中的命名空间一致）
        const nsResolver = (prefix) => {
          const ns = {
            'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
            // 可以添加其他需要的命名空间
          };
          return ns[prefix] || null;
        };
        
        // 使用XPath查询所有rdf:Description元素
        const xpathResult = xmlDoc.evaluate(
          '//rdf:Description',
          xmlDoc,
          nsResolver,
          XPathResult.ORDERED_NODE_ITERATOR_TYPE,
          null
        );
        
        this.rdfDescriptions = [];
        let currentNode;
        
        // 遍历所有找到的rdf:Description节点
        while ((currentNode = xpathResult.iterateNext())) {
          // 获取节点内的所有内容（包括子节点和文本）
          const content = {
            attributes: {},
            children: [],
            innerXML: currentNode.innerHTML // 完整的内部XML
          };
          
          // 获取所有属性
          if (currentNode.attributes) {
            for (let i = 0; i < currentNode.attributes.length; i++) {
              const attr = currentNode.attributes[i];
              content.attributes[attr.name] = attr.value;
            }
          }
          
          // 获取所有子节点文本内容
          if (currentNode.children && currentNode.children.length > 0) {
            for (let i = 0; i < currentNode.children.length; i++) {
              const child = currentNode.children[i];
              content.children.push({
                tag: child.tagName,
                text: child.textContent,
                attributes: Array.from(child.attributes).reduce((attrs, attr) => {
                  attrs[attr.name] = attr.value;
                  return attrs;
                }, {})
              });
            }
          } else {
            // 如果没有子节点，直接获取文本内容
            content.text = currentNode.textContent;
          }
          
          this.rdfDescriptions.push(content);
        }
        
        console.log('所有rdf:Description内容：', this.rdfDescriptions);
      } catch (error) {
        console.error('解析XML出错：', error);
      }
    },
    // 插入视频
    insertVideo(src) {
       if (!this.editor) {
        console.error('编辑器未初始化，无法插入插入视频');
        return;
      }else{
        // const videoUrl = src?src:'https://r1.realme.net/general/20250530/17485780109181ed6767541a64e7d90626e0a3fd1aaae.mp4?type=video/mp4'
        const videoUrl = src?src:'http://localhost:5432/DM_Material/video.mp4'
        
        // 使用 editor.cmd.do 执行插入操作，支持撤销/重做
        this.editor.cmd.do('insertHTML', `<p data-we-empty-p=""><div><video src="${videoUrl}" style="width: 100%;" controls="controls" style="max-width: 100%"></video></div><p data-we-empty-p=""><br></p><p data-we-empty-p=""><br></p></p>`)
        
      }
      
      // 或者使用更简单的插入方式
      // this.editor.txt.append(`<video src="${videoUrl}" controls="controls" style="max-width: 100%"></video>`)
    },
    
    // 插入音频
    insertAudio(src) {
       if (!this.editor) {
        console.error('编辑器未初始化，无法插入音频');
        return;
      }else{
        // let audioUrl = 'https://m801.music.126.net/20250805103535/df94bdfa3bc8c3a07de64531c4925895/jdymusic/obj/wo3DlMOGwrbDjj7DisKw/14096444542/bafc/a068/39f8/9a9e06e5634410b5e7e81df24749e656.mp3?vuutv=6WGmbU7+iXWmpSMnJs8FQEYWEieNRcA9S4YcUYOjmx36NJRHK0ASi7jhIJz0R9gxcmMcAUDn9rf1k08lFtqC9TQYcOlc8ZofqvCCJho3eeBGH/hwnjUlaQHe2GQFyJ32rhYAydM3bCBfIg+ZnpfZTw==';
        let audioUrl =src?src:'http://localhost:5432/DM_Material/music.mp3';
        // 使用预设音频URL
        // const audioHtml = `
        //   <div class="audio-container" style="margin: 10px 0;">
        //     <audio controls src="${audioUrl}" style="width: 100%;"></audio>
        //     <div style="text-align: center; color: #999; font-size: 12px;">音频文件</div>
        //   </div>
        // `;
        const audioHtml = `
        <p data-we-empty-p=""><audio controls src="${audioUrl}" style="width: 100%;"></audio></p><p data-we-empty-p=""><br></p><p data-we-empty-p=""><br></p><p data-we-empty-p=""><br></p>
        `;
        
        // 插入到编辑器
        this.editor.cmd.do('insertHTML', audioHtml);
        
      }
      
      // 或者使用更简单的方式
      // this.editor.txt.append(audioHtml)
    },
   

//循环处理标签
  xh(oldSt,newSt,type,saveId){
    let times = oldSt.length;

    // const ht1 = this.tempDivData.innerHTML;
    // console.log("3d转换之后2",ht1)
    for(let i = 0;i<times;i++){
      const headings = this.tempDivData.querySelectorAll(oldSt[i])
      headings.forEach(heading => {
        const dmTitle = document.createElement(newSt[i])
        heading.parentNode.insertBefore(dmTitle, heading)
        console.log("内容替换",dmTitle, heading)
        dmTitle.appendChild(heading)
      })
    }
    this.createXmlSt(type,saveId);
  },
  //  先清除已有的ID，确保干净的基础
  removeAllIds(htmlString) {
      // 创建临时容器解析HTML
      const tempContainer = document.createElement('div');
      tempContainer.innerHTML = htmlString;
      
      // 递归移除所有元素的id属性
      const removeIdsFromElement = (element) => {
        if (!element || element.nodeType !== 1) return;
        
        // 移除当前元素的id
        element.removeAttribute('id');
        
        // 递归处理子元素
        Array.from(element.children).forEach(child => {
          removeIdsFromElement(child);
        });
      };
      
      // 处理所有子元素
      Array.from(tempContainer.children).forEach(child => {
        removeIdsFromElement(child);
      });
      
      return tempContainer.innerHTML;
    },
    // 删除Colgroup
    removeColgroup(str) {
      // 1. 校验入参（防止传入null/undefined导致报错）
        if (!str || typeof str !== 'string') {
          console.warn('传入的内容不是有效字符串');
          return str; // 入参无效时，直接返回原内容
        }

        // 2. 定义正则（匹配colgroup标签，不区分大小写、全局匹配）
        const colgroupReg = /<colgroup[\s\S]*?<\/colgroup>/gi;
        
        // 3. 判断是否包含colgroup标签
        const hasColgroupTag = colgroupReg.test(str);
        
        // 4. 处理逻辑：包含则移除，不包含则返回原字符串
        let processedStr;
        if (hasColgroupTag) {
          processedStr = str.replace(colgroupReg, '');
          console.log('检测到colgroup标签，已移除');
        } else {
          processedStr = str; // 关键：不包含时返回原字符串，而非null
          console.log('未检测到colgroup标签，返回原字符串');
        }

        // 5. 打印日志（便于调试）
        console.log('解析前：', str);
        console.log('解析后：', processedStr);
        
        return processedStr;
    },
    
    /**
     * 为HTML字符串中的所有标签添加唯一ID
     * @param {string} htmlString - 原始HTML字符串
     * @returns {string} 处理后的HTML字符串
     */
    addUniqueIds(htmlString) {
      // 先清除已有的ID，确保干净的基础
      const cleanHtml = this.removeAllIds(htmlString);
      

      console.log("当前的所有html内容2",cleanHtml)
      const tempContainer = document.createElement('div');
      tempContainer.innerHTML = cleanHtml;
      
      const usedIds = new Set();
      
      // 生成唯一ID
      const generateUniqueId = (tagName, content = '') => {
        const pureTagName = tagName.toLowerCase().replace(/^p/, '');
        const semanticSuffix = content.trim()
          .replace(/\s+/g, '_')
          .replace(/[^a-z0-9-]/g, '')
          .slice(0, 10);
          console.log('循环数据semanticSuffix',semanticSuffix)
        let baseId = pureTagName + (semanticSuffix ? `id_${semanticSuffix}` : 'id');
        let finalId = baseId;
        let counter = 1;
        
        // console.log('循环数据counter',counter)
        // console.log('循环数据baseId',baseId)
        while (usedIds.has(finalId)) {
          finalId = `${baseId}_${counter}`;
          counter++;
        }
        
        usedIds.add(finalId);
        return finalId;
      };
      
      // 递归添加ID
      const addIdsToElement = (element) => {
        if (!element || element.nodeType !== 1) return;
        
        const elementText = element.textContent || '';
        const elementId = generateUniqueId(element.tagName, elementText);
        element.setAttribute('id', elementId);
        
        Array.from(element.children).forEach(child => {
          addIdsToElement(child);
        });
      };
      
      // 处理所有元素
      Array.from(tempContainer.children).forEach(child => {
        addIdsToElement(child);
      });
      
      return tempContainer.innerHTML;
    },
    
    /**
     * 完整处理流程：清除现有ID -> 添加新的唯一ID
     * @param {string} originalHtml - 原始HTML字符串
     */
    processHtmlWithIds(originalHtml) {
      console.log("当前的所有html内容1",originalHtml)

      let processedHtml = this.addUniqueIds(originalHtml);
      console.log("添加完的富文本",processedHtml)
      return processedHtml;
    },

    // 创建XML字符串
    createXmlSt(type,saveId) {
      let desStr = this.form;
      // if(type||this.isNavEdit){
      //   desStr = this.form;
      //   this.isNavEdit = false;
      // }else{
      //   desStr = '';
      // }
      console.log("当前",this.navIsAdd)
      //  const ht3 = this.tempDivData.innerHTML;
      // console.log("3d转换之后3",ht3)
      switch (this.navIsAdd){
        case "create":
          this.tempDivData.innerHTML = '';
          break;
        case "edit":
          // this.tempDivData.innerHTML = this.tempDivData.innerHTML;
          break;
        case "other":
          // this.tempDivData.innerHTML = this.tempDivData.innerHTML;
          this.navIsAdd = 'create';
          break;
        default:
          // this.tempDivData.innerHTML = '';
          break;
      }
      // this.tempDivData.innerHTML = this.navIsAdd?"":this.tempDivData.innerHTML;
    this.tempDivData.innerHTML = this.clearNbsp(this.tempDivData.innerHTML)
  //  const ht4 = this.tempDivData.innerHTML;
  //     console.log("3d转换之后4",ht4)

    console.log("当前的所有html内容3",this.tempDivData.innerHTML)
    let newDST = this.processHtmlWithIds(this.tempDivData.innerHTML)
    
      // const ht5 = this.tempDivData.innerHTML;
      // console.log("3d转换之后5",ht5)
    console.log("结果cleanedStr 然后赋值",this.tempDivData.innerHTML)
    console.log("加ID后的",newDST)
    //去掉table里面的东西
    if(newDST){
      newDST = this.removeColgroup(newDST)
    } else{
      newDST = '';
    }
    //  const ht6 = this.tempDivData.innerHTML;
    //   console.log("3d转换之后6",ht6)


    if(this.loadFileDMC){
      newDST = this.loadFileDMC;
    }
    console.log("解析出来后的",newDST)
    const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
  <dmodule xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://www.purl.org/dc/elements/1.1/">
      <rdf:Description>
        <dc:title>`+desStr.name+`</dc:title>
        <dc:creator>`+desStr.creator+`</dc:creator>
        <dc:permission>`+desStr.permission+`</dc:permission>
        <dc:subject/>
        <dc:publisher>`+desStr.creator+`</dc:publisher>
        <dc:contributor>`+desStr.contributor+`</dc:contributor>
        <dc:version>`+desStr.version+`</dc:version>
        <dc:level>`+desStr.level+`</dc:level>
        <dc:date>`+desStr.date+`</dc:date>
        <dc:applicabilityInformation>`+desStr.applicabilityInformation+`</dc:applicabilityInformation>
        <dc:qualityVerification>`+desStr.qualityVerification+`</dc:qualityVerification>
        <dc:type>text</dc:type>
        <dc:format>text/xml</dc:format>
        <dc:identifier>`+this.getDmName+`</dc:identifier>
        <dc:language>`+desStr.language+`</dc:language>
        <dc:rights>01</dc:rights>
      </rdf:Description>
  <identAndStatusSection>
      <dmAddress>
        <dmIdent>
          <dmCode 
            modelIdentCode="EXAMPLE01" 
            systemDiffCode="A1" 
            systemCode="SYS" 
            subSystemCode="A" 
            subSubSystemCode="B" 
            assyCode="AS01" 
            disassyCode="DS" 
            disassyCodeVariant="001" 
            infoCode="INF" 
            infoCodeVariant="1" 
            itemLocationCode="A"
          />
          <language languageIsoCode="en" countryIsoCode="US"/>
          <issueInfo issueNumber="001" inWork="01"/>
        </dmIdent>
        <dmAddressItems>
          <issueDate year="2023" month="06" day="15"/>
          <dmTitle>
            <techName>Example Technical Document</techName>
          </dmTitle>
        </dmAddressItems>
      </dmAddress>
      <dmStatus>
        <security securityClassification="01"/>
        <responsiblePartnerCompany enterpriseCode="COMP001">
          <enterpriseName>Example Company</enterpriseName>
        </responsiblePartnerCompany>
        <originator>John Doe</originator>
        <brexDmRef>BREX001</brexDmRef>
        <qualityAssurance>QA passed</qualityAssurance>
      </dmStatus>
    </identAndStatusSection>
    <content>`
      +newDST+
    `</content>
  </dmodule>`
  // this.tempDivData.innerHTML
      // ${this.convertHtmlToXmlContent(this.editorContent)}
        console.log("${tempDiv.innerHTML}",this.tempDivData.innerHTML)
        console.log("${tempDiv}",this.tempDivData)
        

        let xmlData = this.fixHrTagsInContent(this.fixBrTagsInContent(this.fixImgTagsInContent(xmlString, false), false),false);  
        console.log("存储最终1",this.tempDivData)
        console.log("存储最终2",xmlString)
        console.log("存储最终3",xmlData)
        //存富文本信息

      //   const ht7 = this.tempDivData.innerHTML;
      // console.log("3d转换之后7",ht7)
      //     const ht8 = xmlData;
      // console.log("3d转换之后8",ht8)
        // xmlData = this.replacemodel3dImages(xmlData);
        if(type){
          console.log("存富文本内容时候1",type,this.nowMaxId,xmlData)
          this.$sendToDotNet('SaveFile','DMC',this.nowMaxId,xmlData,'000');
        }else{
          console.log("存富文本内容时候2",type,saveId,this.currentNode,xmlData)
          this.$sendToDotNet('SaveFile','DMC',saveId?saveId:this.currentNode.id,xmlData,this.currentNode.lagreVersion);  
          this.lastClick = this.currentNode.id; 
        }

        this.contentXmlStr = this.editor.txt.html();


        if(this.navIsAdd == 'create'){
          // this.currentNode = '';
        //   this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.nowMaxId+this.domNameStr[3]+this.domNameStr[4];
        //   console.log("新建目录以后调到新的DMC",this.getDmName)
        //   this.loadFWBFile(this.getDmName);
        }
        // this.successTips('目录保存完成')
        // 处理content标签内的img标签
        // this.xmlDownload(xmlData)
        // this.xmlDownload(this.fixImgTagsInContent(xmlString, false))
    },

     // 创建XML文件然后下载
    xmlDownload(xmlString) {
       // Create download link
        const blob = new Blob([xmlString], { type: 'text/xml' })
        const url = URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = 'document.xml'
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
        URL.revokeObjectURL(url)
    },
    // // XML文件标签剔除
    //  restoreContent(html) { 
    //    console.log("XML初始内容：",html)
    //   if (html) {
    //     const tempDiv = document.createElement('div')
    //     tempDiv.innerHTML = html
        
    //     // 处理所有dmTitle标签
    //     const dmTitles = tempDiv.querySelectorAll('dmTitle')
    //     dmTitles.forEach(dmTitle => {
    //       // 获取dmTitle的子节点
    //       const children = Array.from(dmTitle.childNodes)
          
    //       // 在dmTitle之前插入所有子节点
    //       children.forEach(child => {
    //         dmTitle.parentNode.insertBefore(child.cloneNode(true), dmTitle)
    //       })
    //       // 移除dmTitle
    //       dmTitle.parentNode.removeChild(dmTitle)
    //     })
    //     console.log('内容还原完成！dmTitle标签已被移除')
    //     console.log("tempDiv.innerHTML",tempDiv.innerHTML)
    //     this.editor.txt.html(tempDiv.innerHTML)

    //   }else{
    //     console.log("空白文档")
    //     this.editor.txt.html('')
    //   }
        // this.editor.txt.html(tempDiv.innerHTML)
    // },

  //删除视频
  deleteAllVideos() {
      const videoWrappers = document.querySelectorAll('.video-wrapper')
      if (videoWrappers.length === 0) {
        console.log('没有找到可删除的视频')
        return
      }
      
      videoWrappers.forEach(wrapper => {
        wrapper.remove()
      })
      
      // 删除可能残留的空段落
      const editor = this.$refs.editor
      const paragraphs = editor.querySelectorAll('p')
      paragraphs.forEach(p => {
        if (p.textContent.trim() === '' && p.children.length === 0) {
          p.remove()
        }
      })
      
      // 使用正确的方式通知内容变更
      if (this.editor.txt) {
        this.editor.txt.html(this.editor.txt.html()) // 强制更新编辑器内容
      }
      
      console.log(`已删除 ${videoWrappers.length} 个视频`)
    },


    
    // 加载所有内容到 main 容器
    loadAllContent() {
      const mainContainer = document.getElementById('main')
      mainContainer.innerHTML = this.editorContent;
      console.log("this.editorContent",this.editorContent)
      // 为main容器中的标题添加ID
      this.addHeadingIds(mainContainer)
    },
     

     // 为标题元素添加ID
    addHeadingIds(container) {
      const headings = container.querySelectorAll('h1, h2, h3, h4, h5, h6')
      headings.forEach((heading, index) => {
        if (!heading.id) {
          heading.id = `heading-${index}-${Date.now()}`
          console.log("Date.now",Date.now())
        }
      })
    },
    


    // 生成带锚点的目录
    generateTOC() {

      const navContainer = document.getElementById('nav')
      navContainer.innerHTML = '' // 清空原有目录
      
      // 确保main容器已加载内容
      // if (!document.getElementById('main').innerHTML) {
        this.loadAllContent()
      // }
      
      const mainContainer = document.getElementById('main')
      const headings = mainContainer.querySelectorAll('h1, h2, h3, h4, h5, h6')
      console.log("headings.length",headings.length)
      if (headings.length === 0) {
        navContainer.innerHTML = '<p>没有找到标题元素，无法生成目录。</p>'
        return
      }
      
      const tocList = document.createElement('ul')
      tocList.style.listStyleType = 'none'
      tocList.style.paddingLeft = '0'
      
      headings.forEach(heading => {
        console.log("heading",)
        const level = parseInt(heading.tagName.substring(1))
        const listItem = document.createElement('li')
        listItem.style.marginLeft = `${(level - 1) *1.2}rem`;
        listItem.style.marginBottom = '5px';
        let fontSize = '12px'
        switch(level){
          case 1:
            fontSize = '30px'
            break;
          case 2:
            fontSize = '26px'
            break;
          case 3:
            fontSize = '22px'
            break;
          case 4:
            fontSize = '18px'
            break; 
          case 5:
            fontSize = '20px'
            break; 
        }
        listItem.style.fontSize = fontSize;
        
        const link = document.createElement('a')
        link.href = `#${heading.id}`
        link.textContent = heading.textContent
        link.style.textDecoration = 'none'
        link.style.color = '#333'
        
        // 添加平滑滚动效果
        link.addEventListener('click', (e) => {
          e.preventDefault()
          document.getElementById(heading.id).scrollIntoView({
            behavior: 'smooth'
          })
        })
        
        listItem.appendChild(link)
        tocList.appendChild(listItem) 
      })
      
      const tocContainer = document.createElement('div')
      tocContainer.style.border = '1px solid #ddd'
      tocContainer.style.padding = '15px'
      tocContainer.style.marginBottom = '20px'
      tocContainer.style.background = '#f9f9f9'
      tocContainer.style.borderRadius = '4px'
      
      const tocTitle = document.createElement('h2')
      tocTitle.textContent = '目录'
      tocTitle.style.marginTop = '0'
      
      tocContainer.appendChild(tocTitle)
      tocContainer.appendChild(tocList)
      navContainer.appendChild(tocContainer)
    },

 
    // 处理所有标题元素的ID
    processHeadingIds() {
       if (!this.editor) return
      
      // 获取当前时间戳（简化版，只取后8位）
      const timestamp = Date.now().toString().slice(-8);
      let timestamps = parseInt(Date.now().toString().slice(-8));
      console.log("时间戳",timestamp,timestamps)
      // 获取编辑器内容
      const editorHtml = this.editor.txt.html()
      if (!editorHtml) return
      
      // 创建一个临时div来操作DOM
      const tempDiv = document.createElement('div')
      tempDiv.innerHTML = editorHtml
      
      // 获取所有标题元素
      const headings = tempDiv.querySelectorAll('h1, h2, h3, h4, h5, h6')
      
    
      headings.forEach((heading, index) => {
        console.log("index",index)
        // 生成3个随机字母 + 时间戳后8位
        // const newId = `heading-${randomLetters}-${timestamp}`
        const randomLetters = this.getRandomLetters(this.idLength)
        // const newId = `${heading.id}${randomLetters}${timestamps}`
        timestamps++;
        console.log("timestamp",timestamps)
        const newId = `${randomLetters}`
        if(heading.id.length<this.idLength){
          heading.id = newId
        }
        
      })
      
      // 将修改后的HTML设置回编辑器
      
      this.editor.txt.html(tempDiv.innerHTML);
      setTimeout(() => {
        this.generateTOC()
      }, 200);
    },

    // 生成随机字母
    getRandomLetter() {
      const letters = 'abcdefghijklmnopqrstuvwxyz1234567890'
      return letters.charAt(Math.floor(Math.random() * letters.length))
    },
    
    // 生成随机字母组合
    getRandomLetters(length) {
      let result = ''
      for (let i = 0; i < length; i++) {
        result += this.getRandomLetter()
      }
      return result
    },

 
    
    // XML特殊字符转义
    escapeXml(unsafe) {
      return unsafe.replace(/[<>&'"]/g, (c) => {
        switch (c) {
          case '<': return '&lt;';
          case '>': return '&gt;';
          case '&': return '&amp;';
          case '\'': return '&apos;';
          case '"': return '&quot;';
          default: return c;
        }
      });
    },
     
     
    
    // 从S1000D XML导入
    handleS1000DUpload(event) {
      const file = event.target.files[0];
      if (!file) return;
      
      const reader = new FileReader();
      reader.onload = (e) => {
        const xmlString = e.target.result;
        const html = this.extractContentFromS1000D(xmlString);
        

        // const parser = new DOMParser();
        // const xmlDoc = parser.parseFromString(html, 'text/xml');
        
        // 获取 content 元素
        const contentElement = html.querySelector('content');
        
        console.log("contentElement",contentElement)
      if (contentElement) {
          // 提取 content 内部的所有子节点并转换为字符串
          let innerHtml = '';
          Array.from(contentElement.childNodes).forEach(node => {
            innerHtml += new XMLSerializer().serializeToString(node);
          });
          console.log("innerHtml",innerHtml)
          this.editor.txt.html(innerHtml)
        } 
        // 重置input值，允许重复选择同一文件
        event.target.value = '';
      };
      reader.readAsText(file);
    },
    
    // 从S1000D XML提取内容
    extractContentFromS1000D(xmlString) {
      try {
        // 简单提取description内容
        const descriptionMatch = xmlString.match(/<description>([\s\S]*?)<\/description>/i);
        if (!descriptionMatch || !descriptionMatch[1]) {
          throw new Error('未找到description内容');
        }
        
        // 反转义XML特殊字符
        let content = descriptionMatch[1]
          .replace(/&lt;/g, '<')
          .replace(/&gt;/g, '>')
          .replace(/&amp;/g, '&')
          .replace(/&apos;/g, "'")
          .replace(/&quot;/g, '"');
        
        // 移除可能的多余空格和换行
        content = content.trim();
        
        return content;
      } catch (e) {
        console.error('S1000D导入错误:', e);
        alert(`导入S1000D XML失败: ${e.message}`);
        return '';
      }
    },

    rgbToHex(r, g, b) {//色号转换
      console.log("colors",this.colors)
      return `#${[r, g, b].map(x => x.toString(16).padStart(2, '0')).join('')}`;
    }, 
     

    //保存内容到XML
    generateXml(type,saveId) {
      this.dataXmlProcessing(type,saveId); 
    },
    //测试 保存目录到XML
    navXml() {
      const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<dmodule xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <identAndStatusSection>
    <dmAddress>
      <dmIdent>
        <dmCode 
          modelIdentCode="EXAMPLE01" 
          systemDiffCode="A1" 
          systemCode="SYS" 
          subSystemCode="A" 
          subSubSystemCode="B" 
          assyCode="AS01" 
          disassyCode="DS" 
          disassyCodeVariant="001" 
          infoCode="INF" 
          infoCodeVariant="1" 
          itemLocationCode="A"
        />
        <language languageIsoCode="en" countryIsoCode="US"/>
        <issueInfo issueNumber="001" inWork="01"/>
      </dmIdent>
      <dmAddressItems>
        <issueDate year="2023" month="06" day="15"/>
        <dmTitle>
          <techName>Example Technical Document</techName>
        </dmTitle>
      </dmAddressItems>
    </dmAddress>
    <dmStatus>
      <security securityClassification="01"/>
      <responsiblePartnerCompany enterpriseCode="COMP001">
        <enterpriseName>Example Company</enterpriseName>
      </responsiblePartnerCompany>
      <originator>John Doe</originator>
      <brexDmRef>BREX001</brexDmRef>
      <qualityAssurance>QA passed</qualityAssurance>
    </dmStatus>
  </identAndStatusSection>
  <content><infoCode>`
    +JSON.stringify(this.treeData)+
  `</infoCode></content>
</dmodule>`;


    const blob = new Blob([xmlString], { type: 'text/xml' })
        const url = URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = 'mulu.xml'
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
        URL.revokeObjectURL(url)

    },
     
     //测试 加载XML
    loadXml() {
      this.$refs.fileInput.click()
    },

    //测试 选择文件
    handleFileUpload(event) {
      const file = event.target.files[0]
      if (!file) return
      
      const reader = new FileReader()
      reader.onload = (e) => {
        const xmlContent = e.target.result
        // console.log("xmlContent",xmlContent)
        const parser = new DOMParser()
        const xmlDoc = parser.parseFromString(xmlContent, "text/xml")
        console.log("xmlDoc",xmlDoc)
        const contentNodes = xmlDoc.getElementsByTagName('content')[0];
        console.log("xmlDoc.getElementsByTagName('content')",xmlDoc.getElementsByTagName('content'))
        console.log("contentNodes",contentNodes)
        
        if (contentNodes) {
          const htmlContent = this.convertXmlContentToHtml(contentNodes.innerHTML)
          // this.editor.txt.html(htmlContent)
          //处理过后再导入
          // this.restoreContent(htmlContent)
          this.restoreContentXh(htmlContent)
        }
      }
      reader.readAsText(file)
    },

    completeModel3DTags(htmlString) {
      // 处理自闭合的model3d标签，替换为完整的闭合标签
      return htmlString.replace(/<model3d([^>]*?)\/>/g, (match, attributes) => {
        // 返回带有相同属性的完整闭合标签
        return `<model3d${attributes}></model3d>`;
      });
    },
    
    // 解析xml里面 content内容
    convertXmlContentToHtml(xmlContent) {
      
      return xmlContent
        .replace(/<para>/g, '<p>')
        .replace(/<\/para>/g, '</p>')
        .replace(/<emphasis emphasisType="bold">/g, '<strong>')
        .replace(/<\/emphasis>/g, '</strong>')
        .replace(/<emphasis emphasisType="italic">/g, '<em>')
    },

    /**
     * 修复content标签内的img标签闭合符
     * @param {string} inputStr 输入HTML
     * @param {boolean} useSlash 是否使用自闭合
     * @returns {string} 修正后的HTML
     */
    fixImgTagsInContent(inputStr, useSlash) {
      const contentRegex = /<content>([\s\S]*?)<\/content>/g
      
      return inputStr.replace(contentRegex, (contentMatch, innerContent) => {
        const fixedInnerContent = innerContent.replace(
          /<img\b([^>]*)>/g, 
          (imgMatch, imgAttributes) => {
            // 已有闭合符则不处理
            if (imgMatch.endsWith('/>') || imgMatch.includes('</img>')) {
              return imgMatch
            }
            // 根据参数决定闭合方式
            return useSlash 
              ? `<img${imgAttributes} />` 
              : `<img${imgAttributes}></img>`
          }
        )
        return `<content>${fixedInnerContent}</content>`
      })
    },

    // 检测hr标签是否闭合
    fixHrTagsInContent(inputStr, useSlash) {
      const contentRegex = /<content>([\s\S]*?)<\/content>/g
      
      return inputStr.replace(contentRegex, (contentMatch, innerContent) => {
        const fixedInnerContent = innerContent.replace(
          /<hr\b([^>]*)>/g, 
          (imgMatch) => {
            // 已有闭合符则不处理
            if (imgMatch.endsWith('/>') || imgMatch.includes('</hr>')) {
              return imgMatch
            }
            // 根据参数决定闭合方式
            return useSlash 
              ? `<hr/>` 
              : `<hr></hr>`
          }
        )
        return `<content>${fixedInnerContent}</content>`
      })
    },

    // 检测br标签是否闭合
    fixBrTagsInContent(inputStr, useSlash) {
      const contentRegex = /<content>([\s\S]*?)<\/content>/g
      
      return inputStr.replace(contentRegex, (contentMatch, innerContent) => {
        const fixedInnerContent = innerContent.replace(
          /<br\b([^>]*)>/g, 
          (imgMatch, imgAttributes) => {
            // 已有闭合符则不处理
            if (imgMatch.endsWith('/>') || imgMatch.includes('</br>')) {
              return imgMatch
            }
            // 根据参数决定闭合方式
            return useSlash 
              ? `<br${imgAttributes} />` 
              : `<br${imgAttributes}></br>`
          }
        )
        return `<content>${fixedInnerContent}</content>`
      })
    },




       //富文本内容打标签
    dataXmlProcessing(type,saveId) { 
        let html_1 = '';
        let html = '';
        if(this.editor){
          html = this.editor.txt.html()
          console.log('保存内容',html);
          // 正则表达式：匹配img、audio、video标签的src属性
          // 支持三种标签：<img ...>、<audio ...>、<video ...>
          // 捕获组1: 标签名和src="之前的部分
          // 捕获组2: 提取文件名（最后一个/后面的内容）
          // 捕获组3: 保留"及之后的部分
          const reg = /(<(img|audio|video)[^>]+src=")[^"]+\/([^"]+)("[^>]*>)/gi;
          
          // 替换为：src="文件名"
          html_1 = html.replace(reg, '$1$3$4');
          console.log('解析地址：',html_1)
        }
        

        // const reg2 = /(<(img|audio|video)[^>]+src=")(?!http:\/\/)([^"]+)("[^>]*>)/gi;
        // let jc = 'http://localhost:5432/';
        // // 替换为：src="基础URL+文件名"
        // // 这里假设原路径可能包含DM_Material目录，如果不需要可以去掉
        // let html_2 = html_1.replace(reg2, `$1${jc}$3$4`);
        // console.log('还原地址：',html_2)
        this.tempDivData = document.createElement('div')
        html_1 = this.replacemodel3dImages(html_1);
        // const ht1 = html_1;
        // console.log("3d转换之后1",ht1)
        this.tempDivData.innerHTML = html_1;
        
        this.xh(this.oldSelector,this.newSelector,type,saveId);
    },
     
  countDomNodes() {
      // 重置计数
      this.domCount = 0
      this.elementCount = 0
      this.textCount = 0
      this.commentCount = 0

      // 这里可以改为你需要统计的容器选择器
      // 例如: '#editor' 或 '.tree-container' 或 'body'
      const targetSelector = '#editor'
      const container = document.querySelector(targetSelector)
      
      if (!container) {
        this.$message.error('未找到目标容器')
        return
      }

      this.countTarget = targetSelector
      // 递归统计所有节点
      this.traverseNodes(container)
      // 显示结果弹窗
      this.countDialogVisible = true
    },

    // 递归遍历节点并计数
    traverseNodes(node) {
      if (!node) return

      // 总节点数+1
      this.domCount++

      // 分类计数
      switch(node.nodeType) {
        case 1: // 元素节点
          this.elementCount++
          break
        case 3: // 文本节点
          // 过滤空白文本节点
          if (node.textContent.trim()) {
            this.textCount++
          }
          break
        case 8: // 注释节点
          this.commentCount++
          break
      }

      // 递归处理子节点
      if (node.childNodes && node.childNodes.length) {
        Array.from(node.childNodes).forEach(child => {
          this.traverseNodes(child)
        })
      }
    },
     // XML文件标签剔除
     restoreContentXh(html) { 
      //  console.log("XML初始内容：",html)
      if (html) {
        this.tempDivData = document.createElement('div')
        this.tempDivData.innerHTML = html
        
        let times = this.oldSelector.length;

        for(let i =0;i<times;i++){
           // 处理所有dmTitle标签
          const dmTitles = this.tempDivData.querySelectorAll(this.newSelector[i])
          dmTitles.forEach(dmTitle => {
            // 获取dmTitle的子节点
            const children = Array.from(dmTitle.childNodes)
            // console.log("剔除标签:",dmTitles,children)
            
            // 在dmTitle之前插入所有子节点
            children.forEach(child => {
              dmTitle.parentNode.insertBefore(child.cloneNode(true), dmTitle)
            })
            // 移除dmTitle
            dmTitle.parentNode.removeChild(dmTitle)
              // console.log("剔除标签移除:",dmTitle,'替换成',dmTitle)

          })
        }
        console.log('内容还原完成！dmTitle标签已被移除')
        // console.log("tempDiv.innerHTML",this.tempDivData.innerHTML)
        
        
        const reg2 = /(<(img|audio|video)[^>]+src=")(?!http:\/\/)([^"]+)("[^>]*>)/gi;
        let jc = this.lisenPath; 
        // 检查并去除开头的双引号
        if (jc.startsWith('"')) {
          jc = jc.substring(1);
        } 
        // 检查并去除结尾的双引号
        if (jc.endsWith('"')) {
          jc = jc.substring(0, jc.length - 1);
        } 
        
        // 替换为：src="基础URL+文件名"
        // 这里假设原路径可能包含DM_Material目录，如果不需要可以去掉
        let html_2 = this.tempDivData.innerHTML.replace(reg2, `$1${jc}$3$4`);
      //  html_2 = this.modelToImg(html_2);
       
      //  console.log('还原地址：',html_2) 
        this.editor.txt.html(html_2)
        this.contentXmlStr = this.editor.txt.html();
      }else{
        console.log("空白文档")
        this.editor.txt.html('')
        this.contentXmlStr = this.editor.txt.html();
      }
    },







    // XML文件标签剔除
     restoreContentXh2(html) { 
      //  console.log("XML初始内容：",html)
      if (html) {
        this.tempDivData1 = document.createElement('div')
        this.tempDivData1.innerHTML = html
        
        let times = this.oldSelector.length;

        for(let i =0;i<times;i++){
           // 处理所有dmTitle标签
          const dmTitles = this.tempDivData1.querySelectorAll(this.newSelector[i])
          dmTitles.forEach(dmTitle => {
            // 获取dmTitle的子节点
            const children = Array.from(dmTitle.childNodes)
            // console.log("剔除标签:",dmTitles,children)
            
            // 在dmTitle之前插入所有子节点
            children.forEach(child => {
              dmTitle.parentNode.insertBefore(child.cloneNode(true), dmTitle)
            })
            // 移除dmTitle
            dmTitle.parentNode.removeChild(dmTitle)
              // console.log("剔除标签移除:",dmTitle,'替换成',dmTitle)

          })
        }
        console.log('内容还原完成！dmTitle标签已被移除')
        // console.log("tempDiv.innerHTML",this.tempDivData1.innerHTML)
        
        
        const reg2 = /(<(model3d|img|audio|video)[^>]+src=")(?!http:\/\/)([^"]+)("[^>]*>)/gi;
        let jc = this.viewLis; 
        // 检查并去除开头的双引号
        if (jc.startsWith('"')) {
          jc = jc.substring(1);
        } 
        // 检查并去除结尾的双引号
        if (jc.endsWith('"')) {
          jc = jc.substring(0, jc.length - 1);
        } 
        if(!this.dialogVisibleNav){
          jc = jc+this.historyVsPath+'/';
        }
        // 替换为：src="基础URL+文件名"
        // 这里假设原路径可能包含DM_Material目录，如果不需要可以去掉
        let html_2 = this.tempDivData1.innerHTML.replace(reg2, `$1${jc}$3$4`);
      //  html_2 = this.modelToImg(html_2);
      //  console.log("大豪科技等哈时间",this.viewLis)
      //  console.log('加载还原地址：',html_2)  

      let processedL = this.hintFun(html_2)

       this.neirong = this.modelToImg(processedL);


      //  document.getElementsByClassName("loadContent")[0].innerHTML=html_2;
      //  document.getElementsByClassName("loadContent1")[0].innerHTML=html_2;
      //  console.log('加载还原地址：',html_3) 
        // this.editor.txt.html(html_2)
        // this.contentXmlStr = this.editor.txt.html();
      }else{
        console.log("空白文档")
        // this.editor.txt.html('')
        // this.contentXmlStr = this.editor.txt.html();
      }
    },


    hintFun(html_2) {

      let html = html_2;

 // 先定义所有需要用到的变量，确保初始化顺序
      // 需要移除的class
      // const classesToRemove = ['borderStyle_yellow', 'borderStyle_red'];
      
      // // 处理class属性 - 先替换指定class
      // html = html.replace(/class="([^"]*)"/g, (match, classValues) => {
      //   let newClassValues = classValues;
        
      //   // 在替换函数内部定义class映射，确保在使用前初始化
      //   const classMappings = {
      //     'teshu': 'testBo',
      //     'teshu2': 'testBo2'
      //   };
        
      //   // 替换class
      //   Object.keys(classMappings).forEach(oldClass => {
      //     const newClass = classMappings[oldClass];
      //     const regex = new RegExp(`\\b${oldClass}\\b`, 'g');
      //     newClassValues = newClassValues.replace(regex, newClass);
      //   });
        
      //   // 移除不需要的class
      //   classesToRemove.forEach(classToRemove => {
      //     const regex = new RegExp(`\\b${classToRemove}\\b\\s*`, 'g');
      //     newClassValues = newClassValues.replace(regex, '').trim();
      //   });
        
      //   return `class="${newClassValues}"`;
      // });
      
      // 定义需要替换的class映射关系
      const classMappings = {
        'teshu': 'testBo',
        'teshu2': 'testBo2'
      };
      
      // 使用正则表达式匹配class属性并替换相应的值
      // 这个正则表达式会匹配class属性中的各个class名称
      html = html.replace(/class="([^"]*)"/g, (match, classValues) => {
        let newClassValues = classValues;
        
        // 遍历替换映射，替换每个需要替换的class
        Object.keys(classMappings).forEach(oldClass => {
          const newClass = classMappings[oldClass];
          // 使用单词边界确保只替换完整的class名称
          const regex = new RegExp(`\\b${oldClass}\\b`, 'g');
          newClassValues = newClassValues.replace(regex, newClass);
        });
        
        return `class="${newClassValues}"`;
      });


       const regex = /(<div\s+[^>]*class="[^"]*(testBo2|testBo)[^"]*"[^>]*>)(.*?)(<\/div>)/gis;
      
      html = html.replace(regex, (match, startTag, className, content, endTag) => {
        // 验证捕获的className
        console.log('捕获的class名称:', className);
        
        // 定义不同class对应的边框样式
        let borderStyle;
        if (className === 'testBo2') {
          borderStyle = '3px solid #ffcc00'; // testBo的边框样式(深黄色)
        } else if (className === 'testBo') {
          borderStyle = '3px solid red'; // testBo2的边框样式(红色)
        }
        
        // 包裹div的完整样式
        const wrapperStyle = `background:#fff;padding: 10px;border: ${borderStyle};border-radius: 8px;`;
        // 包裹内容
        const wrappedContent = `<div style='${wrapperStyle}'>${content}</div>`;
        // 返回处理后的标签
        return `${startTag}${wrappedContent}${endTag}`;
      });


           

      return html;
  //      const regex = /\s*class\s*=\s*"teshu"\s*/gi;
  //      const regex2 = /\s*class\s*=\s*"teshu2"\s*/gi;
      
  //       // 将匹配到的class替换为class="testBo"
  //       const styleRegex = /(<div[^>]*?)style\s*=\s*"[^"]*?"\s*([^>]*?class\s*=\s*"teshu"[^>]*?>)/gi;
  //       html_2 = html_2.replace(styleRegex, '$1$2');
  //       const styleRegex2 = /(<div[^>]*?)style\s*=\s*"[^"]*?"\s*([^>]*?class\s*=\s*"teshu2"[^>]*?>)/gi;
  //       html_2 = html_2.replace(styleRegex2, '$1$2');
  //       let html_3 = html_2.replace(regex, ' class="testBo"');
  //       let html_4 = html_3.replace(regex2, ' class="testBo2"');
  //         // let html_4 = html_3;
  //         // 正则表达式匹配class="testBo"的div标签
  //         // 匹配模式：<div class="testBo"[属性...]>内容</div>
  //         const regex1 = /(<div\s+class="testBo"[^>]*>)(.*?)(<\/div>)/gi;
  //         const regex22 = /(<div\s+class="testBo2"[^>]*>)(.*?)(<\/div>)/gi;
          
  //         // 替换匹配到的内容
  //         // 在原内容外层包裹<div style='background:#fff'>...</div>
  //         let processed = html_4.replace(regex22, (match, startTag, content, endTag) => {
  //           return `${startTag}<div style='background:#fff;padding: 10px;
  //     border: 3px solid #000;
  //     border-radius: 8px;
  // '>${content}</div>${endTag}`;
  //         });
  // console.log("预览数据processed",processed)
  //     let processedL = processed.replace(regex1, (match, startTag, content, endTag) => {
  //               return `${startTag}<div style='background:#fff;padding: 10px;
  //         border: 3px solid #000;
  //         border-radius: 8px;
  //     '>${content}</div>${endTag}`;
  //             });
  // console.log("预览数据processedL",processedL)

  //     return processedL
    },





    //处理 3d模型标签
    replaceModel3dToImg(htmlString) {
        // 创建临时DOM元素处理HTML
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = htmlString;
        
        // 查找所有model3d标签
        const model3dElements = tempDiv.querySelectorAll('model3d');
        
        model3dElements.forEach(model3d => {
          // 创建新的img元素
          const img = document.createElement('img');
          
          // 复制所有属性
          Array.from(model3d.attributes).forEach(attr => {
            img.setAttribute(attr.name, attr.value);
          });
          
          // 替换元素
          model3d.parentNode.replaceChild(img, model3d);
        });
        
        return tempDiv.innerHTML;
      },
      //判断富文本内容是否更改
    dmcIsChange() {
      if(this.editor){//初始化时候
        console.log("this.editor.txt.html()",this.editor.txt.html())
        console.log("this.contentXmlStr",this.contentXmlStr)
        console.log("验证结果",this.editor.txt.html() == this.contentXmlStr)
        return this.editor.txt.html() == this.contentXmlStr;
      }else{
        return true
      }
    },
    

    //测试 启用右键功能
    enableContextMenu() {
        console.log("进入isContextMenuEnabled",this.isContextMenuEnabled)
      if (this.isContextMenuEnabled) return;
      
      this.isContextMenuEnabled = true;
      
      // 获取#nav下的所有li元素
      const tocItems = document.querySelectorAll('.elTree .el-tree-node__content');
      
      // 为每个li元素绑定右键事件
      tocItems.forEach((item, index) => {
        // 为元素设置唯一ID
        const elementId = `toc-item-${index}`;
        item.id = elementId;
        
        // 初始化参数存储
        if (!this.itemParams[elementId]) {
          this.$set(this.itemParams, elementId, '');
        }
        
        item.addEventListener('contextmenu', (e) => {
          e.preventDefault();
          this.showContextMenu(e, item);
        });

        item.addEventListener('click', (e) => {
          console.log("左键",e,item)
          this.dialogVisible = true;
        });
      });
      
      // alert('右键菜单功能已启用！');
    },
    
    //测试 显示右键菜单
    showContextMenu(e, element) {
      console.log("ID",element)

      // 获取该 <a> 元素
      // const linkElement = element.querySelector('#toc-item-0 a');
      // 提取 # 后面的参数
      // const hashValue = linkElement.getAttribute('href');
      // const hashValue2 = hashValue.split('#')[1];
     
      // console.log(hashValue,hashValue2); 
      if (!this.isContextMenuEnabled) return;
      
      // 设置右键菜单位置和当前选中元素
      this.contextMenu = {
        visible: true,
        x: e.clientX,
        y: e.clientY,
        selectedElement: element,
        selectedParam: this.itemParams[element.id] || ''
      }
      
      // 点击其他地方关闭菜单
      document.addEventListener('click', this.closeContextMenu, { once: true });
    },
    //测试 关闭右键菜单
    closeContextMenu() {
      this.contextMenu.visible = false;
    },
    //测试 选择右键菜单选项
    selectMenuOption(option) {
      if (this.contextMenu.selectedElement) {
        const element = this.contextMenu.selectedElement;
        
        // 更新元素的参数
        this.$set(this.itemParams, element.id, option);
        
        // 在元素上显示参数（可选）
        const paramSpan = element.querySelector('.param-display');
        if (paramSpan) {
          paramSpan.textContent = `(${option})`;
        } else {
          const span = document.createElement('span');
          span.className = 'param-display';
          span.style.cssText = 'color: #f00; margin-left: 10px;';
          span.textContent = `(${option})`;
          element.appendChild(span);
        }
        
        this.closeContextMenu();
      }
    },
     // 新增方法：打印nav内容
    logTocItems() {
      const navElement = document.getElementById('nav');
      if (!navElement) {
        console.error('未找到ID为"nav"的容器');
        return;
      }
      
      // 获取nav内的HTML内容
      const navHtml = navElement.innerHTML;
      
      // 获取nav内的文本内容
      const navText = navElement.innerText || navElement.textContent;
      
      // 获取结构化数据（包括参数）
      const structuredData = this.getStructuredNavData();
      
      console.log('====== nav的HTML内容 ======');
      console.log(navHtml);
      
      console.log('====== nav的文本内容 ======');
      console.log(navText);
      
      console.log('====== nav的结构化数据 ======');
      console.log(structuredData);
      
    },
    
    // 获取结构化数据
    getStructuredNavData() {
      const items = document.querySelectorAll('#nav ul li');
      return Array.from(items).map(item => {
        return {
          id: item.id,
          text: item.innerText.trim(),
          html: item.innerHTML,
          param: this.itemParams[item.id] || '未设置'
        };
      });
    }, 
    //测试 查看图片
    openDialog() {
      // this.imageStyle();
      const imgItems = document.querySelectorAll('#main img');
      console.log("imgItems",imgItems)
      imgItems.forEach((item, index) => { 
        item.addEventListener('click', (e) => {
          console.log("左键",e,item,index,item.src)
          // 通过选择器获取
          // let imgSrc = e.src;
          this.scale = 1;
          this.rotation = 0;
          this.currentImage = item.src;
          this.dialogVisibleImg = true;
        });
      });

      // this.currentImage = this.images[index]
      // this.dialogVisible = true
      // this.reset() // 每次打开重置状态
    },
    //测试 放大
    zoomIn() {
      console.log("放大")
      this.scale = 1.1*this.scale
    },
    //测试 缩小
    zoomOut() {
      if (this.scale > 0.5) {
        this.scale -= 0.2
      }
    },
    //测试 旋转
    rotate() {
      this.rotation += 90
    },
    //测试 重置
    reset() {
      this.scale = 1
      this.rotation = 0
      this.translateX = 0
      this.translateY = 0
    },
    //测试 开始拖动
  startDrag(e) {
      this.isDragging = true;
      const startX = e.clientX;
      const startWidth = this.leftWidth;
      
      const handleMouseMove = (e) => {
        if (!this.isDragging) return;
        const diffX = e.clientX - startX;
        // 限制最小宽度
        const newWidth = Math.max(100, startWidth + diffX);
        // 限制最大宽度
        this.leftWidth = Math.min(500, newWidth);
        this.getWindowSize();
      };
      
      const handleMouseUp = () => {
        this.isDragging = false;
        document.removeEventListener('mousemove', handleMouseMove);
        document.removeEventListener('mouseup', handleMouseUp);
      };
      
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      e.preventDefault();
    },
    //测试 拖动图片
    dragImage(e) {
      if (!this.isDragging) return
      
      const clientX = e.type === 'mousemove' ? e.clientX : e.touches[0].clientX
      const clientY = e.type === 'mousemove' ? e.clientY : e.touches[0].clientY
      
      this.translateX += (clientX - this.startX) / this.scale
      this.translateY += (clientY - this.startY) / this.scale
      
      this.startX = clientX
      this.startY = clientY
    },
    //测试 停止拖动
    endDrag() {
      this.isDragging = false
      document.removeEventListener('mousemove', this.dragImage)
      document.removeEventListener('touchmove', this.dragImage)
      document.removeEventListener('mouseup', this.endDrag)
      document.removeEventListener('touchend', this.endDrag)
    },
    //测试 图片样式
    imageStyle() {
      
      return {
        transform: `
          scale(${this.scale}) 
          rotate(${this.rotation}deg)
          translate(${this.translateX}px, ${this.translateY}px)
        `,
        cursor: this.isDragging ? 'grabbing' : 'grab'
      }
    },  
    //获取屏幕尺寸
    getWindowSize() {
      // this.windowW = window.innerWidth
      // this.windowH = window.innerHeigh
      // t
      //  this.leftHeight = window.innerHeight - 200;
      //  this.editorHeight = window.innerHeight - 250;

      if(this.currentNode){
      const element = document.querySelector('.w-e-toolbar')
       const container = document.querySelector('.w-e-text-container');
       const rightDivHeight = document.querySelector(".rightDiv").scrollHeight;
       container.style.height = (rightDivHeight -element.scrollHeight - 80 ) +'px' ;
       console.log("内容高度2", (rightDivHeight -element.scrollHeight - 80 ) +'px')
      }



      this.windowH = window.innerHeight;
      this.leftHeight = window.innerHeight - 200; // 检查此值是否合理
      this.editorHeight = window.innerHeight - 250;
      
      // 强制刷新滚动条
      this.$nextTick(() => {
        const scrollbar = this.$refs.scrollbar; // 需给 el-scrollbar 添加 ref="scrollbar"
        if (scrollbar) scrollbar.update();
      });
    },
    // 尺寸变化时的处理函数
    handleResize() {
      // 使用节流优化性能（频繁触发时限制执行频率）
      if (this.resizeTimer) clearTimeout(this.resizeTimer)
      this.resizeTimer = setTimeout(() => {
        this.getWindowSize()
        console.log('窗口尺寸变化:', this.windowW, this.windowH)
        // 在这里可以添加尺寸变化后的业务逻辑
        // 例如：调整组件布局、重新计算元素位置等
      }, 100) // 100ms 节流延迟，可根据需求调整
    },


  // 加载XML文件 dmc
  loadFileBtn() {
    this.$sendToDotNet('GetExistenceDMContent')
  },
  // 获取屏幕和窗口尺寸
    getScreenSize() {
      // 屏幕整体尺寸（设备的屏幕尺寸）
      this.screenWidth = window.screen.width;
      this.screenHeight = window.screen.height;
      
      // 浏览器窗口尺寸（可视区域尺寸）
      this.windowW = window.innerWidth;
      this.windowH = window.innerHeight;
      console.log("屏幕变化的尺寸",window.screen.width,window.screen.height,window.innerWidth,window.innerHeight)
      // 可以在这里添加需要根据尺寸执行的逻辑
      this.handleSizeChange();
    },
    
    // 处理窗口大小变化（使用防抖优化性能）
    // handleResize() {
    //   // 清除之前的定时器
    //   if (this.resizeTimer) {
    //     clearTimeout(this.resizeTimer);
    //   }
      
    //   // 防抖：50ms后再执行，避免频繁触发
    //   this.resizeTimer = setTimeout(() => {
    //     this.getScreenSize();
    //     this.resizeTimer = null;
    //   }, 50);
    // },
    
    // 根据尺寸变化执行的逻辑
    handleSizeChange() {
      // 这里可以添加尺寸变化时需要执行的操作
      console.log('尺寸变化:', {
        screenWidth: this.screenWidth,
        screenHeight: this.screenHeight,
        windowWidth: this.windowW,
        windowHeight: this.windowH
      });
    },











  //预览加载的XML
  viewLoadDMFile() {
    this.maskViewShow = true;
    // this.draggableVis = true;
    // localStorage.setItem("fileName",'dassad')
    this.$sendToDotNet('DMPreview','UserLocalDMPreview')
  },
  //解析加载的DMC
  parseXmlDmc() {
      try {
        // 解析XML字符串
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(this.loadFileXML, "text/xml");
        
        // 检查解析错误
        const errorNode = xmlDoc.querySelector("parsererror");
        if (errorNode) {
          throw new Error("XML解析错误: " + errorNode.textContent);
        }
        
        // 提取content标签内容
        this.extractContent(xmlDoc);
        
        // 解析rdf:Description
        this.parseRdfDescription(xmlDoc);
      } catch (error) {
        console.error("解析失败:", error);
        // alert("解析XML失败: " + error.message);
      }
    },

    //解析新建目录时候的DMC文件
     parseXmlDmc_loadFile() {
      try {
        // 解析XML字符串
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(this.viewXml, "text/xml");
        console.log("得到的1",xmlDoc)
        
        // 检查解析错误
        const errorNode = xmlDoc.querySelector("parsererror");
        console.log("得到的2",errorNode)

        if (errorNode) {
          throw new Error("XML解析错误: " + errorNode.textContent);
        }
        // 提取content标签内容
        this.extractContent2(xmlDoc);
        
      } catch (error) {
        console.error("解析失败:", error);
        // alert("解析XML失败: " + error.message);
      }
    },
















    //验证是否修改过的dmc文件
    handleCheckVersion() {
        this.showModifyBtn = true;
      // 可选：若需高亮有01版本的节点，可在此处触发树重渲染
      this.$nextTick(() => {
        this.$refs.tree.updateKeyChildren(); // 强制树更新节点
      });
    },


    // 3. 递归判断：当前节点或其所有子节点是否存在minorVersion: '01'
    hasMinorVersion01(node) {
      // 边界条件：节点不存在则返回false
      if (!node) return false;
      
      // 第一步：检查当前节点是否为01版本
      if (node.minorVersion === '01') {
        return true;
      }

      // 第二步：若有子节点，递归检查所有子节点
      if (node.children && node.children.length > 0) {
        // 只要有一个子节点满足，就返回true
        return node.children.some(child => this.hasMinorVersion01(child));
      }

      // 第三步：无子孙节点且当前节点不是01版本，返回false
      return false;
    },
     // 4. 【修改】文字点击事件（可根据需求扩展修改逻辑）
    handleModify(node) {
      console.log('当前需要修改的节点：', node);
      // 示例：可打开修改弹窗、跳转修改页面等
      // this.$emit('openModifyDialog', node);
    },

 
    // 提取content标签内的内容
    extractContent(xmlDoc) {
      const contentNodes = xmlDoc.getElementsByTagName("content");
      if (contentNodes.length === 0) {
        this.contentResult = "未找到content标签";
        return;
      }
      
      const contentNode = contentNodes[0];
      let contentHtml = "";
      
      // 序列化content节点的所有子节点
      for (let i = 0; i < contentNode.childNodes.length; i++) {
        const child = contentNode.childNodes[i];
        // 忽略空文本节点
        if (child.nodeType === 1 || (child.nodeType === 3 && child.textContent.trim())) {
          contentHtml += new XMLSerializer().serializeToString(child);
        }
      }
      this.loadFileDMC = contentHtml.trim();
      console.log("解析出来DMC内容",contentHtml)
      console.log("解析出来DMC内容",contentHtml.trim())
      // this.contentResult = contentHtml.trim();
    },


    // 提取新建目录时候的DMC文件中content标签内的内容
    extractContent2(xmlDoc) {
      const contentNodes = xmlDoc.getElementsByTagName("content");
      if (contentNodes.length === 0) {
        this.contentResult = "未找到content标签";
        return;
      }
      
      const contentNode = contentNodes[0];
      let contentHtml = "";
      
      // 序列化content节点的所有子节点
      for (let i = 0; i < contentNode.childNodes.length; i++) {
        const child = contentNode.childNodes[i];
        // 忽略空文本节点
        if (child.nodeType === 1 || (child.nodeType === 3 && child.textContent.trim())) {
          contentHtml += new XMLSerializer().serializeToString(child);
        }
      }
      // this.viewXmlContent = contentHtml.trim();
      console.log("加载解析出来DMC内容",contentHtml)
      console.log("加载解析出来DMC内容",contentHtml.trim())

      this.restoreContentXh2(contentHtml.trim())
      // this.contentResult = contentHtml.trim();
    },
    
    // 解析rdf:Description为对象
    parseRdfDescription(xmlDoc) {
      const rdfObj = {};
      const rdfNamespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
      const rdfNode = xmlDoc.getElementsByTagNameNS(rdfNamespace, "Description")[0];
      
      if (!rdfNode) {
        // this.rdfResult = { error: "未找到rdf:Description标签" };
        return;
      }
      
      // 解析dc命名空间下的所有子节点
      const dcNamespace = "http://www.purl.org/dc/elements/1.1/";
      const dcNodes = rdfNode.getElementsByTagNameNS(dcNamespace, "*");
      
      Array.from(dcNodes).forEach(node => {
        const key = node.localName; // 获取不带命名空间前缀的标签名
        const value = node.textContent.trim() || ""; // 处理空标签
        rdfObj[key] = value;
      });
      console.log("解析出来DMC目录内容",rdfObj)
      // this.rdfResult = rdfObj;
      for(let key in this.form){
        this.form[key] = rdfObj[key]?rdfObj[key]:'';
      }
      this.form.name = rdfObj.title;
      this.form.version = '000';
    },
  //转换时间值
  timeChange(isoTime){
    const date = new Date(isoTime);

    // 3. 提取时间组件（注意：月份从 0 开始，需 +1；数字不足 2 位时补 0）
    const year = date.getFullYear(); // 年份：2025
    const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份：09（getMonth() 返回 8，+1 后补 0）
    const day = String(date.getDate()).padStart(2, "0"); // 日期：01
    const hours = String(date.getHours()).padStart(2, "0"); // 小时：16（24小时制）
    const minutes = String(date.getMinutes()).padStart(2, "0"); // 分钟：39
    const seconds = String(date.getSeconds()).padStart(2, "0"); // 秒：07

    // 4. 拼接成正常时间格式
    const normalTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
    return normalTime;
  },
  // 关闭预览弹窗
  handleCloseMask() {
    this.maskViewShow = false;
  },
  // 关闭修改书名弹窗
  handleCloseEditBookName() {
    this.getBookName = this.getBookNameDf;
    this.editBookNameDialog = false;
  },
    //关闭弹窗节点
    handleClose(type) {
      this.loadFileDMC = '';
      console.log('点',type);
      this.dialogVisibleHistory = false;
      this.dialogVisibleNav = false;
      this.dialogVisibleRight = false;
      this.dialogVisibleTips = false;
      this.dialogVisibleTips2 = false;
      this.dialogVisibleBland = false;
      this.dialogVisibleBland = false;
      this.currentNode = null;
      this.clearNodeState();
    },
    handleClose2() {
      this.dialogVisibleHistory = false;
      this.dialogVisibleNav = false;
      this.dialogVisibleRight = false;
      this.dialogVisibleTips = false;
      this.dialogVisibleTips2 = false;
      this.dialogVisibleBland = false;
      this.dialogVisibleBland = false;
    },
    //测试 保存当前目录信息
    saveNowDmcClick() {
        const targetNode = this.findNodeById(this.treeData,this.currentNode.id);
        targetNode.minorVersion = '01';
        const aaa = this.editor.txt.html();
        console.log("当前的所有html内容4",aaa)

        this.catalogueAnalysis(this.treeData);
        this.generateXml(false,this.currentNode.id);
        // this.$sendToDotNet('RefreshTree');
        this.contentXmlStr = this.editor.txt.html();
    },
    //保存当前DMC信息
    saveNowDmc2(type) {
         if(this.editor){
          const html4 = this.editor.txt.html();
         console.log("保存内容4",html4)
        }
      console.log("保存时候点击",this.lastClick)
      if(type == 'save'){
          console.log("保存时候点击 this.currentNode",this.currentNode,this.currentNode.minorVersion)
        // if(this.currentNode.minorVersion == '00'){
          const targetNode = this.findNodeById(this.treeData,this.lastClick);
          targetNode.minorVersion = '01';
        
         
        // }
          console.log("保存时候点击 treedata",this.treeData)
         this.catalogueAnalysis(this.treeData);
        
        this.generateXml(false,this.lastClick);
    
       
         this.contentXmlStr = this.editor.txt.html();
        // const targetNode = this.findNodeById(this.treeData, this.lastClick);
        //   if (targetNode) {
        //     targetNode.minorVersion = '01';
        //   }
        // this.catalogueAnalysis(this.treeData);
      }else if(type == 'noSave'){
        this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.lastClick+this.domNameStr[3]+this.domNameStr[4];
        console.log("加载富文本的文件名",this.getDmName)
        this.loadFWBFile(this.getDmName);
        console.log("不保存")
      }
      this.dialogVisibleTips2 = false;
        console.log("saveNowDmc2",type)
    },
    //保存当前DMC信息
    saveNowDmc(type){
      if(type == 'save'){
        this.navIsAdd = 'other'
        this.generateXml(false);
        this.dialogVisibleTips = false;
        this.dialogVisibleNav = true;
      }else if(type == 'noSave'){
        this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.lastClick+this.domNameStr[3]+this.domNameStr[4];
        this.loadFWBFile(this.getDmName);
        this.dialogVisibleTips = false;
        this.dialogVisibleNav = true;
      }
      this.loadFileDMC = '';
      this.clearFormData();
      this.showView = false;
      this.$sendToDotNet('CancelUserHistoy')
    },
    //测试 绑定资源弹窗显示
    showBand() {
      this.dialogVisibleRight = false;
      this.dialogVisibleBland = true;
    },
    //测试 历史版本展示
    showHistory() {
      this.dialogVisibleRight = false;
      this.dialogVisibleHistory = true;
      this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.currentNode.id+this.domNameStr[3]+this.domNameStr[4];
      console.log("历史版本查询时候的名字",this.getDmName)
      console.log("历史版本查询时候的domNameStr",this.domNameStr)
      console.log("历史版本查询时候的currentNode",this.currentNode)
      this.$sendToDotNet("GetHistoryVesions",this.getDmName)

    },
    //版本定稿
    finalVersion() {
      console.log("定版时候的参数",this.currentNode) 
      const newStr = 'A-A_'+this.currentNode.lagreVersion+'_00';
      // let versionName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.currentNode.id+this.domNameStr[3]+this.domNameStr[4]+'.xml';
      const versionName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.currentNode.id+newStr+this.domNameStr[4]+'.xml';
      // this.currentNode.minorVersion = '00';

      const targetNode = this.findNodeById(this.treeData,this.currentNode.id);
      targetNode.minorVersion = '00';
      // targetNode.lagreVersion = this.currentNode.lagreVersion

      const num = parseInt(this.currentNode.lagreVersion, 10);
      // 3. 加1运算
      const newNum = num + 1;
      // 4. 格式化为3位带前导零的字符串
      this.form.version = String(newNum).padStart(3, "0");

      console.log("定稿时候逇form",this.form)
      this.catalogueAnalysis(this.treeData);
      this.generateXml(false);
      this.$sendToDotNet("CreatVersion",versionName)
    },
    //显示新建弹窗
    showAddDialog(type) {
      console.log("点击新建",type)
      this.$sendToDotNet("CancelPriview")
      this.navIsAdd = type;
      if(type == "create"){
        this.form.name = '';
        this.isLoadOldDmc = '2',
        this.clearFormData();
      }else{
        this.form.name = this.currentNode.name;
      }

      if(this.dmcIsChange()){
        this.dialogVisibleNav = true;
        this.loadFileDMC = '';
        this.showView = false;
      }else{
        this.dialogVisibleTips = true;
      }
      // this.$sendToDotNet('CancelUserHistoy')
    
      this.dialogVisibleRight = false;
    },
    //截取路径信息
    removeQuotationMarks(data) {
      const result = data.replace(/^"|"$/g, '');
      return result;
    },
    //目录节点点击
    handleNodeClick(data) { 
    // this.currentNode = data; //有问题
      this.navIsAdd = ''; 
     console.log("这一次点击的节点信息",data);
      console.log("上一次点击的时候的ID",this.lastClick)
      console.log("这一次点击的时候的ID",this.nowClick)
      if(this.lastClick == this.nowClick.id){
        this.currentNode = data;
        this.nowClick = data;
        this.lastClick = data.id; 
      }else{ 
     
        console.log("中中中中中",this.lastClick,this.dmcIsChange())
        if(this.lastClick&&!this.dmcIsChange()){
          this.dialogVisibleTips2 = true;
          console.log("dialogVisibleTips2出现")
          console.log("恢复成上一次点击",this.lastClick)
          // this.$refs.tree.setCheckedKeys([this.lastClick]);

          // 确保DOM更新后再重置状态
          this.$nextTick(() => {
            this.$refs.tree.setCheckedKeys([this.lastClick]);
            this.$refs.tree.setCurrentKey(this.lastClick);
          });
        }else{
           this.currentNode = data;
          const target = this.domNameStr[3];
          // 假设需要替换的格式是 "前缀_xxx_yy"，其中xxx是3位，yy是2位
          // 先找到最后两个下划线的位置
          const lastUnderlineIndex = target.lastIndexOf('_');
          const secondLastUnderlineIndex = target.lastIndexOf('_', lastUnderlineIndex - 1);
          
          if (lastUnderlineIndex > -1 && secondLastUnderlineIndex > -1) {
            // 截取前缀部分（到第二个下划线）
            const prefix = target.substring(0, secondLastUnderlineIndex + 1);
            // 截取中间部分（3位）和末尾部分（2位），并用新值替换
            // const newValue = `${prefix}${data.lagreVersion}_${data.minorVersion}`;
            const newValue = `${prefix}${data.lagreVersion}_00`;
            
            // 更新数组
            this.domNameStr.splice(3, 1, newValue);
            this.replaced = true;
          }

          console.log("点击时候的节点data",data.id)
          this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+data.id+this.domNameStr[3]+this.domNameStr[4];
          console.log("加载富文本的文件名",this.getDmName)
          this.loadFWBFile(this.getDmName);
          this.lastClick = data.id; 
        }
        
        // if(this.lastClick){
        //   if(!this.dmcIsChange()){
        //     this.navIsAdd = 'edit';
        //     this.generateXml(false,this.lastClick);
        //   }
        // }
        //   this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+data.id+this.domNameStr[3]+this.domNameStr[4];
        //   console.log("加载富文本的文件名",this.getDmName)
        //   this.loadFWBFile(this.getDmName);
      } 
      console.log("当前节点点击",data);
      setTimeout(() => {
        this.getWindowSize();
      }, 30); 
      // this.$sendToDotNet('GetFilePath','PMC',data.id,'');

    },

    zy(dataStr) {
       try {
          // 1. 清理字符串
          const cleaned = dataStr.replace(/;$/g, '');
          // 2. 转义双引号
          const escaped = cleaned.replace(/"/g, '\\"');
          // 3. 解码 Unicode
          let unicodeDecoded = JSON.parse(`"${escaped}"`);
          // 4. 处理反斜杠
          let a  = unicodeDecoded.replace(/\\\\/g, "\\")
          return a;
        } catch (e) {
          // 捕获解析错误，避免页面崩溃
          console.error("字符串解析失败：", e);
          return "解析错误";
        }
    },
    //确认新建目录
    confirmAdd(type) {
      if(type){
        this.loadFileDMC = ''; 
      }else{
         this.$sendToDotNet('CopyToWorkDire');
      }
      this.$refs.form.validate((valid) => {
        if (!valid) return

        // if(!this.dmcIsChange()){

        // }else{

        // }
        
        const newNode = {
          id: this.queryMaxId(),
          maxId:this.mId,
          name: this.form.name,
          attributes: [],
          formMes:this.form,
          lagreVersion:this.form.version,//大版本
          minorVersion:'00',//临时版本
          children: []
        }
        console.log("新建章节目录时候的参数",newNode)
        this.nowMaxId = newNode.id;

        if (this.currentNode) {
          if (!this.currentNode.children) {
            this.$set(this.currentNode, 'children', [])
          }
          this.currentNode.children.push(newNode)
        } else {
          this.treeData.push(newNode)
        }

        this.dialogVisibleNav = false
        this.$nextTick(() => {
          this.$refs.tree.setCurrentKey(newNode.id)
          // this.currentNode = newNode;
           this.currentNode = '';

          this.catalogueAnalysis(this.treeData);
          // this.$sendToDotNet('SaveFile','PMC',newNode.id,JSON.stringify(this.currentNode));
          //创建目录时候同时创建一个空DM文件
          console.log("创建目录时候同时创建一个空DM文件")
          this.generateXml(true);

         
        })
      })
    },
    //编辑目录时候点击确认进行保存
    confirmEdit() {
      this.currentNode.name = this.form.name;
      console.log("点击编辑确定",this.currentNode,this.treeData)
      
      
      this.currentNode.minorVersion = '01';
      this.catalogueAnalysis(this.treeData);

      this.isNavEdit = true;
      this.dialogVisibleNav = false;
      this.generateXml(false,this.treeData.id)
      // let targetNode = this.findNodeById(this.treeData,this.currentNode.id);
      // if (targetNode) {
      //     // 替换attributes
      //     // targetNode.name = ...this.currentNode.name];
      //     // this.hasReplaced = true;
      //     console.log('替换成功，新的节点数据:', targetNode);
      //   } else {
      //     console.warn('未找到节点');
      //   }
      // console.log('获取当前节点',this.currentNode)
    },
    // 删除时候的二次确认弹窗
    deleteDialog() {
      console.log("currentNode.children",this.currentNode)
      this.dialogVisibleNavDel = true;
    },
    // 删除绑定资源按钮
    deleteAttr(name,index) {
      this.nowAttr ={
        name:name,
        index:index,
      }
      this.dialogVisibleAttrDel = true;
    },
     // 删除绑定资源二次确定
    deleteAttrSure() {
      this.currentNode.attributes.splice(this.nowAttr.index, 1);
      this.catalogueAnalysis(this.treeData);
      this.dialogVisibleAttrDel = false;
    },
    //删除节点时候判断是否有子节点。
    deleteNode() {
      if (this.currentNode.children && this.currentNode.children.length > 0) {
        this.$message({
          type: 'warning',
          message: '该节点包含子节点，不能删除！'
        })
      }else{
        let isDel = this.deleteNodeFromTree(this.treeData, this.currentNode.id)
        console.log("删除是否成功",isDel,this.currentNode)
        // this.currentNode = null;
        const fileId = this.currentNode.id;
        this.catalogueAnalysis(this.treeData);
        this.dialogVisibleNavDel = false;
        // this.$sendToDotNet('RefreshTree');
       console.log('删除RMDMfile fileId',fileId)
        this.$sendToDotNet('RMDMfile','DMC',fileId,this.currentNode.lagreVersion)
        this.currentNode = '';
        // this.$message({
        //   type: 'success',
        //   message: '删除成功!'
        // })
      }
    },

    
    // 更新指定节点的版本号
    updateNodeVersion(id,vs) {
      const targetNode = this.findNodeById(this.treeData2, id);
      if (targetNode) {
        targetNode.lagreVersion = vs;
      }
    },
    //删除节点
    deleteNodeFromTree(nodes, id) {
      for (let i = 0; i < nodes.length; i++) {
        if (nodes[i].id === id) {
          nodes.splice(i, 1)
          return true
        }
        if (nodes[i].children && nodes[i].children.length > 0) {
          if (this.deleteNodeFromTree(nodes[i].children, id)) {
            return true
          }
        }
      }
      return false
    },
    //重置输入框
    resetForm() {
      this.$refs.form.resetFields()
    },
    // 搜索相关方法
    handleSearch() {
      if (!this.searchText.trim()) {
        this.$refs.tree.filter(this.searchText);
        // 搜索内容为空时，重置所有节点的可见性
        this.resetTreeVisibility(this.treeData)
      }else{
        this.$refs.tree.filter(this.searchText)
      }
      
    },
    //清除搜索
    handleSearchClear() {
      this.searchText = '';
      // 清空搜索时重置所有节点的可见性
      this.$refs.tree.filter('');
      this.resetTreeVisibility(this.treeData)
    },
    //重置目录节点信息
    resetTreeVisibility(nodes) {
      nodes.forEach(node => {
        // 重置节点的可见性
        node.visible = true
        if (node.children && node.children.length > 0) {
          this.resetTreeVisibility(node.children)
        }
      })
      // 强制刷新树组件
      this.$refs.tree.updateKeyChildren()
    },
    //目录节点信息
    filterNode(value, data) {
      if (!value) return true; // 空值时显示所有节点
      // 这里假设你要搜索的是节点的name属性
      return data.name.toLowerCase().includes(value.toLowerCase()); 
    },   
    //筛选后高亮class
    isHighlight(data) {
       return this.searchText && data.name.toLowerCase().includes(this.searchText.toLowerCase())
    }, 
 
    // 保存属性
    saveAttributes() {
      console.log("this.currentNode.id",this.currentNode.id)
      this.$sendToDotNet('GetFilePath','PMC',this.currentNode.id,'');

      // if (this.currentNode) {
      //   // 保存选中的属性到当前节点
      //   this.currentNode.attributes = [...this.selectedAttributes];
      //   // 刷新树结构
      //   this.$refs.tree.setCurrentKey(this.currentNode.id);
      // }
      // this.dialogVisibleRight = false;
    }, 

    //查询最大ID值
    queryMaxId() {
      //  maxId = '00001'
      console.log("初始化ID",this.treeData)
      // if(this.treeData[0]){
      let maxId = this.mId?this.mId:'00001';
      const length = maxId.length;
      // 将字符串转换为数字并加1
      const number = parseInt(maxId, 10) + 1;
      // 格式化数字为指定长度的字符串，不足的前面补零
      maxId = number.toString().padStart(length, '0');
      // }
      this.mId = maxId;
      return maxId;
      // let maxId = 0;
      // let treeData = this.treeData;
      // // 递归遍历函数
      // const traverse = (nodes) => {
      //   if (!nodes || nodes.length === 0) return;
        
      //   nodes.forEach(node => {
      //     // 比较当前节点ID与最大值
      //     if (node.id > maxId) {
      //       maxId = node.id;
      //     }
      //     // 递归处理子节点
      //     traverse(node.children);
      //   });
      // };
        
      // // 开始遍历
      // traverse(treeData);
      // console.log("当前数据最大ID",maxId)
      // const length = maxId.length;
      // // 将字符串转换为数字并加1
      // const number = parseInt(maxId, 10) + 1;
      // // 格式化数字为指定长度的字符串，不足的前面补零
      // maxId = number.toString().padStart(length, '0');
      // if(maxId == 1){
      //   maxId = '00001'
      // }
      // return maxId;
    },
    

    //解析XML目录（暂时不用）
    extractDmCode(xmlString) {
      // 1. 解析 XML 字符串
      const parser = new DOMParser();
      const xmlDoc = parser.parseFromString(xmlString, "text/xml");

      // 2. 获取所有 dmCode 节点
      const dmCodeNodes = xmlDoc.getElementsByTagName("dmCode");
      const issueInfoNodes = xmlDoc.getElementsByTagName("issueInfo");
      const languageNodes = xmlDoc.getElementsByTagName("language");

      // 3. 遍历节点，提取属性
      let dmCodeList = Array.from(dmCodeNodes).map(node => {
        const attributes = {};
        // 遍历节点的所有属性
        for (let i = 0; i < node.attributes.length; i++) {
          const attr = node.attributes[i];
          attributes[attr.name] = attr.value;
        }
        return attributes;
      });
      let issueInfoList = Array.from(issueInfoNodes).map(node => {
        const attributes = {};
        // 遍历节点的所有属性
        for (let i = 0; i < node.attributes.length; i++) {
          const attr = node.attributes[i];
          attributes[attr.name] = attr.value;
        }
        return attributes;
      });
      let languageList = Array.from(languageNodes).map(node => {
        const attributes = {};
        // 遍历节点的所有属性
        for (let i = 0; i < node.attributes.length; i++) {
          const attr = node.attributes[i];
          attributes[attr.name] = attr.value;
        }
        return attributes;
      });
      // 处理函数：将对象按指定字段集拼接成字符串
      let dmCodeTitle = ['modelIdentCode','systemDiffCode','systemCode','subSystemCode','subSubSystemCode','disassyCode','disassyCodeVariant','infoCode','infoCodeVariant','itemLocationCode']
      let issueInfoTitle = ['issueNumber','inWork'];
      let languageTitle = ['languageIsoCode','countryIsoCode']
      
    

      // 处理三组数据
      let dmCodeResult = this.joinFields(dmCodeList, dmCodeTitle,'-');
      let issueInfoResult = this.joinFields(issueInfoList, issueInfoTitle,'_');
      let languageResult = this.joinFields(languageList, languageTitle,'_');
      
      console.log("参数 dmCodeResult",dmCodeResult)
      console.log("参数 issueInfoResult",issueInfoResult)
      console.log("参数 languageResult",languageResult)

      // let dmCodeResult2 = [];

      let newList = [];
      for(let i = 0;i<dmCodeResult.length;i++){
        // let strA = dmCodeResult[0]+'_'+dmCodeResult[0]
        let str = dmCodeResult[i]+"-"+issueInfoResult[i]+"-"+languageResult[i]
        newList.push(str);
      }
      console.log("结果",newList)
    },

    //解析目录节点数据
    generateTreeData(xmlContent) {
      // console.log("加载XML解析内容 初始化内容",xmlContent)
      // 1. 解析XML
      const parser = new DOMParser();
      const xmlDoc = parser.parseFromString(xmlContent, "text/xml");
      //  console.log("加载XML解析内容 初始化XML",xmlDoc)
      // 2. 获取根节点（content下的所有pmEntry）
      const contentNode = xmlDoc.querySelector("content");
      // console.log("加载XML解析内容 content",contentNode)
      const rootPmEntries = contentNode ? Array.from(contentNode.children).filter(node => node.tagName === "pmEntry") : [];
      

      let getBookName = xmlDoc.getElementsByTagName('pmTitle');
      this.getBookName = getBookName[0].textContent;
      console.log("得到的书名",this.getBookName)
      // 3. 递归处理节点，构建树形结构
      this.treeData = this.parsePmEntries(rootPmEntries);
      this.handleCheckVersion();
      // console.log("")
  
      console.log("重新解析结果",this.treeData)
      // if(this.treeData.length>0){
      //   this.clearNodeState();
      // }
      //  this.enableContextMenu();//绑定右键

      // 获取最大ID
      const simpleParaNode = xmlDoc.querySelector("simplePara");
      console.log("加载XML解析内容 id",simpleParaNode)
      const maxId = simpleParaNode.getAttribute("maxId") || "00001";
      console.log("当前目录最大ID",maxId)
      this.mId = maxId;

      const issueInfoNode = xmlDoc.querySelector("issueInfo");
      this.minLevel = issueInfoNode.getAttribute("minLevel")
      this.maxLevel = issueInfoNode.getAttribute("maxLevel")
      this.maxPermission = issueInfoNode.getAttribute("maxPermission")
      this.minPermission = issueInfoNode.getAttribute("minPermission")
      console.log("版本号上各种参数",this.minLevel,this.maxLevel,this.minPermission,this.maxPermission)
    },
    
    /**
     * 递归解析pmEntry节点列表，生成树形数据
     * @param {NodeList} pmEntries - pmEntry节点列表
     * @param {Object} parent - 父节点（用于处理嵌套关系）
     * @returns {Array} 树形结构数组
     */
    parsePmEntries(pmEntries, parent = null) {
      const treeNodes = [];
      console.log("parent",parent)
      pmEntries.forEach(entry => {
        // const lagreVersion = parent.getAttribute("lagreVersion") || "";
        // const minorVersion = parent.getAttribute("minorVersion") || "";
        // console.log("数循环结果 大版本",lagreVersion)
        // console.log("数循环结果 小版本",minorVersion)
        // a. 提取当前节点的id、name、attributes
        const titleNode = entry.querySelector("pmEntryTitle") || entry.querySelector("techName");
        if (!titleNode) return; // 跳过无标题的节点
        
        const id = titleNode.getAttribute("id");
        const name = titleNode.textContent.trim();
        const attributesStr = titleNode.getAttribute("attributes") || "";
        const lagreVersion = titleNode.getAttribute("lagreVersion") || "000";
        const minorVersion = titleNode.getAttribute("minorVersion") || "00";
        // const maxID = titleNode.getAttribute("maxId") || "00001";
        const attributes = attributesStr ? attributesStr.split(",").map(item => item.trim()) : [];
        
        
        // b. 创建节点基本结构
        const node = {
          id,
          name,
          // maxId:maxID,
          attributes,
          formMes: {}, // 固定空对象
          children: [],
          lagreVersion:lagreVersion,//大版本
          minorVersion:minorVersion,//临时版本
        };
        
        // c. 处理子节点（当前pmEntry下的子pmEntry）
        const childEntries = Array.from(entry.children).filter(child => child.tagName === "pmEntry");
        if (childEntries.length > 0) {
          node.children = this.parsePmEntries(childEntries, node);
        }
        
        treeNodes.push(node);
      });
      
      return treeNodes;
    },
    //测试 解析xml 暂未使用
     parseXml(xmlInput) {
      
      this.errorMessage = '';
      this.parsedData = [];
      
      try {
        // 创建DOMParser实例
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(xmlInput, "text/xml");
        console.log("xmlDoc",xmlDoc)
        // 检查XML解析错误
        const parserError = xmlDoc.getElementsByTagName("parsererror")[0];
        if (parserError) {
          throw new Error("XML格式错误: " + parserError.textContent);
        }
        
        // 获取所有顶级pmEntry节点
        const pmEntries = xmlDoc.querySelectorAll('content > pmEntry');
        let parsedData = [];
        // 解析每个pmEntry
        pmEntries.forEach(pmEntry => {
          const entryData = this.parsePmEntry(pmEntry);
          if (entryData) {
            parsedData.push(entryData);
          }
        });
        
        parsedData.map((res)=>{
          if(res.infoCode){
             return res.is = res.infoCode,res.name = res.title;
          }
        })
        this.treeData = parsedData;
        console.log("parsedData",parsedData)
      } catch (error) {
        this.errorMessage = "解析失败: " + error.message;
        console.error("XML解析错误:", error);
      }
    },
     /**
     * 获取指定节点的值
     * @param {Element} parentNode - 父节点
     * @param {string} selector - 节点选择器
     * @returns {string} 节点值
     */
    getNodeValue(parentNode, selector) {
      const node = parentNode.querySelector(selector);
      return node ? node.textContent.trim() : '';
    },
    //格式化数据提取节点内容
    parsePmEntry(pmEntryElement) {
      // 获取pmEntryTitle
      const titleElement = pmEntryElement.querySelector('pmEntryTitle');
      if (!titleElement) return null;
      
      const title = titleElement.textContent.trim();
      const result = {
        title,
        children: [],
        subItems: []
      };
      
      // 获取当前pmEntry下的所有子节点
      const childNodes = Array.from(pmEntryElement.childNodes);
      
      // 查找子pmEntry和dmRef节点
      childNodes.forEach(node => {
        if (node.nodeType !== 1) return; // 只处理元素节点
        
        if (node.tagName === 'pmEntry') {
          // 递归解析子pmEntry
          const childData = this.parsePmEntry(node);
          if (childData) {
            result.children.push(childData);
          }
        } else if (node.tagName === 'dmRef') {
          // 解析dmRef中的infoCode
          const dmCode = node.querySelector('dmRefIdent > dmCode');
          if (dmCode && dmCode.hasAttribute('infoCode')) {
            result.subItems.push({
              infoCode: dmCode.getAttribute('infoCode')
            });
          }
        }
      });
      
      // 如果没有子节点但有subItems，设置当前节点的infoCode为第一个subItem的infoCode
      if (result.children.length === 0 && result.subItems.length > 0) {
        result.infoCode = result.subItems[0].infoCode;
      }
      
      return result;
    },
    // 处理数据信息
     joinFields(dataList, fields) {
       return dataList.map(item => {
        return fields.map(field => item[field]).join('_');
      });
    },

  
  //处理目录节点信息
    catalogueAnalysis(treeData) {
        console.log("处理每个节点信息 treeData",treeData)
       // 递归处理每个节点，跟踪路径用于生成infoName
    const processNode = (node, path = [], level = 0) => {
      let nodeStr = '';
      console.log("处理每个节点信息 node",node)
      // 每个节点都用pmEntry标签包裹
      nodeStr += '<pmEntry>\n';
      
      // 计算当前节点的路径，用于生成infoName
      const currentPath = [...path, node.name];
      
      // 如果有子节点，添加pmEntryTitle标签
      if (node.children && node.children.length > 0) {
        nodeStr += `\t<pmEntryTitle attributes='${node.attributes}' lagreVersion="${node.lagreVersion}" minorVersion="${node.minorVersion}" id="${node.id}">${node.name}</pmEntryTitle>\n`;
        
        // 递归处理子节点
        node.children.forEach((child, index) => {
          console.log("index",index)
          // 递归处理子节点，传入当前路径（移除了未使用的infoCode和issueDate参数）
          nodeStr += processNode(child, currentPath, level + 1);
        });
      } else {
        // 没有子节点的节点用dmRef标签包裹
        nodeStr += '\t<dmRef>\n';
        
        // 添加dmRefIdent部分，包含动态生成的dmCode
        nodeStr += `\t\t<dmRefIdent>\n`;
        nodeStr += `\t\t\t<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="${getInfoCode(level)}" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="${getSubSubSystemCode(level)}" subSystemCode="${getSubSystemCode(level)}" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>\n`;
        nodeStr += `\t\t\t<issueInfo issueNumber="001" inWork="01"/>\n`;
        nodeStr += `\t\t\t<language languageIsoCode="zh" countryIsoCode="CN"/>\n`;
        nodeStr += `\t\t</dmRefIdent>\n`;
        
        // 添加dmRefAddressItems标签
        nodeStr += `\t\t<dmRefAddressItems>\n`;
        
        // 添加dmTitle标签，包含techName和infoName
        nodeStr += `\t\t\t<dmTitle>\n`;
        nodeStr += `\t\t\t\t<techName  attributes='${node.attributes}' lagreVersion="${node.lagreVersion}" minorVersion="${node.minorVersion}" id="${node.id}">${node.name}</techName>\n`;
        nodeStr += `\t\t\t\t<infoName>${currentPath.join('-')}</infoName>\n`;
        nodeStr += `\t\t\t</dmTitle>\n`;
        
        // 添加issueDate标签
        nodeStr += `\t\t\t<issueDate year="2024" month="06" day="${getIssueDay(level)}"/>\n`;
        
        // 闭合dmRefAddressItems标签
        nodeStr += `\t\t</dmRefAddressItems>\n`;
        
        // 闭合dmRef标签
        nodeStr += `\t</dmRef>\n`;
      }
      
      // 闭合当前节点的pmEntry标签
      nodeStr += '</pmEntry>\n';
      
      return nodeStr;
    };
    
    // 根据层级和索引生成infoCode
    const getInfoCode = (level, index = 0) => {
      if (level === 1 && index === 0) return "042";
      if (level === 1 && index === 1) return "041";
      return "040";
    };
    
    // 根据层级生成subSystemCode
    const getSubSystemCode = (level) => {
      if (level === 0) return "0";
      if (level === 1) return "1";
      if (level === 2) return "3";
      return "0";
    };
    
    // 根据层级生成subSubSystemCode
    const getSubSubSystemCode = (level, index = 0) => {
      if (level === 1) return "1";
      if (level === 2) return index + 1;
      return "0";
    };
    
    // 根据层级生成issueDay
    const getIssueDay = (level) => {
      return level === 1 ? "13" : "12";
    };
    
    // 处理所有根节点
    let result = '';
    treeData.forEach(node => {
      result += processNode(node);
    });
    
      // console.log('catalogueString 目录字符串',result);
      this.catalogueString = result;
      this.saveNav();
      // console.log(this.treeData)
    },
  //生成目录节点XML信息 并保存目录pmc
    saveNav() {
   let a1 =  this.form.permission;//2
   let a2 =  this.form.level;//2
   
  //  let minP = this.minPermission;//1
   let maxP = this.maxPermission;//5
  //  let minL = this.minLevel;//1
   let maxL = this.maxLevel;//5

   if(a1>maxP){
    maxP = a1;
   }
   if(a2>maxL){
    maxL = a2;
   }

      let xmlStr = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
            <!DOCTYPE pm [
            ]>
            <pm xsi:noNamespaceSchemaLocation="http://www.s1000d.org/S1000D_4-1/xml_schema_flat/pm.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://www.purl.org/dc/elements/1.1/" xmlns:xlink="http://www.w3.org/1999/xlink">
              <identAndStatusSection>
                <pmAddress>
                  <pmIdent>
                    <pmCode modelIdentCode="YSC001" pmIssuer="732380192B" pmNumber="00001" pmVolume="00"/>
                    <language countryIsoCode="CN" languageIsoCode="zh"/>
                    <issueInfo minLevel="1" maxLevel="`+maxL+`" maxPermission="`+maxP+`" minPermission="1" issueNumber="000" inWork="01"/>
                  </pmIdent>
                  <pmAddressItems>
                    <issueDate year="2024" month="06" day="24"/>
                    <pmTitle>`+this.getBookName+`</pmTitle>
                  </pmAddressItems>
                </pmAddress>
                <pmStatus issueType="new">
                  <security securityClassification="01"/>
                  <responsiblePartnerCompany enterpriseCode=" "/>
                  <originator/>
                  <applic>
                    <displayText>
                      <simplePara maxId='`+this.mId+`'>A0304-1A无人机系统地面运输方舱</simplePara>
                    </displayText>
                  </applic>
                  <brexDmRef>
                    <dmRef xlink:type="simple" xlink:actuate="onRequest" xlink:show="replace" xlink:href="URN:S1000D:DMC-S1000D-E-04-10-0301-00A-022A-D">
                      <dmRefIdent>
                        <dmCode modelIdentCode="YSC001" systemDiffCode="A" systemCode="P4" subSystemCode="0" subSubSystemCode="0" assyCode="00" disassyCode="00" disassyCodeVariant="A" infoCode="022" infoCodeVariant="A" itemLocationCode="A"/>
                      </dmRefIdent>
                    </dmRef>
                  </brexDmRef>
                  <qualityAssurance>
                    <unverified/>
                  </qualityAssurance>
                </pmStatus>
              </identAndStatusSection>
              <content>`
              +this.catalogueString+
              `</content>
            </pm>`
            // console.log("传递字符串",this.catalogueString)
            // console.log("存时候",xmlStr)
      this.$sendToDotNet('SaveFile','PMC','',xmlStr);

      // if(this.dialogVisibleNav){
      //   this.dialogVisibleNav = false;
      //   this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+this.currentNode.id+this.domNameStr[3]+this.domNameStr[4];
      //   console.log("加载富文本的文件名997",this.getDmName)
      //   setTimeout(() => {
      //       this.loadFWBFile(this.getDmName); 
      //       console.log("加载富文本的文件名997")
      //   }, 500);
      // }
     
      
    },
    //测试 加载目录
    jzml() {
      let a = `<!DOCTYPE pm [
            ]>
            <pm xsi:noNamespaceSchemaLocation="http://www.s1000d.org/S1000D_4-1/xml_schema_flat/pm.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://www.purl.org/dc/elements/1.1/" xmlns:xlink="http://www.w3.org/1999/xlink">
              <identAndStatusSection>
                <pmAddress>
                  <pmIdent>
                    <pmCode modelIdentCode="YSC001" pmIssuer="732380192B" pmNumber="00001" pmVolume="00"/>
                    <language countryIsoCode="CN" languageIsoCode="zh"/>
                    <issueInfo issueNumber="000" inWork="01"/>
                  </pmIdent>
                  <pmAddressItems>
                    <issueDate year="2024" month="06" day="24"/>
                    <pmTitle>无人机系统地面运输方舱使用维护说明书</pmTitle>
                  </pmAddressItems>
                </pmAddress>
                <pmStatus issueType="new">
                  <security securityClassification="01"/>
                  <responsiblePartnerCompany enterpriseCode=" "/>
                  <originator/>
                  <applic>
                    <displayText>
                      <simplePara>A0304-1A无人机系统地面运输方舱</simplePara>
                    </displayText>
                  </applic>
                  <brexDmRef>
                    <dmRef xlink:type="simple" xlink:actuate="onRequest" xlink:show="replace" xlink:href="URN:S1000D:DMC-S1000D-E-04-10-0301-00A-022A-D">
                      <dmRefIdent>
                        <dmCode modelIdentCode="YSC001" systemDiffCode="A" systemCode="P4" subSystemCode="0" subSubSystemCode="0" assyCode="00" disassyCode="00" disassyCodeVariant="A" infoCode="022" infoCodeVariant="A" itemLocationCode="A"/>
                      </dmRefIdent>
                    </dmRef>
                  </brexDmRef>
                  <qualityAssurance>
                    <unverified/>
                  </qualityAssurance>
                </pmStatus>
              </identAndStatusSection>
              <content><pmEntry>
	<pmEntryTitle>装备概况</pmEntryTitle>
<pmEntry>
	<pmEntryTitle>方舱概述</pmEntryTitle>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="040" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="3" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00003">无人机系统</techName>
				<infoName>装备概况-方舱概述-功能介绍</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="12"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="040" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="3" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00004">无人机系统</techName>
				<infoName>装备概况-方舱概述-规格介绍</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="12"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="042" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="1" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes='["金","木","水"]' id="00005">无人机系统</techName>
				<infoName>装备概况-舱体</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="13"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="042" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="1" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00006">无人机系统</techName>
				<infoName>装备概况-机身转运小车</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="13"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="042" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="1" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00007">无人机系统</techName>
				<infoName>装备概况-无人机部件存储装置</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="13"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="042" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="1" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00008">无人机系统</techName>
				<infoName>装备概况-机身转运小车</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="13"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<pmEntryTitle>附件及工具</pmEntryTitle>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="040" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="3" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00010">无人机系统</techName>
				<infoName>装备概况-附件及工具-灭火器</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="12"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="040" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="3" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00011">无人机系统</techName>
				<infoName>装备概况-附件及工具-应急灯</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="12"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="040" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="3" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00012">无人机系统</techName>
				<infoName>装备概况-附件及工具-土木工具</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="12"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="040" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="3" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00013">无人机系统</techName>
				<infoName>装备概况-附件及工具-机械工具</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="12"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
</pmEntry>
</pmEntry>
<pmEntry>
	<pmEntryTitle>使用说明</pmEntryTitle>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="042" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="1" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00014">无人机系统</techName>
				<infoName>使用说明-无人机出舱</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="13"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="042" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="1" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00015">无人机系统</techName>
				<infoName>使用说明-无人机入舱</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="13"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
<pmEntry>
	<dmRef>
		<dmRefIdent>
			<dmCode itemLocationCode="A" infoCodeVariant="A" infoCode="042" disassyCodeVariant="A" disassyCode="00" assyCode="00" subSubSystemCode="1" subSystemCode="1" systemCode="P4" systemDiffCode="A" modelIdentCode="YSC001"/>
			<issueInfo issueNumber="000" inWork="01"/>
			<language languageIsoCode="zh" countryIsoCode="CN"/>
		</dmRefIdent>
		<dmRefAddressItems>
			<dmTitle>
				<techName attributes="[]" id="00016">无人机系统</techName>
				<infoName>使用说明-灭火器使用</infoName>
			</dmTitle>
			<issueDate year="2024" month="06" day="13"/>
		</dmRefAddressItems>
	</dmRef>
</pmEntry>
</pmEntry>
</content>
            </pm>`
          this.parseToTreeData(a); 
    },
    //清除新建目录弹窗内容信息。
    clearFormData() {
      this.form = {
        name: '',
        version:'000',
        date:'',
        language:'',
        level:'1',
        contributor:'',
        creator:'四威高科',
        applicabilityInformation:'',
        qualityVerification:'',
        permission:'1'
      }
    },
 
    //测试 格式化目录信息
    parseToTreeData(xmlString) {
          // 创建DOMParser实例
        const parser = new DOMParser();
        // 解析XML字符串
        const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
        
        // 获取根节点下的所有pmEntry节点（顶级节点）
        const rootPmEntries = xmlDoc.querySelectorAll('content > pmEntry');
        
        // 递归解析节点的函数
        const parseNode = (xmlNode) => {
          // 检查是否有pmEntryTitle子节点
          const titleNode = xmlNode.querySelector('pmEntryTitle');
          
          if (titleNode) {
            // 有标题节点，说明是父节点
            const node = {
              id: '', // 后续会从子节点中查找合适的id
              name: titleNode.textContent.trim(),
              children: [],
              attributes: []
            };
            
            // 修复选择器错误：使用更兼容的方式获取直接子节点
            const childNodes = xmlNode.childNodes;
            const childPmEntries = [];
            
            // 遍历所有子节点，筛选出直接子pmEntry元素
            for (let i = 0; i < childNodes.length; i++) {
              const child = childNodes[i];
              // 检查是否是元素节点且标签名为pmEntry
              if (child.nodeType === 1 && child.tagName === 'pmEntry') {
                childPmEntries.push(child);
              }
            }
            
            // 递归解析每个子节点
            childPmEntries.forEach(childEntry => {
              const childNode = parseNode(childEntry);
              if (childNode) {
                node.children.push(childNode);
              }
            });
            
            // 为父节点生成合适的id
            if (!node.id && node.children.length > 0) {
              // 取第一个子节点id的前缀并生成父节点id
              const firstChildId = node.children[0].id;
              // 简单处理：取前面的数字部分并减1（根据实际情况调整）
              node.id = (parseInt(firstChildId, 10) - 1).toString().padStart(firstChildId.length, '0');
            }
            
            return node;
          } else {
            // 没有标题节点，说明是叶子节点，从dmRef中获取信息
            const dmRef = xmlNode.querySelector('dmRef');
            if (!dmRef) return null;
            
            // 获取techName节点中的id和内容
            const techNameNode = dmRef.querySelector('techName');
            const id = techNameNode.getAttribute('id');
            const attributes = techNameNode.getAttribute('attributes');
            
            // 从infoName获取名称路径
            const infoNameNode = dmRef.querySelector('infoName');
            const infoName = infoNameNode.textContent.trim();
            // 取最后一部分作为名称
            const nameParts = infoName.split('-');
            const name = nameParts[nameParts.length - 1];
            
            return {
              id,
              name,
              children: [],
              attributes: attributes
            };
          }
        };
        
        // 解析所有顶级节点
        const treeData = [];
        rootPmEntries.forEach(entry => {
          const node = parseNode(entry);
          if (node) {
            treeData.push(node);
          }
        });
    
    console.log("打印",treeData)
    console.log("打印String",JSON.stringify(treeData))
        this.treeData = treeData;
      },

    //和后台交互 加载需要读取的dmc
    loadFWBFile(dmName) {
      // this.$sendToDotNet('LoadDM','DMC--A-P4-20-00-00A-00001A-A_000_01_zh_cn');
      console.log("需要读取的富文本：",dmName)
      this.$sendToDotNet('LoadDM','DMC',dmName);
      // this.$sendToDotNet('GetFilePath','PMC',data.id,'');

    },
    //和后台交互 查看历史版本 
    lookHistoryFile(path) {
      let newPath = path+'\\'+this.getLastPartOfPath(path)+'.xml';
      this.historyVsPath = path;
      console.log("发送路径",newPath)

        this.$sendToDotNet('DMPreview','HistoryDMPreview',newPath)

      // this.$sendToDotNet('GetHistoryDMContent',newPath);

      // localStorage.setItem('filePath',newPath);
      // const url = this.$router.resolve({ name: 'WangG2' }).href
      
      // // 打开新窗口，可指定窗口大小和位置
      // window.open(
      //   url, 
      //   '_blank', 
      //   'width=800,height=600,top=100,left=100'
      // )
    },
    //清除 NBSP str
    clearNbsp(originalStr) {
      const cleanedStr = originalStr.replace(/&nbsp;/g, '');
      
      console.log("结果cleanedStr",cleanedStr)
      
      return cleanedStr;    
    },
    //测试 测试拼接地址；
    ceshi() {
      this.lisenPath = '"http://localhost:61980/"';
      let e = {
        detail:'"\\1.jpg"'
      }
      const parsedA = this.lisenPath.replace(/"/g, '');
      const parsedB = e.detail.replace(/"/g, '');
        
        // 2. 处理转义字符（如斜杠）
        const processedA = parsedA.replace(/\\/g, '');
        const processedB = parsedB.replace(/\\/g, '');
        
        // 3. 确保基础URL以斜杠结尾
        let baseUrl = processedA;
        if (baseUrl && !baseUrl.endsWith('/')) {
          baseUrl += '/';
        }

        this.insertImage( baseUrl + processedB)
    },
    //判断拖拽进富文本的文件类型；
    isImageSuffix(a) {
        let type = '';
        // 检查参数是否为字符串
        if (typeof a !== 'string') {
          return false;
        }
        // 转换为小写后判断（忽略大小写）
        const lowerCaseA = a.toLowerCase();
        
        if(this.allImgType.has(lowerCaseA)){
          type = 'img';
        }else if(this.allMusicType.has(lowerCaseA)){
          type = 'music';
        }else if(this.allVideoType.has(lowerCaseA)){
          type = 'video';
        }else if(this.otherType.has(lowerCaseA)){
          type = '3d'
        }else {
          type = 'other'
        }
        return type;
      },
      //解析字符串信息
    parseSpecialString(str) {
      return str.replace(/['"\\]/g, '')
      // 处理步骤：移除引号 → 替换转义反斜杠 → 解析Unicode
      // return str
      //   .replace(/^"|"$/g, '')
      //   .replace(/\\\\/g, '\\')
      //   .replace(/\\\\/g, '\\')
      //   .replace(/""/g, '')
      //   .replace(/\\u([0-9a-fA-F]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
    },
    //根据ID查询节点 已经需要替换的内容信息
      replaceAttributes() {
        // 找到treeData中id为xx节点
        const targetNode = this.findNodeById(this.treeData,this.currentNode.id);
        
        if (targetNode) {
          // 替换attributes
          targetNode.attributes = [...this.currentNode.attributes];
          // this.hasReplaced = true;
          console.log('替换成功，新的attributes:', targetNode.attributes);
        }
        this.catalogueAnalysis(this.treeData);
      },
       /**
     * 查找树形结构中指定id的节点
     * @param {Array} nodes - 节点数组
     * @param {string} id - 要查找的节点id
     * @returns {Object|null} 找到的节点或null
     */
    findNodeById(nodes, id) {
      // 遍历节点数组
      for (const node of nodes) {
        // 找到目标节点
        if (node.id === id) {
          return node;
        }
        // 递归查找子节点
        if (node.children && node.children.length > 0) {
          const found = this.findNodeById(node.children, id);
          if (found) {
            return found;
          }
        }
      }
      return null;
    },
    //成功信息  暂未使用
    successTips(msg) {
       this.$message({
          message: msg,
          type: 'success'
        });
    },

  //目录节点拖拽结束后
  handleDragEnd() {
    //拖拽完成后保存目录节点。
    this.catalogueAnalysis(this.treeData)
  },

    // 处理节点右键点击
// 处理节点右键点击
handleNodeContextMenu(event, data, node, component) {
  event.preventDefault();
  event.stopPropagation();
  console.log("node",node)
  console.log("component",component)
  this.navIsAdd = '';
  this.contextMenuNode = data;
   this.currentNode = data;
   this.nowRightHint = data.name;
   console.log("右键以后赋值:",this.currentNode,data)
    this.getDmName = this.domNameStr[0]+this.domNameStr[1]+this.domNameStr[2]+data.id+this.domNameStr[3]+this.domNameStr[4];
      console.log("删除的DM名字",this.getDmName)
      // return;
  // 获取鼠标位置
  let clientX = event.clientX;
  let clientY = event.clientY;
  
  // 预估菜单高度（可根据实际菜单内容调整）
  const menuHeight = 200; // 包含4个选项+分隔线+关闭按钮的大概高度
  const windowHeight = window.innerHeight;
  
  // 计算菜单底部位置
  const menuBottom = clientY + menuHeight;
  
  // 如果菜单底部超出窗口高度，向上调整位置
  if (menuBottom > windowHeight) {
    // 调整后的位置 = 鼠标Y - 菜单高度（确保菜单顶部不超出窗口顶部）
    clientY = Math.max(0, clientY - menuHeight);
  }
  
  // 设置调整后的菜单位置
  this.contextMenuLeft = clientX;
  this.contextMenuTop = clientY;
  this.contextMenuVisible = true;
  
  // 点击其他区域关闭菜单 - 修复版
  const handleClickOutside = (e) => {
    // 先判断菜单元素是否存在
    const menuElement = document.querySelector('.custom-context-menu');
    if (!menuElement) {
      // 元素不存在时直接移除监听
      document.removeEventListener('click', handleClickOutside);
      return;
    }
    
    // 元素存在再判断点击位置
    if (!menuElement.contains(e.target)) {
      this.contextMenuVisible = false;
      document.removeEventListener('click', handleClickOutside);
    }
  };
    
    // 确保移除之前可能存在的监听，避免重复绑定
    setTimeout(() => {
      document.removeEventListener('click', handleClickOutside);
      document.addEventListener('click', handleClickOutside);
    }, 0);
  }
  ,
    
    // 处理菜单选项点击
    handleMenuClick(option) {
      console.log('选择了选项:', option, '，节点数据:', this.contextMenuNode);
      // 根据选项执行对应操作
      switch(option) {
        case 'a':
          this.showAddDialog('edit');
          // 处理选项a逻辑
          break;
        case 'b':
          this.showBand();
          // 处理选项b逻辑
          break;
        case 'c':
          this.finalVersion();
          // 处理选项b逻辑
          break;
        case 'd':
          this.showHistory();
          // 处理选项c逻辑
          break;
        case 'e':
          // 处理选项d逻辑
          this.deleteDialog();
          break;
      }
      // 关闭菜单
      this.contextMenuVisible = false;
    },
    // 复用路径截取函数
    getLastPartOfPath(path) {
      if (!path || typeof path !== 'string') return '';
      const lastBackslashIndex = path.lastIndexOf('\\');
      return lastBackslashIndex === -1 ? path : path.slice(lastBackslashIndex + 1);
    },
    //转译 多个反斜杠
    fixJsonEscapes(str) {
      // 步骤1：先将所有单个\转义为\\（基础转义修复）
      let fixed = str.replace(/(?<!\\)\\/g, '\\\\');
      
      // // 步骤2：将所有实际换行符（\n）替换为字符串\\n
      // fixed = fixed.replace(/\n/g, '\\n');
      
      // // 步骤3：处理可能存在的\r（回车符）
      // fixed = fixed.replace(/\r/g, '\\r');
          return fixed;
    },
    //测试 新开一个浏览器窗口
    openWangG2InNewWindow(sendStr) {

      let str = "[{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_000_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_000_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:39:07.0578892+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_001_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_001_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:41:46.4181541+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_002_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_002_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:42:06.7153697+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_003_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_003_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:42:25.8314261+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_004_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_004_00_zh_cn\",\"CreationTime\":\"2025-09-01T16:51:02.3778949+08:00\"},{\"Path\":\"C:\\Users\\sw\\Desktop\\net8.0-windows7.0\\DM_Material\\Version\\DMC-testNew2-A-P4-20-00-00A-00001A-A\\DMC-testNew2-A-P4-20-00-00A-00001A-A_005_00_zh_cn\",\"Name\":\"DMC-testNew2-A-P4-20-00-00A-00001A-A_005_00_zh_cn\",\"CreationTime\":\"2025-09-02T15:59:19.5476416+08:00\"}]"
      // let strb = JSON.parse(str);
      console.log("解析的结果",str)
      // // 获取wangG2页面的路由路径
      const wangG2Url = this.$router.resolve({ name: 'WangG2' }).href
      
      // // 打开新窗口，可指定窗口大小和位置
      // window.open(
      //   url, 
      //   '_blank', 
      //   'width=800,height=600,top=100,left=100'
      // )


      // 打开新窗口，假设wangG2.vue的路由路径是/wangG2
      // const wangG2Url = this.$router.resolve({ path: '/wangG2' }).href;

      // 打开新窗口并设置尺寸
      this.wangG2Window = window.open(
        wangG2Url, 
        'WangG2Window', 
        'width=800,height=600,left=200,top=100'
      );
      
      // 检查窗口是否被浏览器拦截
      if (!this.wangG2Window) {
        this.$message.error('窗口被浏览器拦截，请允许弹出窗口');
        return;
      }
      
      // 定时检查窗口是否加载完成并发送数据
      this.checkWindowTimer = setInterval(() => {
        // 窗口已关闭
        if (this.wangG2Window.closed) {
          clearInterval(this.checkWindowTimer);
          this.$message.info('wangG2窗口已关闭');
          return;
        }
        
        try {
          // 尝试发送消息，确保窗口已加载
          this.wangG2Window.postMessage(
            {
              type: 'INIT_DATA',
              // payload: this.dataToSend,
              payload: sendStr,
              sender: 'MainPage'
            },
            window.location.origin // 限制只发送到同源地址
          );
          
          // 发送成功后清除定时器
          clearInterval(this.checkWindowTimer);
          this.$message.success('数据已发送到wangG2窗口');
        } catch (error) {
          // 窗口未加载完成时会抛出错误，继续等待
          console.log('等待wangG2窗口加载...');
        }
      }, 100);
    },
    
    // 将处理逻辑提取为单独的方法，便于绑定和解绑
    handleFilePathSend(e) {
      const newStr = this.parseSpecialString(e.detail);
      console.log('路径接收:', this.currentNode, e, e.detail, newStr);
      
      // 访问 currentNode 前先判断是否存在，避免 null 错误
      if (this.currentNode && this.currentNode.attributes) {
        this.currentNode.attributes.push(newStr);
        this.replaceAttributes();
        console.log("当前节点", this.currentNode, this.treeData);
      } else {
        console.warn('currentNode 不存在或无 attributes 属性');
      }
    },
  },
watch: {
  // 监听新建目录的弹窗状态
  dialogVisibleNav(newVal, oldVal) {
    console.log("弹窗",newVal,oldVal)
    if(newVal == true){
      this.loadFileDMC  = '';
    }
  },
  currentNode(newVal) {
    if (newVal) {
      this.$nextTick(() => {
        // 先销毁旧编辑器
        if (this.editor) {
          this.editor.destroy();
        }
        // 初始化新编辑器
        this.initEditor();
      });
    } else {
      // 节点为空时销毁编辑器
      if (this.editor) {
        this.editor.destroy();
        this.editor = null;
      }
    }
  }
},
created() {
    // let that = this;
    // 方式1：直接访问全局变量
    this.$watch(
      () => this.$dotNetMessage,
      (newMsg) => {
        console.log('收到消息:', newMsg)
      }
    )


    //和后台交互 获取对应的DMC的历史版本列表
    window.addEventListener('GetHistoryVesions', (e) => {
        if(e.detail){
          const aa = this.fixJsonEscapes(e.detail);
          console.log("1第一次接收历史版本信息this.historyData", e.detail,aa)
          this.historyData = JSON.parse(aa);
          console.log("1第二次接收历史版本信息this.historyData", this.historyData)
        }
      })
    
    //和后台交互 暂未使用
    window.addEventListener('GetHistoryDMContent', (e) => {
      console.log('GetHistoryDMContent接收历史版本信息XML:', e.detail)
    })

      

    //和后台交互 新建章节目录时候点击加载DMC文件
    window.addEventListener('GetExistenceDMContent', (e) => {
        // console.log('接收历史版本DMC的XML内容:',e, e.detail)
        
        if(e.detail){
          this.isLoadOldDmc = '2';
          this.showView = true;
          this.loadFileXML = e.detail;
            if (this.loadFileXML.startsWith('"')) {
            this.loadFileXML = this.loadFileXML.substring(1);
          } 
          // 检查并去除结尾的双引号
          if (this.loadFileXML.endsWith('"')) {
            this.loadFileXML = this.loadFileXML.substring(0, this.loadFileXML.length - 1);
          }
          this.parseXmlDmc();
        }
      })


      //和后台交互 接收富文本XML
    window.addEventListener('FrontLoadProjectNew', this.FrontLoadDM_g2)
 
    //和后台交互 接收目录XML
    // window.addEventListener('FrontLoadProjectNew', (e) => {
     
    // })

    //和后台交互 单独获取DM的文文件(暂未使用)
    window.addEventListener('GetDMDta', (e) => {
      // 加载目录
      console.log('GetDMDta 参数接收:',e,e.detail)
        
    })


    //和后台交互 接收富文本XML
    window.addEventListener('FrontLoadDM', this.FrontLoadDM_g1)
 
    //和后台交互 获取文件地址
    window.addEventListener('SendResourcePath', (e) => {
      console.log('拖拽文件地址:',e,e.detail)
    
        let newData = this.zy(e.detail);

        // 1. 去除双引号
        const parsedA = this.lisenPath.replace(/"/g, ''); 
        const parsedB = newData.replace(/"/g, '');
        
        // 2. 处理转义字符（如斜杠）
        const processedA = parsedA.replace(/\\/g, '');
        // const processedB = parsedB.replace(/\\/g, '');
        const processedB = parsedB.replace(/\\\\/g, "\\");
        console.log("processedB",processedB,parsedB)
        // 3. 确保基础URL以斜杠结尾
        let baseUrl = processedA;
        if (baseUrl && !baseUrl.endsWith('/')) {
          baseUrl += '/';
        }

        const cleanedFile = parsedB.replace(/\\/g, '');
        
        // 2. 提取后缀名
        const lastDotIndex = cleanedFile.lastIndexOf('.');
        const suffix = cleanedFile.substring(lastDotIndex + 1).toLowerCase();
// allImgType allMusicType allVideoType
        console.log("后缀",suffix)

        
        switch (this.isImageSuffix(suffix)){
          case 'img':
              this.insertImage( baseUrl + processedB)
              // this.insertImage( baseUrl + '/zw.jpg') 
            break;
          case 'music':
              this.insertAudio( baseUrl + processedB)
            break;
          case 'video':
              this.insertVideo( baseUrl + processedB)
            break;
          case '3d':
              this.insert3d(baseUrl + '/zw.jpg')
            break;
          default:
              this.$message({
                message: '当前文件不支持',
                type: 'warning'
              });
            break;
        }
    })

     console.log('监听器开始注册11：', Date.now()) // 打印注册时间戳
    //和后台交互 获取文件地址
    window.addEventListener('SendLisentPath', this.SendLisentPathFun)

    //和后台交互 获取项目名
    window.addEventListener('SendProjectName', (e) => {
      this.domNameStr[1] = this.removeQuotationMarks(e.detail);
      console.log('获取项目文件夹名子：',this.domNameStr,e,e.detail)
      this.isLoadMsg = true;
    })
     
  
    //和后台交互 定稿之后获取最新的dm名称
    window.addEventListener('SendNewVersionDMFileName', (e) => {
      console.log("定稿以后的信息",e.detail)
      let str = this.removeQuotationMarks(e.detail);
      console.log("定稿以后的 str",str)
      const firstUnderline = str.indexOf('_');
      console.log("定稿以后的 firstUnderline",firstUnderline)
      const secondUnderline = str.indexOf('_', firstUnderline + 1);
      console.log("节点属性",this.currentNode)
      console.log("定稿以后的secondUnderline",secondUnderline)
      if(this.currentNode){
        this.currentNode.lagreVersion =str.substring(
          firstUnderline + 1, 
          secondUnderline
        );
        this.updateNodeVersion(this.currentNode.id,this.currentNode.lagreVersion)
        console.log("定稿以后的currentNode",this.currentNode)
        console.log("定稿以后的树",this.treeData)
        this.catalogueAnalysis(this.treeData);
      }
    })


    //和后台交互 获取加载时候的DMC文件预览服务器端口号
    window.addEventListener('handPrePath', (e) => {
      if(e){
        this.viewLis = e.detail;    
      }
    })
    
    //和后台交互 获取加载时候的DMC文件具体内容
    window.addEventListener('handreContent', (e) => {
      if(e){
        this.maskViewShow = true;
        this.viewXml = e.detail;
          if (this.viewLis.startsWith('"')) {
          this.viewXml = this.viewXml.substring(1);
        } 
        // 检查并去除结尾的双引号
        if (this.viewXml.endsWith('"')) {
          this.viewXml = this.viewXml.substring(0, this.viewXml.length - 1);
        } 
        console.log("得到的0",this.viewXml)
          this.parseRdfDescriptions(this.viewXml)
        this.parseXmlDmc_loadFile();

      }
    })
    // window.addEventListener('handleMessageFromDotNet', this.fun1)
  }, 
}
</script>  
<style scoped>
.drag-handle {
  position: absolute;
  top: 0;
  right: 0;
  width: 5px;
  height: 100%;
  cursor: col-resize;
  /* background-color: #aaa; */
  background-color: rgba(0,0,0,.1);
  z-index: 2;
}

.drag-handle:hover {
  /* background-color: #666; */
}
.el-main{
  padding:0 10px ;
}
</style>