<template>
  <div class="doc-container">
    <div class="editor-top">
      <div class="left">
        <div class="doc" v-if="type == 'document'">
          <span>当前打开文档：</span
          >{{ docAttr.title == "" ? "新建文档" : docAttr.title }}
        </div>
        <div class="doc" v-else-if="type == 'module'">
          <span>当前打开模块：</span
          >{{ coms[0].name == "" ? "新建模块" : coms[0].name }}
        </div>
        <div class="doc" v-else>
          <span>当前打开模版：</span
          >{{ docAttr.title == "" ? "新建模版" : docAttr.title }}
        </div>
        <div class="creator">
          <span>创建者：</span
          ><!-- {{ userInfo && userInfo.username }} -->
        </div>
      </div>
      <div class="right">
        <el-button
          type="primary"
          size="mini"
          @click="onSaveAs"
          v-if="
            type !== 'module' && type == 'document' && articleId == undefined
          "
          >保存文档</el-button
        ><!-- v-if="docAttr.id > 0" -->
        <el-button
          type="primary"
          size="mini"
          @click="renew"
          v-if="
            articleId !== undefined && type !== 'module' && type == 'document'
          "
          >更新文档</el-button
        >
        <!-- <el-popover
          placement="bottom"
          trigger="click"
          v-if="type !== 'module' && type !== 'document'"
        > -->
        <el-button
          type="primary"
          v-if="type !== 'module' && type !== 'document' && !articleId"
          @click="onSaveUpload"
          >保存</el-button
        >
        <el-button
          type="primary"
          v-if="type !== 'module' && type !== 'document' && articleId"
          @click="onUpload"
          >更新</el-button
        >
        <!-- <el-button
            slot="reference"
            type="primary"
            size="mini"
            style="margin: 0 10px"
            v-if="$store.state.user.name == 'admin'"
            >保存并更新模版</el-button
          >
        </el-popover> -->
        <!-- <el-button
          type="primary"
          size="mini"
          v-if="$store.state.user.name == 'admin'"
          @click="onSaveUpload"
          >保存并更新模版</el-button
        > -->
        <el-button
          type="primary"
          size="mini"
          v-if="type !== 'module' && type == 'document'"
          @click="onOpenView"
          >预览导出
        </el-button>
        <el-button type="primary" size="mini" @click="onClose">
          关闭文档
        </el-button>
      </div>
    </div>
    <div class="editor-content">
      <!-- 文档选择面板 -->
      <div
        class="left_scheme"
        v-if="type !== 'module'"
        :class="{ collapsed: isSchemeCollapsed }"
      >
        <div class="scheme-header">
          <div class="title">
            请选择文档
            <i class="el-icon-menu" @click="toggleSchemePanel"></i>
          </div>
          <div class="search">
            <el-input
              v-model="searchKey"
              placeholder="请输入搜索"
              prefix-icon="el-icon-search"
              clearable
              @keyup.enter.native="handleSearch"
              @clear="handleClear"
            >
            </el-input>
          </div>
          <!-- <div class="action-btns">
            <el-button type="primary" size="small" @click="createScheme"
              >新建方案</el-button
            >
            <el-button type="primary" size="small" @click="createCategory"
              >新建分类</el-button
            >
          </div> -->
          <div class="current-scheme">
            当前文档: {{ currentScheme || "已选择方案三" }}
          </div>
        </div>

        <div class="scheme-content" v-show="!isSchemeCollapsed">
          <el-tree
            :data="schemeData"
            :props="defaultProps"
            @node-click="handleNodeClick"
            :default-expanded-keys="expandedKeys"
            node-key="id"
            ref="documentTree"
          >
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span @click="onLoadArticle(data.id)">
                <i class="el-icon-folder" v-if="data.children"></i>
                <i class="el-icon-document" v-else></i>
                {{ node.label }}
              </span>
            </span>
          </el-tree>
        </div>
      </div>

      <!-- 资源面板 -->
      <div class="natural" :class="{ collapsed: isResourceCollapsed }">
        <div class="resource-header-title">
          <div class="title-left">
            <span>请选择模块</span>
          </div>
          <i class="el-icon-menu" @click="toggleResourcePanel"></i>
        </div>
        <div class="resource-container" v-show="!isResourceCollapsed">
          <div class="resource-header">
            <el-input
              v-model="templateSearchKey"
              placeholder="请输入选择"
              prefix-icon="el-icon-search"
              clearable
              @keyup.enter.native="handleTemplateSearch"
              @clear="handleResourceClear"
            >
            </el-input>
            <!--  <div class="action-btns">
              <el-button type="primary" @click="createResource"
                >新建资源</el-button
              >
              <el-button type="primary" @click="createResourceCategory"
                >新建资源分类</el-button
              >
            </div> -->
          </div>

          <!-- <div class="resource-status">
            已打开1个资源，已选择3个资源
            <el-button size="small" plain @click="refreshResources"
              >更新</el-button
            >
          </div> -->

          <div class="resource-content">
            <el-collapse v-model="activeCategories">
              <el-collapse-item
                v-for="(category, index) in categoryList"
                :key="index"
                :title="category.name"
                :name="category.id"
              >
                <template slot="title">
                  <span>{{ category.name }}</span>
                </template>
                <div class="resource-list">
                  <draggable
                    v-model="category.templates"
                    :options="{
                      group: { name: 'itxst', pull: 'clone' },
                      sort: true,
                    }"
                    :disabled="type == 'module'"
                    @end="handleDragEnd"
                  >
                    <transition-group>
                      <div
                        v-for="template in category.templates"
                        :key="template.dcb_id || template.name"
                        class="resource-item"
                        :data-template-id="template.dcb_id"
                      >
                        <el-checkbox
                          v-model="template.selected"
                          @change="
                            (val) =>
                              handleTemplateSelect(category, template, val)
                          "
                          :disabled="isTemplateUsed(template)"
                        >
                          {{ template.dcb_name }}
                        </el-checkbox>
                      </div>
                    </transition-group>
                  </draggable>
                </div>
              </el-collapse-item>
            </el-collapse>
          </div>
        </div>
      </div>

      <!--  <div class="neary-doc">
        <div class="left-content">
          <div class="new-article">
            <div v-if="showView == 0 && type !== 'module'">
              <el-collapse v-model="activeNames">
                <el-collapse-item
                  title="最新文档"
                  name="-1"
                  v-if="type == 'document'"
                >
                  <div
                    v-for="(it, index) in articleList"
                    draggable
                    :key="it.id"
                    :data-index="index"
                    data-type="article"
                    class="sub-menus"
                  >
                    <div @click="onLoadArticle(it.id)" style="cursor: pointer">
                      {{ it.title }}
                    </div>
                  </div>
                </el-collapse-item>
                <el-collapse-item
                  title="模版列表"
                  name="-2"
                  v-if="showView == 0"
                >
                  <div
                    v-for="(it, index) in templateList"
                    draggable
                    :key="it.id"
                    :data-index="index"
                    data-type="article"
                    class="sub-menus"
                  >
                    <div @click="onTemplateInfo(it.id)" style="cursor: pointer">
                      {{ it.title }}
                    </div>
                  </div>
                </el-collapse-item>
              </el-collapse>
            </div>
            <div v-if="showView == 1" class="scrollable-container">
              <el-collapse
                v-model="activeModel"
                :accordion="true"
                @change="handleItemClick"
                class="borderless-collapse"
              >
                <el-collapse-item
                  v-for="(item, itemIndex) in categoryList"
                  :key="itemIndex"
                  :title="item.name"
                  :name="item.id"
                  class="min-width-content"
                >
                  <el-collapse
                    v-if="item.children && item.children.length"
                    v-model="item.activeChildren"
                    @change="handleItemVal"
                    v-show="item.children"
                    class="borderless-collapse"
                  >
                    <el-collapse-item
                      v-for="(child, childIndex) in item.children"
                      :key="childIndex"
                      :title="child.name"
                      :name="child.id"
                      class="min-width-content"
                    >
                      <el-collapse
                        v-if="child.children && child.children.length"
                        v-model="child.activeChildren"
                        @change="handleChildItemVal"
                        v-show="child.children"
                        class="borderless-collapse"
                      >
                        <el-collapse-item
                          v-for="(
                            grandChild, grandChildIndex
                          ) in child.children"
                          :key="grandChildIndex"
                          :title="grandChild.name"
                          :name="grandChild.id"
                          class="min-width-content"
                        >
                          <el-collapse
                            v-if="
                              grandChild.children && grandChild.children.length
                            "
                            v-model="grandChild.activeChildren"
                            @change="handleGrandChildItemVal"
                            v-show="grandChild.children"
                            class="borderless-collapse"
                          >
                            <el-collapse-item
                              v-for="(
                                greatGrandChild, greatGrandChildIndex
                              ) in grandChild.children"
                              :key="greatGrandChildIndex"
                              :title="greatGrandChild.name"
                              :name="greatGrandChild.id"
                              class="min-width-content"
                            >
                              <el-collapse
                                v-if="
                                  greatGrandChild.children &&
                                  greatGrandChild.children.length
                                "
                                v-model="greatGrandChild.activeChildren"
                                @change="handlegreatGrandChildItemVal"
                                v-show="greatGrandChild.children"
                                class="borderless-collapse"
                              >
                                <el-collapse-item
                                  v-for="(
                                    fiveChild, fiveIndex
                                  ) in greatGrandChild.children"
                                  :key="fiveIndex"
                                  :title="fiveChild.name"
                                  :name="fiveChild.id"
                                  class="min-width-content"
                                >
                                  <draggable
                                    v-model="fiveChild.dataList"
                                    :options="{
                                      group: { name: 'itxst', pull: 'clone' },
                                      sort: true,
                                    }"
                                    :disabled="type === 'module'"
                                  >
                                    <transition-group>
                                      <div
                                        class="sub-menus min-width-content"
                                        v-for="(
                                          fiveIts, fiveIndex
                                        ) in fiveChild.dataList"
                                        :key="fiveIndex"
                                      >
                                        <div style="cursor: move">
                                          {{ fiveIts.name }}
                                        </div>
                                      </div>
                                    </transition-group>
                                  </draggable>
                                </el-collapse-item>
                              </el-collapse>
                              <draggable
                                v-model="greatGrandChild.dataList"
                                :options="{
                                  group: { name: 'itxst', pull: 'clone' },
                                  sort: true,
                                }"
                                :disabled="type == 'module'"
                              >
                                <transition-group>
                                  <div
                                    class="sub-menus min-width-content"
                                    v-for="(
                                      its, index
                                    ) in greatGrandChild.dataList"
                                    :key="index"
                                  >
                                    <div style="cursor: move">
                                      {{ its.name }}
                                    </div>
                                  </div>
                                </transition-group>
                              </draggable>
                            </el-collapse-item>
                          </el-collapse>
                          <draggable
                            v-model="grandChild.dataList"
                            :options="{
                              group: { name: 'itxst', pull: 'clone' },
                              sort: true,
                            }"
                            :disabled="type == 'module'"
                          >
                            <transition-group>
                              <div
                                class="sub-menus min-width-content"
                                v-for="(it, index) in grandChild.dataList"
                                :key="index"
                              >
                                <div style="cursor: move">{{ it.name }}</div>
                              </div>
                            </transition-group>
                          </draggable>
                        </el-collapse-item>
                      </el-collapse>
                      <draggable
                        v-model="child.dataList"
                        :options="{
                          group: { name: 'itxst', pull: 'clone' },
                          sort: true,
                        }"
                        :disabled="type == 'module'"
                      >
                        <transition-group>
                          <div
                            class="sub-menus min-width-content"
                            v-for="(it, index) in child.dataList"
                            :key="index"
                          >
                            <div style="cursor: move">{{ it.name }}</div>
                          </div>
                        </transition-group>
                      </draggable>
                    </el-collapse-item>
                  </el-collapse>
                  <draggable
                    v-model="item.dataList"
                    :options="{
                      group: { name: 'itxst', pull: 'clone' },
                      sort: true,
                    }"
                    :disabled="type == 'module'"
                  >
                    <transition-group>
                      <div
                        class="sub-menus min-width-content"
                        v-for="(it, index) in item.dataList"
                        :key="index"
                      >
                        <div style="cursor: move">{{ it.name }}</div>
                      </div>
                    </transition-group>
                  </draggable>
                </el-collapse-item>
              </el-collapse>
            </div>
          </div>
        </div>
        <div class="right-sidebarew">
          <div
            v-if="type !== 'module'"
            class="sidebar-item"
            :class="showView == 0 ? 'active-item' : ''"
            @click="viewDocument"
          >
            <span v-if="type == 'document'">查看文档</span>
            <span v-else>查看模版</span>
          </div>
          <div
            v-if="type !== 'document'"
            class="sidebar-item"
            :class="showView == 1 ? 'active-item' : ''"
            @click="viewModule"
          >
            模块列表
          </div>
        </div>
      </div> -->
      <div class="leftContent">
        <div class="catalog-content">
          <!-- 目录内容展示区域 -->
          <el-tree
            :data="catalogData"
            :props="catalogProps"
            default-expand-all
            @node-click="handleCatalogClick"
            draggable
            :allow-drop="allowDrop"
            :allow-drag="allowDrag"
            @node-drag-end="handleDragEnd"
          >
            <span class="custom-tree-node" slot-scope="{ data }">
              <span v-if="data.isEditing">
                <el-input
                  v-model="data.editingContent"
                  size="mini"
                  @blur="handleEditComplete(data)"
                  @keyup.enter.native="handleEditComplete(data)"
                  ref="editInput"
                ></el-input>
              </span>
              <span v-else @dblclick="handleStartEdit(data)">
                {{ data.label }}
              </span>
            </span>
          </el-tree>
        </div>
      </div>
      <div class="editor-main">
        <!-- 添加tab页导航 -->
        <div class="editor-tabs">
          <el-tabs v-model="activeTab" type="card" @tab-click="handleClick">
            <el-tab-pane label="目录" name="catalog">
              <div class="catalog-content">
                <!-- 目录内容展示区域 -->
                <el-tree
                  v-if="activeTab === 'catalog'"
                  :data="catalogData"
                  :props="{ children: 'children', label: 'label' }"
                  node-key="id"
                  draggable
                  @node-drag-end="handleDirectoryDragEnd"
                >
                  <span class="custom-tree-node" slot-scope="{ node, data }">
                    <template v-if="data.isEditing">
                      <el-input
                        v-model="data.content"
                        :ref="`directory-input-${data.id}`"
                        size="mini"
                        @blur="handleDirectorySave(data)"
                        @keyup.enter.native="handleDirectorySave(data)"
                      />
                    </template>
                    <template v-else>
                      <span @dblclick="handleDirectoryEdit(data)">{{
                        data.label
                      }}</span>
                      <span class="directory-actions">
                        <el-button
                          type="text"
                          size="mini"
                          @click="handleDirectoryEdit(data)"
                        >
                          编辑
                        </el-button>
                      </span>
                    </template>
                  </span>
                </el-tree>
              </div>
            </el-tab-pane>
            <el-tab-pane label="模板内容" name="template">
              <div class="template-content">
                <!-- <div class="search-box">
                  <el-input
                    v-model="templateSearchKey"
                    placeholder="搜索模板"
                    @keyup.enter="handleTemplateSearch"
                    clearable
                    @clear="handleTemplateClear"
                  >
                    <i slot="prefix" class="el-input__icon el-icon-search"></i>
                  </el-input>
                </div> -->

                <!-- 原有的menus和editor内容 -->
                <div class="menus-box">
                  <menus
                    @onEvents="onInsert"
                    @onVariable="uptadeVariable"
                    :comArr="coms"
                  ></menus>
                </div>
                <div
                  class="editor-box"
                  ref="tabHtml"
                  v-loading="loading"
                  element-loading-text="加载中..."
                  element-loading-spinner="el-icon-loading"
                >
                  <editor
                    ref="editor"
                    :coms="coms"
                    :comIndex="comIndex"
                    :isAdmin="isAdmin"
                    :templateCate="categoryList"
                    :insertCmd="insertCmd"
                    @onSetActiveIndex="onSetActiveIndex"
                    @onInsert="onInsert"
                    @onLoadArticle="onLoadArticle"
                    @onRebuild="onRebuild"
                    @onDelete="onRemove"
                    @onSetComs="onSetComs"
                  ></editor>
                </div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
      <div class="module-list-container">
        <draggable
          v-model="coms"
          @add="onAdd"
          @update="onDragEnd"
          @end="onDragComplete"
          group="itxst"
          animation="300"
          handle=".drag-handle"
          :scroll="true"
          :scrollSensitivity="100"
          :scrollSpeed="20"
        >
          <transition-group style="display: block">
            <template v-for="(it, index) in coms">
              <div
                :key="index"
                class="module-item"
                :class="comIndex == index ? 'active-module' : ''"
              >
                <div class="drag-handle">
                  <img
                    src="@/icons/svg/drag.svg"
                    style="width: 20px"
                    icon-class="drag"
                  />
                </div>
                <div class="module-info">
                  <div class="module-content">
                    <div class="module-category">
                      <span class="label">模块分类:</span>
                      <span class="value">{{
                        getCategory(it.category_id)
                      }}</span>
                    </div>
                    <div class="module-name">
                      <span class="label">模块名称:</span>
                      <span class="value">{{ it.dcb_name }}</span>
                    </div>
                  </div>
                </div>
                <div class="module-actions">
                  <el-button
                    v-if="type !== 'document'"
                    type="text"
                    size="mini"
                    @click="onSaveTemplate(it)"
                  >
                    <i class="el-icon-document-add"></i> 保存
                  </el-button>
                  <el-button
                    type="text"
                    size="mini"
                    @click="onEdit(index, it.isEdit !== 1 ? 1 : 2)"
                  >
                    <i :class="it.isEdit !== 1 ? 'el-icon-edit' : 'el-icon-view'"></i>
                    {{ it.isEdit !== 1 ? "编辑" : "预览" }}
                  </el-button>
                  <el-button
                    type="text"
                    size="mini"
                    @click="onRemove(index)"
                  >
                    <i class="el-icon-delete"></i> 删除
                  </el-button>
                </div>
              </div>
            </template>
          </transition-group>
        </draggable>
      </div>
    </div>

    <!-- 新增资源选择弹框 -->
    <!--  <el-dialog
      title="请选择可用的资源"
      :visible.sync="resourceDialogVisible"
      width="800px"
      custom-class="resource-dialog"
    >
      <div class="resource-container">
        <div class="resource-header">
          <el-input
            v-model="resourceSearchKey"
            placeholder="请输入选择"
            prefix-icon="el-icon-search"
            clearable
          >
          </el-input>
          <div class="action-btns">
            <el-button type="primary" @click="createResource"
              >新建资源</el-button
            >
            <el-button type="primary" @click="createResourceCategory"
              >新建资源分类</el-button
            >
          </div>
        </div>

        <div class="resource-status">
          已打开1个资源，已选择3个资源
          <el-button size="small" plain @click="refreshResources"
            >更新</el-button
          >
        </div>

        <div class="resource-content">
          <el-collapse v-model="activeCategories">
           
            <el-collapse-item name="dlp">
              <template slot="title">
                <span>DLP产品</span>
                <i class="el-icon-arrow-up"></i>
              </template>
              <div class="resource-list">
                <div
                  v-for="item in dlpProducts"
                  :key="item.id"
                  class="resource-item"
                >
                  <el-checkbox v-model="item.selected">
                    {{ item.name }}
                  </el-checkbox>
                  <i class="el-icon-menu"></i>
                </div>
              </div>
            </el-collapse-item>

      
            <el-collapse-item name="led">
              <template slot="title">
                <span>LED产品系列</span>
                <i class="el-icon-arrow-up"></i>
              </template>
              <div class="resource-list">
                <div
                  v-for="item in ledProducts"
                  :key="item.id"
                  class="resource-item"
                >
                  <el-checkbox v-model="item.selected">
                    {{ item.name }}
                  </el-checkbox>
                  <i class="el-icon-menu"></i>
                </div>
              </div>
            </el-collapse-item>

        
            <el-collapse-item name="processor">
              <template slot="title">
                <span>处理器</span>
                <i class="el-icon-arrow-up"></i>
              </template>
              <div class="resource-list">
                <div
                  v-for="item in processors"
                  :key="item.id"
                  class="resource-item"
                >
                  <el-checkbox v-model="item.selected">
                    {{ item.name }}
                  </el-checkbox>
                  <i class="el-icon-menu"></i>
                </div>
              </div>
            </el-collapse-item>

           
            <el-collapse-item name="service">
              <template slot="title">
                <span>售后服务</span>
                <i class="el-icon-arrow-up"></i>
              </template>
              <div class="resource-list">
                <div
                  v-for="item in services"
                  :key="item.id"
                  class="resource-item"
                >
                  <el-checkbox v-model="item.selected">
                    {{ item.name }}
                  </el-checkbox>
                  <i class="el-icon-menu"></i>
                </div>
              </div>
            </el-collapse-item>
          </el-collapse>
        </div>
      </div>
    </el-dialog> -->

    <el-dialog
      :visible.sync="showViewForm"
      :close-on-click-modal="false"
      append-to-body
      v-el-drag-dialog
      width="850px"
      custom-class="prod-verify"
      title="文档预览"
    >
      <ViewForm :coms="coms" :docAttr="docAttr"></ViewForm>
    </el-dialog>

    <el-dialog
      :visible.sync="showProductAttr"
      append-to-body
      v-el-drag-dialog
      :close-on-click-modal="false"
      width="850px"
      custom-class="prod-verify"
      title="插入产品属性"
    >
      <ProductAttr
        :docAttr="docAttr"
        @onInsertProductAttr="onInsertProductAttr"
      ></ProductAttr>
    </el-dialog>
    <el-dialog
      :visible.sync="docVisible"
      append-to-body
      v-el-drag-dialog
      :close-on-click-modal="false"
      width="500px"
      custom-class="prod-verify"
      title="文档信息"
    >
      <el-form
        :model="docForm"
        :rules="docRules"
        ref="docRef"
        label-width="120px"
      >
        <el-form-item label="文档标题:" prop="dcm_title">
          <el-input
            v-model="docForm.dcm_title"
            style="width: 60%"
            class="input-item"
            placeholder="请填写文档标题"
            :disabled="docAttr.id > 0"
          />
        </el-form-item>

        <el-form-item label="文档模板类别:" prop="dcm_type">
          <el-select
            v-model="docForm.dcm_type"
            style="width: 60%"
            placeholder="请选择文档模板类别"
            :disabled="docAttr.id > 0"
          >
            <!--  <el-option
              v-for="(item, index) in articleCategoryList"
              :key="index"
              :label="item.name"
              :value="item.id"
            /> -->
            <el-option label="官方模板" :value="1" />
            <el-option label="私有模板" :value="2" />
            <el-option label="共享模板" :value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="文档分类:">
          <el-select
            v-model="docForm.dcm_category_id"
            style="width: 60%"
            placeholder="请选择文档模板类别"
            :disabled="docAttr.id > 0"
            ><el-option
              v-for="(item, index) in articleCategoryList"
              :key="index"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
          <!-- {{ userInfo && userInfo.username }} -->
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDoc">取 消</el-button>
        <el-button type="primary" @click="submitDoc">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { findData } from "@/api/sourceData";
/* import utils from "@/utils/fun"; // 方法类 */
import { searchDocument, pageDocument } from "@/api/document";
import menus from "./com/menus";
import editor from "./com/editor";
import Attribute from "./com/components/Attribute";
import attributeVar from "./com/components/Attribute/attributeVar/index.vue";
import ProductAttr from "./com/components/ProductAttr";
import {
  searchTemplateCategory,
  searchTemplate,
  getTemplateInfo,
  getAllCategory,
  createTemplate,
  updateTemplate,
} from "@/api/template";
import docAttr from "./com/components/Attribute/docAttr";
import comList from "./com/components/Attribute/comList";
import Directory from "./com/components/Attribute/Directory";
import { getCurrentUserInfo } from "@/api/api";
import {
  createDocument,
  updateDocument,
  getDocumentInfo,
  exportDocument,
  searchDocumentCategory,
} from "@/api/document";
import ViewForm from "./com/view";
import elDragDialog from "@/directive/el-drag-dialog";
import draggable from "vuedraggable";
import htmlDocx from "html-docx-js/dist/html-docx";
import { searchFormula } from "@/api/formula";
import axios from "axios";
import settings from "@/settings";
// import htmlDocx from "htmlDocx";
export default {
  name: "create",
  components: {
    menus,
    editor,
    Attribute,
    comList,
    docAttr,
    ViewForm,
    ProductAttr,
    Directory,
    draggable,
    attributeVar,
  },
  directives: {
    elDragDialog,
  },
  data() {
    return {
      activeNames: "-1",
      nestedActiveNames: [],
      articleList: [],
      activeModel: "",
      templateList: [],
      categoryList: [],
      //组件相关
      coms: [],
      comIndex: 9999, //当前组件索引
      showProductAttr: false,
      comList: [],
      //文档属性
      docAttr: {
        id: 0,
        dcm_category_id: "",
        title: "",
        content: "",
        status: 5,
        links: "",
        linkProduct: [],
        linkProject: [],
        projects: "",
      },
      insertCmd: null,
      showViewForm: false,
      isAdmin: 2, //1是管理员，2非管理员
      //当前选中表格
      tabExt: {
        row: 0,
        col: 0,
      },
      userInfo: null,
      articleId: 0,
      loading: false, // 增加 loading 状态
      showView: 0, //查看 文档/模块
      childrenList: "",
      value: [],
      AttributeIndex: 0,
      catalogIndex: 0, //目录信息
      docuComIndex: 3,
      type: "",
      docVisible: false,
      docForm: {
        dcm_title: "",
        dcm_type: "",
        dcm_category_id: "",
      },
      docRules: {
        dcm_title: [
          { required: true, message: "请输文档名称", trigger: "blur" },
        ],
        dcm_type: [
          { required: true, message: "请选择文档模板分类", trigger: "change" },
        ],
        dcm_category_id: [
          { required: true, message: "请选择文档分类", trigger: "change" },
        ],
      },
      articleCategoryList: [],

      //方案
      searchKey: "",
      currentScheme: "",
      expandedKeys: [], // 默认展开的节点
      schemeData: [],
      defaultProps: {
        children: "children",
        label: "label",
      },
      /* 资源 */
      resourceDialogVisible: false,
      resourceSearchKey: "",
      activeCategories: ["dlp", "led", "processor", "service"],
      dlpProducts: [
        { id: 1, name: "产品选型/DLP/单元/", selected: false },
        { id: 2, name: "产品选型/DLP/机芯/", selected: true },
        { id: 3, name: "产品选型/DLP/控制盒/", selected: true },
      ],
      ledProducts: [
        { id: 4, name: "产品选型/LED/黄河系/", selected: false },
        { id: 5, name: "产品选型/LED/华夏系/", selected: true },
        { id: 6, name: "产品选型/LED/黄河单元/", selected: false },
      ],
      processors: [
        { id: 7, name: "产品选型/处理器/D301/", selected: false },
        { id: 8, name: "产品选型/处理器/IPWH300/", selected: false },
        { id: 9, name: "产品选型/处理器/IPWD400/", selected: false },
      ],
      services: [
        { id: 10, name: "产品选型/处理器/IPWH300/", selected: false },
        { id: 11, name: "产品选型/处理器/IPWH301/", selected: false },
        { id: 12, name: "产品选型/处理器/IPWD400/", selected: false },
      ],

      /* 目录/模板 */

      activeTab: "template", // 默认显示模板内容tab
      catalogData: [], // 目录数据
      catalogProps: {
        children: "children",
        label: "label",
      },
      templateSearchKey: "", // 添加模板搜索关键字
      originalTemplateList: [], // 保存原始模板列表
      isSaving: false,
      saveAs: false,
      isSchemeCollapsed: false,
      isResourceCollapsed: false,
    };
  },
  watch: {
    coms: {
      handler(newComs, oldComs) {
        this.updateAttrs(newComs, oldComs);
      },
      immediate: true, //立即执行
      deep: true,
    },
    articleId: {
      handler(val) {
        if (val == null || val == undefined || val <= 0) return;
        if (this.$route.query.type == "document") {
          this.loadArticle(val);
        } else {
          this.onTemplateInfo(val);
        }
        //
      },
      immediate: true,
      deep: true,
    },
    coms: {
      handler(newComs) {
        this.updateCatalog(newComs);
      },
      deep: true,
    },
    comIndex: {
      handler(newIndex) {
        // 高亮当前选中模块对应的目录项
        this.$nextTick(() => {
          this.highlightCurrentCatalogItem(newIndex);
        });
      },
    },
  },

  async mounted() {
    this.articleId = this.$route.query.articleId;
    this.type = this.$route.query.type;
    if (this.type == "module") {
      this.showView = 1;
    }

    this.searchArticle();
    await this.initCategoryList();
    await this.initCurrentUser();
    let templateId = this.$route.query.templateId;
    if (templateId > 0) {
      this.loadTemplateInfo(templateId);
    }
    this.isAdmin = 2; //this.userInfo ? this.userInfo.roleInfo.is_admin : 2;
    this.initArticleCategoryList();
    if (this.type !== "module" && this.type !== "document") {
      document.title = "新建模版-" + settings.title;
    }
    if (
      this.type !== "module" &&
      this.type !== "document" &&
      this.articleId !== undefined
    ) {
      document.title = this.docAttr.title + settings.title;
    }
    this.$nextTick(() => {
      const arrows = document.querySelectorAll(".el-collapse-item__arrow");
      arrows.forEach((arrow) => {
        arrow.style.margin = "0";
      });
    });
    this.initTemplateSelection();
    this.expandedKeys = []; // 初始化展开节点数组
    //this.initCatalog(); // 初始化目录
  },

  methods: {
    /* 切换目录/模板 */
    handleClick(val) {
      if (val.name === "catalog") {
        this.updateCatalog(this.coms);
      }
    },

    // 更新目录数据
    updateCatalog(modules) {
      let catalogData = [];

      modules.forEach((module, moduleIndex) => {
        // 获取并排序目录类型的属性
        const directoryAttrs = module.attrs
          .filter((attr) => attr.type === "Directory")
          .sort((a, b) => {
            // 首先按层级排序
            if (a.level !== b.level) return a.level - b.level;
            // 同层级按编号自然排序
            return a.number.localeCompare(b.number, undefined, {
              numeric: true,
            });
          });

        directoryAttrs.forEach((attr) => {
          const catalogItem = {
            id: attr.id,
            label: `${attr.number} ${attr.content}`,
            level: attr.level,
            moduleIndex: moduleIndex,
            content: attr.content,
            number: attr.number,
            children: [],
            isEditing: false,
          };

          // 根据level确定目录层级
          if (attr.level === 1) {
            catalogData.push(catalogItem);
          } else {
            // 查找父级目录并添加为子项
            const parent = this.findParentDirectory(catalogData, attr.number);
            if (parent) {
              parent.children.push(catalogItem);
            }
          }
        });
      });

      this.catalogData = catalogData;
      this.$nextTick(() => this.$forceUpdate());
    },

    // 添加 findParentDirectory 辅助方法
    findParentDirectory(catalogData, number) {
      const parentNumber = number.split(".").slice(0, -1).join(".");

      const findInChildren = (items) => {
        for (let item of items) {
          if (item.label.startsWith(parentNumber + " ")) {
            return item;
          }
          if (item.children) {
            const found = findInChildren(item.children);
            if (found) return found;
          }
        }
        return null;
      };

      return findInChildren(catalogData);
    },
    /* 方案点击 */
    handleNodeClick(data) {
      console.log(data);
      this.currentScheme = data.label;
      this.resourceDialogVisible = true; // 点击方案时打开资选择弹框
    },

    createScheme() {
      // 实现新建方案逻辑
      this.$message.success("新建方案");
    },
    createCategory() {
      // 实现新建分类逻辑
      this.$message.success("新建分类");
    },
    /* 资源 */
    createResource() {
      this.$message.success("新建资源");
    },
    createResourceCategory() {
      this.$message.success("新建资源分类");
    },
    refreshResources() {
      this.$message.success("刷新资源列表");
    },

    /* 目录模板 */
    handleCatalogClick(data) {
      // 如果正在编辑，不触发其他操作
      if (data.isEditing) return;

      // 其他点击处理逻辑...
      console.log("点击的目录项:", data);
    },

    handleItemVal(value) {
      this.$forceUpdate();
      this.loadChildren(value);
    },
    handleChildItemClick(child) {
      if (!child.children) {
        this.loadChildren(child);
      }
    },
    handleChildItemVal(value) {
      this.$forceUpdate();
      this.loadChildren(value);
    },
    handleGrandChildItemClick(grandChild) {
      if (!grandChild.children) {
        this.loadChildren(grandChild);
      }
    },
    handleGrandChildItemVal(value) {
      this.loadChildren(value);
      this.$forceUpdate();
    },
    handlegreatGrandChildItemVal(greatGrandChild) {
      this.loadChildren(greatGrandChild);
      this.$forceUpdate();
    },
    async loadChildren(category) {
      const category_id = category[category.length - 1];

      try {
        const res = await searchTemplateCategory({ parent_id: category_id });
        if (res.status != 200 || res.data.length == 0) return;
        const newChildren = res.data;
        for (let i = 0; i < newChildren.length; i++) {
          newChildren[i].dataList = await this.getTemplateList(
            newChildren[i].id
          );
        }
        this.insertChildrenById(this.categoryList, category_id, newChildren);
        console.log(this.categoryList);
        this.$forceUpdate(); // Force Vue to re-render the component
      } catch (error) {
        console.error("Error fetching template categories:", error);
      }
    },

    insertChildrenById(list, id, newChildren) {
      for (let item of list) {
        if (item.id === id) {
          this.$set(item, "children", newChildren); // Use Vue.set to ensure reactivity
          return true; // Stop searching once the item is found
        }
        if (item.children && item.children.length > 0) {
          const found = this.insertChildrenById(item.children, id, newChildren);
          if (found) return true; // Stop searching if the item is found in deeper levels
        }
      }
      return false; // Continue searching
    },
    /* 取消新增 */
    closeDoc() {
      this.docVisible = false;
      this.docForm = {
        dcm_title: "",
        dcm_type: "",
        dcm_category_id: "",
      };
    },
    /* 确定新增模块*/
    submitDoc() {
      this.$refs.docRef.validate((valid) => {
        if (valid) {
          this.docAttr.dcm_title = this.docForm.dcm_title;
          this.docAttr.dcm_type = this.docForm.dcm_type;
          this.docAttr.dcm_category_id = this.docForm.dcm_category_id;
          this.onSave();
        }
      });
    },
    //加载文档分类
    initArticleCategoryList() {
      let _this = this;
      searchDocumentCategory({ page: 1, pageSize: 99, status: 5 }).then(
        (res) => {
          if (res.status != 200) return;
          _this.articleCategoryList = res.data.dataList;
        }
      );
    },
    updateAttrs(newComs, oldComs) {
      newComs.forEach((newCom, comIndex) => {
        const oldCom = oldComs[comIndex];
        console.log("oldCom:", oldCom, "newCom:", newCom);
        if (oldCom) {
          newCom.attrs.forEach((newAttr, attrIndex) => {
            const oldAttr = oldCom.attrs[attrIndex];
            if (oldAttr && newAttr.content !== oldAttr.content) {
              // 内容发生变化，进行全局更新
              this.updateGlobalAttr(newAttr.name, newAttr.content);
            }
          });
        }
      });
    },

    updateGlobalAttr(attrId, newContent) {
      // 遍历所有组件，更新匹配的属性
      this.coms.forEach((com) => {
        console.log(com);
        com.attrs.forEach((attr) => {
          // 只更新非 variableNull 类型的属性
          if (attr.name === attrId && attr.type !== "variableNull") {
            attr.content = newContent;
          }
        });

        // 如果是文本区域，更新内容中的占位符
        if (com.dcb_type === "TextArea") {
          com.content = com.content.replace(
            new RegExp(`{{${attrId}}}`, "g"),
            (match) => {
              const attr = com.attrs.find((a) => a.id === attrId);
              if (attr && attr.type !== "variableNull") {
                return newContent;
              }
              return match; // 保留 variableNull 类型的原始占位符
            }
          );
        }
      });

      // 触发视图更新
      this.replaceData(this.coms);
      this.$forceUpdate();
    },

    async replaceData(data) {
      for (let item of this.coms) {
        for (let el of item.attrs) {
          let attrId = el.id;
          if (el.type === "formual") {
            try {
              let formual = await this.analysisFormual(el);
              formual = await this.getRemote(formual);
              el.content = eval(formual);
            } catch (error) {
              console.error("处理公式时出错:", error);
            }
          } else if (el.type === "variableNull") {
            // 保留 variableNull 类型的原始内容
            el.content = el.content || "请输入";
          }
        }
      }
      return data;
    },
    //分析公式
    async analysisFormual(attrs) {
      let _this = this;
      // console.log("开始分析公式:", attrs.formula);
      var pattern = /(\[.*?\]){3}/;
      var formual = attrs.formula;
      var reg = new RegExp(pattern);
      while (true) {
        var items = formual.match(reg);
        if (items == null) break;
        let itemName = items[0];
        // console.log("处理项:", itemName);
        try {
          let data = await _this.getFormualData(itemName);
          // console.log(`获取到的数据: ${itemName} = ${data}`);
          if (data === null || data === undefined || isNaN(data)) {
            console.warn(`获取到的数据无效: ${itemName}`);
            formual = formual.replace(itemName, "(0)");
          } else {
            formual = formual.replace(itemName, `(${parseFloat(data)})`);
          }
        } catch (error) {
          console.error(`处理 ${itemName} 时出错:`, error);
          formual = formual.replace(itemName, "(0)");
        }
      }
      // console.log("分析后的公式:", formual);
      return formual;
    },
    async getFormualData(formualItem) {
      let _this = this;
      // console.log("开始获取公式数据:", formualItem);
      var pattern = /\[(.*?)\]\[(.*?)\]\[(.*?)\]/;
      var reg = new RegExp(pattern);
      let items = formualItem.match(reg);
      // console.log("解析结果:", items);
      let calResult = 0;
      if (items && items[1] == "T") {
        calResult = await _this.getModuleData(items[2], items[3]);
      } else {
        console.warn("无法解析公式项:", formualItem);
      }
      // console.log("计算结果:", calResult);
      return calResult;
    },
    //获取本地文档模块数据
    async getModuleData(code, attrName) {
      let _this = this;
      // console.log(`尝试获取模块数据: code=${code}, attrName=${attrName}`);
      // console.log("当前 coms:", _this.coms);

      let item = _this.coms.filter((o) => o.name == code);
      // console.log(`找到的模块:`, item);

      if (item.length > 0) {
        let attr = item[0].attrs.filter((o) => o.name == attrName);
        // console.log(`找到的属性:`, attr);

        if (attr.length > 0) {
          // console.log(`返回的值:`, attr[0].content);
          return parseFloat(attr[0].content);
        }
      }
      // console.log("未找到匹配的模块或属性，返回 0");
      return 0;
    },

    async getRemote(formual) {
      let _this = this;
      var pattern = /\[(.*?)\]\[(.*?)\]\[(.*?)\]\[(.*?)\]/;
      var reg = new RegExp(pattern);
      while (true) {
        let items = formual.match(reg);
        if (items == null) break;
        if (items[1] == "R") {
          //表示获取远程数据
          var dataIndex = items[4];
          dataIndex = items[4].split(",");
          let calResult = await _this.getRemoteData(
            items[2],
            items[3],
            dataIndex[0],
            dataIndex[1]
          );
          let itemName = items[0];
          // 检查calResult是否为数字
          if (!isNaN(calResult)) {
            formual = formual.replace(
              itemName,
              "(" + parseFloat(calResult) + ")"
            );
          } else {
            formual = formual.replace(itemName, `"${calResult}"`);
          }
          formual = formual.replace(
            itemName,
            "(" + parseFloat(calResult) + ")"
          );
        }
      }
      return formual;
    },
    async getRemoteData(code, sheet, row, col) {
      let _this = this;
      let result = 0;
      let par = {
        code: code,
        sheetName: sheet,
        row: row,
        col: col,
      };

      /*  if (!this.isEditing) {
        this.loading = true;
        this.progress = 0;

        try {
          const updateProgress = setInterval(() => {
            if (this.progress < 90) {
              this.progress += 10;
            }
          }, 100);

          let res = await findData(par);
          if (res.status == 200) {
            result = res.data.result;
          }

          this.progress = 100;
          clearInterval(updateProgress);
        } catch (error) {
          console.error("Error fetching remote data:", error);
        } finally {
          setTimeout(() => {
            this.loading = false;
            this.progress = 0;
          }, 1000);
        }
      } else { */
      // 如果正在编辑，直接获取数据而不显示进度条
      try {
        let res = await findData(par);
        if (res.status == 200) {
          result = res.data.result;
          // 添加数据类型检查和转换
          if (typeof result === "string" && !isNaN(result)) {
            result = parseFloat(result);
          }
        }
      } catch (error) {
        console.error("获取远程数据错误:", error);
      }
      /*   } */

      return result;
    },
    /* 
    handleItemVal(value) {
      console.log(value);
      this.$forceUpdate();
    }, */
    async handleItemClick(item) {
      const category = this.categoryList.find((cat) => cat.id === item);
      if (!category) return;

      if (!category.children) {
        try {
          const res = await searchTemplateCategory({ parent_id: item });
          if (res.status != 200 || res.data.length == 0) return;
          category.children = res.data;
          for (let i = 0; i < category.children.length; i++) {
            category.children[i].dataList = await this.getTemplateList(
              category.children[i].id
            );
          }
        } catch (error) {
          console.error("Error fetching template categories:", error);
        }
      }

      // 触发视图更新
      this.$set(category, "activeChildren", category.activeChildren || []);
    },
    /* 切换标签 */
    viewDocument() {
      this.showView = 0;
    },
    viewModule() {
      this.showView = 1;
    },
    /* 更新变 */
    /*  uptadeVariable(value) {
      for (const item of this.coms) {
        for (const el of item.attrs) {
          if (el.type === "variable") {
            if (el.data.id == value.id) {
              el.content = value.value;
              el.data = value;
            }
          } else if (el.type === "constant") {
            if (el.data.id == value.id) {
              el.content = value.value;
              el.data = value;
            }
          }
        }
      }
    } */
    uptadeVariable(value) {
      const { id, value: newValue } = value;
      this.coms.forEach((item) => {
        item.attrs.forEach((el) => {
          if (
            (el.type === "variable" || el.type === "constant") &&
            el.data.id === id
          ) {
            el.content = newValue;
            el.data = value;
          }
        });
      });
    },
    /* 更新检索内容 */
    async uptadeSearch() {
      for (const item of this.coms) {
        for (const el of item.attrs) {
          if (el.type === "ai") {
            // await this.retrieval(el);
          }
        }
      }
    },
    /* 初始化检索 */
    async retrieval(el) {
      this.loading = true; // 开始加载动画
      try {
        const response = await axios.post(
          "http://58.246.234.210:7860/api/v1/run/3f84a841-cefd-44b3-9555-568cc3b6c2d2?stream=false",
          {
            input_value: el.search,
            output_type: "chat",
            input_type: "chat",
            tweaks: {
              "ChatInput-em6qC": {},
              "ParseData-yO3YQ": {},
              "Prompt-Wj75b": {},
              "ChatOutput-zy9na": {},
              "SplitText-O1knk": {},
              "File-4j6Zd": {},
              "OllamaEmbeddings-xbYXX": {},
              "Chroma-OIejP": {},
              "OllamaModel-04mEO": {},
              "OllamaEmbeddings-UGvLP": {},
              "Chroma-HzukO": {},
            },
          },
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        );

        if (response.status === 200) {
          // 假设返回的数据在 response.data.outputs[0].outputs[0].results.message.data.text 中
          const resultText =
            response.data.outputs[0].outputs[0].results.message.data.text;
          // 将搜索词和生成的内容存在 searchResult 对象中
          el.content = resultText; // 重新赋值给原数组对应 content
        }
      } catch (error) {
        console.error("Error during retrieval:", error);
        this.$message.error("检索失败，请稍后重试");
      } finally {
        this.loading = false; // 结束加载动画
      }
    },
    async loadTemplateInfo(id) {
      try {
        // 获取模板信息
        const { data } = await getTemplateInfo(id);
        console.log(!data.dcb_attrs || !data.dcb_type);
        // 设置默认值
        if (!data.dcb_attrs || !data.dcb_type) {
          Object.assign(data, {
            dcb_attrs: "[]",
            dcb_nr: "请填写内容",
            lay_id: "textArea",
            dcb_type: "TextArea",
          });
        }

        // 设置文档标题
        document.title = data.name
          ? `${data.name}-${settings.title}`
          : "新建模块-" + settings.title;

        // 解析属性
        data.dcb_attrs = JSON.parse(data.dcb_attrs);
        data.content = data.dcb_nr;
        data.type = data.dcb_type;
        data.name = data.dcb_name;
        data.attrs = data.dcb_attrs;
        // 获取公式并更新属性
        const {
          data: { dataList },
        } = await searchFormula({ page: 1, pageSize: 999 });
        console.log(data);
        data.dcb_attrs = data.dcb_attrs.map((item) => {
          const formula = dataList.find((el) => el.id === item.id);
          return formula
            ? { ...item, formula: formula.formula, data: formula }
            : item;
        });
        // 从 content 中提取 {{}} 包裹的 ID
        const contentIds = (data.dcb_nr.match(/{{([^}]+)}}/g) || []).map(
          (match) => match.slice(2, -2).trim()
        );

        // 过滤 attrs，只保留在 content 中出的 ID
        data.dcb_attrs = data.dcb_attrs.filter((item) =>
          contentIds.includes(item.id)
        );

        this.coms = [data];
      } catch (error) {
        console.error("加载模板信息失败:", error);
      }
    },
    onExport(e) {
      let _this = this;
      _this.comIndex = -1;
      let content = _this.$refs.tabHtml.innerHTML;
    },

    onOpenView(e) {
      console.log("this.coms", this.coms);
      this.showViewForm = true;
    },
    onClose() {
      this.$confirm("是否要关闭文档?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.$router.back();
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消",
          });
        });
    },

    loadArticle(e) {
      let _this = this;
      _this.onLoadArticle(e);
      /* getDocumentInfo({
        id: e,
      }).then((res) => {
        if (res.status != 200) return;
        _this.onLoadArticle(res.data);
      }); */
    },

    handleDragStart(e) {
      let data = {};
      if (e.target.dataset.type == "article") {
        let index = e.target.dataset.index;
        data = {
          optType: e.target.dataset.type,
          item: this.articleList[index],
        };
      } else {
        let index = e.target.dataset.index;
        let subIndex = e.target.dataset.subIndex;
        let item = this.categoryList[index].dataList[subIndex];
        delete item.category;
        data = {
          ...item,
          optType: e.target.dataset.type,
          key: "addNew",
          attrs: JSON.parse(item.attrs),
        };
      }
      e.dataTransfer.setData("item", JSON.stringify(data));
      this.operation = "drag";
    },

    onRebuild(comList) {
      try {
        // 深拷贝以避免引用问题
        const newComList = JSON.parse(JSON.stringify(comList));

        // 确保每个组件的属性都被正确处理
        newComList.forEach((com) => {
          // 确保 dcb_attrs 是数组
          if (!Array.isArray(com.dcb_attrs)) {
            com.dcb_attrs = [];
          }

          // 确保 attrs 是数组
          if (!Array.isArray(com.attrs)) {
            com.attrs = [];
          }

          // 处理其他必要的属性
          com.content = com.content || com.dcb_nr || "";
          com.dcb_nr = com.content || com.dcb_nr || "";
          com.type = com.dcb_type || com.type;
          com.name = com.dcb_name || com.name;
        });

        // 更新组件列表
        this.coms = newComList;

        // 保存到本地存储
        this.saveToLocalStorage();
      } catch (error) {
        console.error("重建组件时出错:", error);
        this.$message.error("重建组件失败：" + error.message);
      }
    },

    // 添加一个保存到本地存储的方法
    saveToLocalStorage() {
      try {
        localStorage.setItem("document_coms", JSON.stringify(this.coms));
      } catch (error) {
        console.warn("保存到本地存储失败:", error);
      }
    },

    //初始化当前用户信息
    async initCurrentUser() {
      let _this = this;
      let res = await getCurrentUserInfo();
      if (res.status != 200) return;
      _this.userInfo = res.data;
    },
    //加载文档信息
    async onLoadArticle(id) {
      try {
        this.loading = true;
        // 在加载文档前重置所有模板状态
        this.resetAllTemplateSelections();

        const res = await getDocumentInfo(id);

        if (res.status !== 200) {
          throw new Error("Invalid response status");
        }

        this.docAttr = {
          dcm_id: res.data.dcm_id,
          dcm_type: Number(res.data.dcm_type),
          dcm_category_id: res.data.dcm_category_id,
          dcm_title: res.data.dcm_title,
          content: "",
          status: res.data.status,
          is_template: res.data.is_template,
          linkProduct: res.data.linkProduct,
          links: res.data.links,
          linkProject: res.data.linkProject,
          projects: res.data.projects,
        };
        // 同时更新 docForm
        this.docForm = {
          dcm_title: res.data.dcm_title,
          dcm_type: Number(res.data.dcm_type),
          dcm_category_id: res.data.dcm_category_id, // 确保这个字段也被设置
        };

        const templateData =
          typeof res.data.dcm_data === "string"
            ? JSON.parse(res.data.dcm_data)
            : res.data.dcm_data;

        const updatedComs = await Promise.all(
          templateData.map(async (el) => {
            /* let templateInfo = { data: {} };
            if (this.type !== "document") {
              templateInfo = await getTemplateInfo({ id: el.id });
            } */
            const formulaData = await searchFormula({ page: 1, pageSize: 999 });

            const attrs = el.attrs;
            /* typeof templateInfo.data.attrs === "string"
                ? JSON.parse(templateInfo.data.attrs)
                : templateInfo.data.attrs || []; // Add a fallback empty array */

            attrs.forEach((item) => {
              if (item && item.data && item.data.id) {
                const matchedFormula = formulaData.data.dataList.find(
                  (ite) => ite.id === item.data.id
                );
                if (matchedFormula) {
                  item.data = matchedFormula;
                  item.formula = matchedFormula.formula;
                }
              }
            });

            return { ...el /* , ...templateInfo.data, attrs */ };
          })
        );

        this.coms = updatedComs;
        console.log("coms", updatedComs);

        if (this.type === "document" && this.articleId !== undefined) {
          document.title = `${this.docAttr.title}-${settings.title}`;
        }

        this.uptadeSearch();
        this.initTemplateSelection();
      } catch (error) {
        console.error("Error in onLoadArticle:", error);
      } finally {
        this.loading = false;
      }
    },
    /* 加载模版信息 */
    async onTemplateInfo(id) {
      try {
        this.loading = true;
        // 在加载模板前重置所有模板状态
        this.resetAllTemplateSelections();

        // 获取文档信息
        const res = await getDocumentInfo({ id });

        if (res.status !== 200 || !res.data) {
          throw new Error("无效的响应或未收到数据");
        }

        // 设置文档属性
        this.docAttr = {
          id: this.docAttr.id,
          category_id: Number(this.docAttr.category_id),
          title: res.data.title,
          content: "",
          status: res.data.status,
          is_template: res.data.is_template,
          linkProduct: res.data.linkProduct || [],
          links: res.data.links || "",
          linkProject: res.data.linkProject || [],
          projects: res.data.projects || "",
        };

        // 解析文档数据
        const documentData = res.data.data ? JSON.parse(res.data.data) : [];
        console.log(documentData);
        const updatedComs = await Promise.all(
          documentData.map(async (docEl) => {
            if (!docEl || !docEl.id) {
              console.warn("无效的文档项:", docEl);
              return null;
            }

            // 获取模板信息
            const templateInfo = await getTemplateInfo({ id: docEl.id });
            // 获取公式数据
            const formulaData = await searchFormula({ page: 1, pageSize: 999 });

            // 使用模板的 content 作为基础
            let content = templateInfo.data.content;
            // 使用模板的 attrs 作为基础，排除 Directory 类型
            let attrs = templateInfo.data.attrs
              ? JSON.parse(templateInfo.data.attrs).filter(
                  (attr) => attr.type !== "Directory"
                )
              : [];

            // 从文档数据中提取所有 Directory 类型的属性
            const docDirectories = docEl.attrs.filter(
              (attr) => attr.type === "Directory"
            );

            // 将文档中的 Directory 属性添加到 attrs 中
            attrs = [...attrs, ...docDirectories];

            // 解析 content 中的所有项
            const contentItems = (content.match(/{{([^}]+)}}/g) || []).map(
              (match) => match.slice(2, -2)
            );
            console.log("contentItems", contentItems);
            // 确保 content 中引用的所有 Directory 项都存在于 attrs 中
            contentItems.forEach((itemId) => {
              if (
                itemId.startsWith("Directory_") &&
                !attrs.some((attr) => attr.id === itemId)
              ) {
                const [, moduleIndex, level] = itemId.split("_");
                attrs.push({
                  type: "Directory",
                  id: itemId,
                  name: "目录信息",
                  intro: "目录信息",
                  number: "",
                  content: "",
                  level: parseInt(level),
                  moduleIndex: parseInt(moduleIndex),
                });
              }
            });

            // 更新公式数据
            attrs = attrs.map((item) => {
              if (item.type === "formual" && item.data && item.data.id) {
                const matchedFormula = formulaData.data.dataList.find(
                  (ite) => ite.id === item.data.id
                );
                if (matchedFormula) {
                  return {
                    ...item,
                    data: matchedFormula,
                    formula: matchedFormula.formula,
                  };
                }
              }
              return item;
            });

            // 返回更新后的数据，以模板信息为主，但 Directory 项完全使用文档信息
            return { ...templateInfo.data, attrs, content };
          })
        );

        // 过滤掉无效的组件
        this.coms = updatedComs.filter(Boolean);
        console.log("组件", this.coms);
        console.log("模版", this.docAttr);
        if (this.articleId !== undefined) {
          document.title = `${this.docAttr.title}-${settings.title}`;
        }
        this.uptadeSearch();
        this.initTemplateSelection();
      } catch (error) {
        console.error("加载模板信息时出错:", error);
        this.$message.error("加载模板信息时出错，请稍后重试");
      } finally {
        this.loading = false;
      }
    },
    onRemove(index) {
      const removedComponent = this.coms[index];
      // 移除组件
      this.coms.splice(index, 1);

      // 如果是从模板创建的组件，更新对应模板的选中状态
      if (removedComponent.dcb_id) {
        const template = this.categoryList
          .flatMap((category) => category.templates || [])
          .find((t) => t.dcb_id === removedComponent.dcb_id);

        if (template) {
          this.updateTemplateSelection(template, false);
        }
      }
    },
    /* 目录信息 */
    onCatalogIndex(e) {
      this.catalogIndex = e;
      if (
        (this.docuComIndex =
          3 || this.comIndex == 9998 || this.AttributeIndex == 1)
      ) {
        this.comIndex = 0;
        this.AttributeIndex = 0;
        this.docuComIndex = 0;
      }
      this.$nextTick(() => {
        this.$forceUpdate();
      });
    },
    onSetActiveIndexs(e) {
      this.docuComIndex = e;
      if (
        this.AttributeIndex == 1 ||
        this.comIndex == 9998 ||
        this.catalogIndex == 9997
      ) {
        this.catalogIndex = 0;
        this.AttributeIndex = 0;
        this.comIndex = 0;
      }
    },
    //设置当前索引
    onSetActiveIndex(e) {
      this.comIndex = e;
      if (
        this.AttributeIndex == 1 ||
        this.docuComIndex == 3 ||
        this.catalogIndex == 9997
      ) {
        this.catalogIndex = 0;

        this.docuComIndex = 0;
      }
    },
    /* 属性变量 */
    onAttributeIndex(e) {
      this.AttributeIndex = e;
      if (
        (this.docuComIndex =
          3 || this.comIndex == 9998 || this.catalogIndex == 9997)
      ) {
        this.catalogIndex = 0;
        this.comIndex = 0;
        this.docuComIndex = 0;
      }
    },
    /* 更新 */
    renew() {
      let _this = this;
      _this.docVisible = true;
      this.docForm.dcm_title = _this.docAttr.dcm_title;
      this.docForm.dcm_type = _this.docAttr.dcm_type;
    },
    /* 保存 */
    onSaveAs(e) {
      let _this = this;
      if (_this.coms.length <= 0) {
        _this.$alert("请填写内容");
        return;
      }
      _this.docAttr.dcm_id = "";
      _this.docVisible = true;
      this.docForm.dcm_title = _this.docAttr.dcm_title;
      this.docForm.dcm_type = _this.docAttr.dcm_type;
    },
    //保存文档
    onSave(e) {
      let _this = this;
      if (_this.coms.length <= 0) {
        _this.$alert("增加组件");
        return;
      }
      if (_this.docAttr.dcm_type == "" || _this.docAttr.dcm_type <= 0) {
        _this.$alert("请选择文档分类");
        return;
      }
      if (_this.docAttr.dcm_title == "") {
        _this.$alert("请填写文档标题");
        return;
      }

      _this.docAttr.links = JSON.stringify(_this.docAttr.linkProduct);
      _this.docAttr.projects = JSON.stringify(_this.docAttr.linkProject);
      _this.docAttr.dcm_data = JSON.stringify(_this.coms);
      _this.docAttr.is_template = 0;
      /* _this.docAttr.user_name = _this.$store.state.user.name;
      _this.docAttr.user_id = _this.$store.state.user.id; 获取用户id,名称 */
      if (_this.docAttr.dcm_id > 0) {
        updateDocument(_this.docAttr).then((res) => {
          if (res.status !== 200) return; //更新文档
          _this.docAttr.id = res.data;
          _this.$alert("文档更新成功");
          _this.docVisible = false;
          _this.docForm = {
            dcm_title: "",
            dcm_type: "",
            dcm_category_id: "",
          };
          _this.searchArticle();
        });
      } else {
        createDocument(_this.docAttr).then((res) => {
          if (res.status !== 200) return; //保存文档
          _this.docAttr.id = res.data;
          _this.articleId = res.data;
          _this.$alert("文档保存成功");
          _this.docVisible = false;
          _this.docForm = {
            dcm_title: "",
            dcm_type: "",
            dcm_category_id: "",
          };
          _this.searchArticle();
        });
      }
    },
    /*更新  */
    onUpload() {
      let _this = this;
      if (_this.coms.length <= 0) {
        _this.$alert("增加组件");
        return;
      }
      /* if (_this.docAttr.category_id == "" || _this.docAttr.category_id <= 0) {
        _this.$alert("请选择分类");
        return;
      } */
      if (_this.docAttr.title == "") {
        _this.$alert("请填写模版标题");
        return;
      }
      _this.docAttr.links = JSON.stringify(_this.docAttr.linkProduct);
      _this.docAttr.projects = JSON.stringify(_this.docAttr.linkProject);
      _this.docAttr.data = JSON.stringify(_this.coms);
      _this.docAttr.is_template = 1;
      _this.docAttr.id = this.$route.query.articleId;
      /* _this.docAttr.user_name = _this.$store.state.user.name;
      _this.docAttr.user_id = _this.$store.state.user.id; 获取用户id,名称*/
      updateDocument(_this.docAttr).then((res) => {
        if (res.status != 200) return; //更新文档
        _this.docAttr.id = res.data;
        _this.$alert("模版更新成功");
        _this.searchArticle();
      });
    },
    /* 保存并更新版 */
    onSaveUpload(e) {
      let _this = this;
      if (_this.coms.length <= 0) {
        _this.$alert("增加组件");
        return;
      }
      /* if (_this.docAttr.category_id == "" || _this.docAttr.category_id <= 0) {
        _this.$alert("请选择分类");
        return;
      } */
      if (_this.docAttr.title == "") {
        _this.$alert("请填写模版标题");
        return;
      }

      _this.docAttr.links = JSON.stringify(_this.docAttr.linkProduct);
      _this.docAttr.projects = JSON.stringify(_this.docAttr.linkProject);
      _this.docAttr.data = JSON.stringify(_this.coms);
      _this.docAttr.is_template = 1;
      /* _this.docAttr.user_name = _this.$store.state.user.name;
      _this.docAttr.user_id = _this.$store.state.user.id; 获取用户id,名称*/
      /* if (_this.docAttr.id > 0) {
        updateDocument(_this.docAttr).then((res) => {
          if (res.status != 200) return; //更新文档
          _this.docAttr.id = res.data;
          _this.$alert("模版更新成功");
          _this.searchArticle();
        });
      } else { */
      createDocument(_this.docAttr).then((res) => {
        if (res.status != 200) return; //保存文档
        _this.docAttr.id = res.data;
        _this.articleId = res.data;
        _this.$alert("模版保存成功");
        _this.searchArticle();
      });
      /*   } */
    },

    //设置组件值
    onSetComs(e) {
      let _this = this;
      _this.coms = [...e];
    },
    onAddLayer(cateIndex, dataIndex) {
      let _this = this;
      let item = _this.categoryList[cateIndex].dataList[dataIndex];
      let data = {
        ...item,
        attrs: JSON.parse(item.attrs),
      };
      delete data.category;
      _this.coms.push(data);
      _this.comIndex = _this.coms.length - 1;
    },
    //处理插入事件
    onInsert(e) {
      let _this = this;
      switch (e.key) {
        case "article": //插入图文
          _this.insertArticle();
          break;
        case "table": //插入图表
          _this.insertTable();
          break;
        case "sourceData": //插入原数据
          _this.insertSourceData(e);
          break;
        case "formual": //插入公式
          _this.insertFormual(e);
          break;
        case "constant": //插入常量
          _this.insertConstant(e);
          break;
        case "variable": //插入变量
          _this.insertVariable(e);
          break;
        case "pager": //插入分页符
          _this.insertPager();
          break;
        case "attr":
          // 直接调用插入逻辑，不再检查 linkProduct
          let com = _this.coms[_this.comIndex];
          if (com && e.content) {
            let data = {
              type: "ProductAttr",
              id: e.content.id,
              dataId: "",
              name: "商品属性",
              intro: "商品属性",
              content: e.content.content || "",
              attrs: e.content.attrs,
            };

            com.attrs.push(data);
            _this.insertCmd = {
              content: "{{" + data.id + "}}",
            };

            // 可选：将产品信息添加到文档关联商品
            if (e.content.attrs.productInfo) {
              const productInfo = e.content.attrs.productInfo;
              if (!_this.docAttr.linkProduct) {
                _this.docAttr.linkProduct = [];
              }
              // 避免重复添加
              if (
                !_this.docAttr.linkProduct.some(
                  (p) => p.dcp_p_no === productInfo.dcp_p_no
                )
              ) {
                _this.docAttr.linkProduct.push(productInfo);
              }
            }
          }
          break;
        case "Directory": //插入主题
          _this.insertDirectory(e);
          break;
        case "addNew": //插入新记录
          _this.insertNew(e);
          break;
        case "InsertNull":
          _this.insertVal();
          break;
        case "ai": //插入ai
          _this.insertAI(e);
          break;
      }
    },
    /* 插入空值 */
    insertVal() {
      let _this = this;
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }
      let com = _this.coms[_this.comIndex];
      let uniqueId = "val" + Date.now(); // 使用时间戳创建唯一ID
      let data = {
        type: "variableNull",
        id: uniqueId,
        dataId: "",
        name: "非变量",
        intro: "",
        content: "请输入",
        data: "",
      };
      com.attrs.push(data);
      if (com.type == "TextArea") {
        //如果是图文，更新内容
        _this.insertCmd = {
          content: "{{" + data.id + "}}",
        };
      } else {
        //仅对图表中插入有效
        if (_this.comIndex >= 0) {
          _this.setTableData(data.id);
        }
      }
    },
    /* 插入ai */
    insertAI(e) {
      let _this = this;
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }
      let com = _this.coms[_this.comIndex];

      let data = {
        type: "ai",
        id: "ai" + (com.attrs.length + 1),
        dataId: "",
        name: "AI",
        intro: "插入AI",
        content: e.content.result,
        search: e.content.searchTerm,
      };
      com.attrs.push(data);
      if (com.type == "TextArea") {
        //如果是图文，更新内容
        _this.insertCmd = {
          content: "{{" + data.id + "}}",
        };
      }
    },
    insertProductAttr() {
      let _this = this;
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }

      let com = _this.coms[_this.comIndex];
      if (!com) {
        _this.$alert("请先添加文档内容");
        return false;
      }

      // 允许直接插入产品属性，移除原有的限制检查
      this.showProductAttr = true;
    },
    //插入目录
    insertDirectory(e) {
      if (this.comIndex < 0) {
        this.$message.warning("请选择插入图层");
        return;
      }

      const com = this.coms[this.comIndex];
      const currentLevel = e.content.level || 1;

      try {
        // 生成目录编号和内容
        const { number, content } = this.generateDirectoryItem(
          this.comIndex,
          currentLevel
        );
        console.log(number);
        const directoryItem = {
          type: "Directory",
          id: `Directory_${this.comIndex}_${currentLevel}_${Date.now()}`,
          name: "目录信息",
          intro: "目录信息",
          number,
          content: content || "新建目录项",
          level: currentLevel,
          moduleIndex: this.comIndex,
        };

        com.attrs.push(directoryItem);

        // 更新文本内容
        this.insertCmd = {
          content: `{{${directoryItem.id}}}`,
        };

        // 更新目录树
        this.updateCatalog(this.coms);

        // 强制更新视图
        this.$nextTick(() => {
          this.$forceUpdate();
        });
      } catch (error) {
        console.error("Error inserting directory:", error);
        this.$message.error("插入目录失败，请重试");
      }
    },

    // 添加 findParentNumber 方法
    findParentNumber(moduleIndex, level) {
      if (level <= 1) {
        return (moduleIndex + 1).toString();
      }

      const module = this.coms[moduleIndex];
      if (!module || !module.attrs) return "";

      // 获取所有目录类型的属性并按编号排序
      const directories = module.attrs
        .filter((attr) => attr.type === "Directory" && attr.level < level)
        .sort((a, b) => {
          const aNum = a.number.split(".").map(Number);
          const bNum = b.number.split(".").map(Number);
          for (let i = 0; i < Math.min(aNum.length, bNum.length); i++) {
            if (aNum[i] !== bNum[i]) return aNum[i] - bNum[i];
          }
          return aNum.length - bNum.length;
        });

      // 找到最近的上级目录
      const parentDir = directories[directories.length - 1];
      return parentDir ? parentDir.number : (moduleIndex + 1).toString();
    },

    // 修改 generateDirectoryItem 方法
    generateDirectoryItem(moduleIndex, level) {
      const module = this.coms[moduleIndex];
      const existingDirs = module.attrs.filter(
        (attr) => attr.type === "Directory" && attr.level === level
      );

      const parentNumber = this.findParentNumber(moduleIndex, level);
      const siblingCount = existingDirs.length;

      let number;
      if (level === 1) {
        number = (moduleIndex + 1).toString();
      } else {
        number = `${parentNumber}.${siblingCount + 1}`;
      }

      return {
        number,
        content: `第${number}章`, // 默认内容
      };
    },

    // 插入新记录
    insertNew(e) {
      this.coms.push(e);

      // 如果是从模板拖拽的，更新模板选中状态
      if (e.dcb_id) {
        const template = this.categoryList
          .flatMap((category) => category.templates || [])
          .find((t) => t.dcb_id === e.dcb_id);

        if (template) {
          this.updateTemplateSelection(template, true);
        }
      }
    },

    //插入分页
    insertPager() {
      let _this = this;
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }
      let com = _this.coms[_this.comIndex];
      let data = {
        type: "pager",
        id: "pager" + (com.attrs.length + 1),
        name: "分页符",
        intor: "强制分页",
        content: "",
      };
      com.attrs.push(data);
      if (com.type == "TextArea") {
        //如果是图文，更新内容
        _this.insertCmd = {
          content: "<div>{{" + data.id + "}}</div>",
        };
      }
    },

    //插入图文
    insertArticle() {
      /*   let _this = this;
      _this.coms.push({
        type: "TextArea",
        lay_id: "textArea",
        code: "模块名",
        name: "图文",
        intro: "图文介绍",
        isEdit: 2,
        content: "请填写内容",
        attrs: [],
      });
      _this.comIndex = _this.coms.length - 1; */
      let _this = this;
      let newArticle = {
        type: "TextArea",
        lay_id: "textArea",
        code: "模块名",
        name: "图文",
        intro: "图文介绍",
        isEdit: 2,
        content: "请填写内容",
        attrs: [],
      };
      _this.coms.push(newArticle);
      _this.comIndex = _this.coms.length - 1;

      // 添加一些日志来帮助调试
      console.log("New article added:", newArticle);
      console.log("Current coms:", _this.coms);
      console.log("New comIndex:", _this.comIndex);
    },

    //插入表格
    insertTable() {
      let _this = this;
      _this.coms.push({
        type: "Table",
        lay_id: "Table",
        code: "模块名",
        name: "图表名称",
        intro: "图表介绍",
        isEdit: 2,
        tableHeader: this.initTableHeader(),
        tableData: [{}],
        htmlData: "",
        attrs: [],
      });
      _this.comIndex = _this.coms.length - 1;
    },
    initTableHeader() {
      var start = 65;
      var data = [];
      for (var i = start; i <= start + 25; i++) {
        data.push(String.fromCharCode(i));
      }
      return data;
    },
    //插入变量
    insertConstant(e) {
      let _this = this;
      // console.log("insertconstant");
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }
      let com = _this.coms[_this.comIndex];
      let data = {
        type: "constant",
        id: e.content.code + (com.attrs.length + 1),
        dataId: e.id,
        name: e.content.code,
        intro: e.content.intro,
        content: e.content.value,
        data: e.content,
      };

      com.attrs.push(data);
      if (com.type == "TextArea") {
        //如果是图文，更新内容
        _this.insertCmd = {
          content: "{{" + data.id + "}}",
        };
      } else {
        //仅对图表中插入有效
        if (_this.comIndex >= 0) {
          _this.setTableData(data.id);
        }
      }
    },

    //插入变量
    insertVariable(e) {
      let _this = this;
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }
      let com = _this.coms[_this.comIndex];
      let data = {
        type: "variable",
        id: e.content.code + (com.attrs.length + 1),
        dataId: e.id,
        name: e.content.code,
        intro: e.content.intro,
        content: e.content.value,
        data: e.content,
      };
      com.attrs.push(data);
      if (com.type == "TextArea") {
        //如果是图文，更新内容
        _this.insertCmd = {
          content: "{{" + data.id + "}}",
        };
      } else {
        //仅对图表中插入有效
        if (_this.comIndex >= 0) {
          _this.setTableData(data.id);
        }
      }
    },
    //插入原数据
    insertSourceData(e) {
      let _this = this;
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }
      let com = _this.coms[_this.comIndex];
      let data = {
        type: "sourceData",
        id: "sourceData" + (com.attrs.length + 1),
        dataId: "",
        name: "源数据",
        intro: "插入源数据",
        formula:
          "[R][" +
          e.content.tb +
          "][" +
          e.content.sheet +
          "][" +
          e.content.r +
          "," +
          e.content.c +
          "]",
        content: e.content.value,
        data: e.content,
      };
      com.attrs.push(data);
      if (com.type == "TextArea") {
        //如果是图文，更新内容
        _this.insertCmd = {
          content: "{{" + data.id + "}}",
        };
      }
    },
    //插入公式
    insertFormual(e) {
      let _this = this;
      if (_this.comIndex < 0) {
        _this.$alert("请选择插入图层");
        return false;
      }
      let com = _this.coms[_this.comIndex];
      let data = {
        type: "formual",
        id: "formual" + (com.attrs.length + 1),
        dataId: e.id,
        name: e.content.name,
        intro: e.content.intro,
        formula: e.content.formula,
        content: 0,
        data: e.content,
      };
      com.attrs.push(data);
      if (com.type == "TextArea") {
        //如果是图文，更新内容
        _this.insertCmd = {
          content: "{{" + data.id + "}}",
        };
      } else {
        //仅对图表中插入有效
        if (_this.comIndex >= 0) {
          _this.setTableData(data.id);
        }
      }
    },

    //获取模版分类信息
    async initCategoryList() {
      let _this = this;
      try {
        let res = await searchTemplateCategory({
          page: 1,
          pageSize: 99,
          parent_id: 0,
          status: 5,
        });

        if (res.status != 200) return;

        // 处理分类数据
        _this.categoryList = await Promise.all(
          res.data.dataList.map(async (category) => {
            // 获取该分类下的模板列表
            const templates = await _this.getTemplateList(category.id);

            // 只保留category_id与当前分类id匹配的模板
            const filteredTemplates = templates.filter(
              (template) => template.category_id === category.id
            );

            return {
              ...category,
              templates: filteredTemplates.map((template) => ({
                ...template,
                selected: false, // 添加选中状态
              })),
            };
          })
        );

        // 过滤掉没有模板的分类
        _this.categoryList = _this.categoryList.filter(
          (category) => category.templates && category.templates.length > 0
        );

        console.log("处理后的分类数据:", _this.categoryList);
      } catch (error) {
        console.error("初始化分类列表失败:", error);
      }
    },
    //获取模版列表

    async getTemplateList(categoryId) {
      let _this = this;
      let res = await searchTemplate({
        page: 1,
        pageSize: 999,
        category_id: categoryId,
        status: 5,
      });
      if (res.status != 200) return [];

      let dataList = res.data.dataList.map((item) => {
        try {
          // 处理属性值
          if (item.dcb_attrs) {
            // 如果存在 dcb_attrs，优先使用它并确保正确解析
            item.attrs =
              typeof item.dcb_attrs === "string"
                ? JSON.parse(item.dcb_attrs)
                : item.dcb_attrs;
          } else if (!item.attrs) {
            // 如果既没有 dcb_attrs 也没有 attrs，设置为空数组
            item.attrs = [];
          } else {
            // 如果有 attrs 但是是字符串，解析它
            item.attrs =
              typeof item.attrs === "string"
                ? JSON.parse(item.attrs)
                : item.attrs;
          }

          // 确保 content 存在
          item.content = item.dcb_nr || item.content || "";

          // 从 content 中提取所有 {{}} 包裹的 ID
          const contentIds = (item.content.match(/{{([^}]+)}}/g) || []).map(
            (match) => match.slice(2, -2).trim()
          );

          // 只在有 contentIds 时进行过滤
          if (contentIds.length > 0) {
            item.attrs = Array.isArray(item.attrs)
              ? item.attrs.filter(
                  (attr) => attr && attr.id && contentIds.includes(attr.id)
                )
              : [];
          }

          // 确保 attrs 是数组
          if (!Array.isArray(item.attrs)) {
            item.attrs = [];
          }
        } catch (error) {
          console.error("Error processing template item:", error, item);
          item.attrs = [];
        }

        return item;
      });

      console.log("处理后的数据列表:", dataList);
      return dataList;
    },

    //获取文档模板列表
    async searchArticle() {
      try {
        // 获取文档分类
        const categoryRes = await searchDocumentCategory({
          page: 1,
          pageSize: 999,
        });
        if (categoryRes.status !== 200) return;

        // 获取文档列表
        const documentRes = await pageDocument({
          page: 1,
          pageSize: 99,
          isContentShow: true,
        });
        if (documentRes.status !== 200) return;

        // 处理数据为树形结构
        this.schemeData = categoryRes.data.dataList.map((category) => ({
          label: category.name,
          id: category.id,
          children: documentRes.data.dataList
            .filter((doc) => doc.dcm_category_id === category.id)
            .map((doc) => ({
              label: doc.dcm_title,
              id: doc.dcm_id,
              type: "document",
            })),
        }));

        // 更新默认展开的节点 - 展开所有分类
        this.expandedKeys = this.schemeData.map((category) => category.id);

        console.log("Processed schemeData:", this.schemeData);
      } catch (error) {
        console.error("Error processing document data:", error);
        this.$message.error("获取文档数据失败");
      }
    },
    // 添加模板选择处理方法
    /* handleTemplateSelect(category, template, value) {
      template.selected = value;
      console.log("Selected template:", {
        category: category.name,
        template: template.dcb_name,
        selected: value,
      });
      // 这里可以添加其他选择逻辑
    }, */
    // 检查模板是否已被使用
    isTemplateUsed(template) {
      const isUsed = this.coms.some((com) => com.dcb_id === template.dcb_id);
      if (isUsed) {
        // 如果模板被使用，设置 selected 为 true
        template.selected = true;

        // 同步其他分类中相同模板的选中状态
        this.categoryList.forEach((category) => {
          const sameTemplate = category.templates?.find(
            (t) => t.dcb_id === template.dcb_id
          );
          if (sameTemplate) {
            sameTemplate.selected = true;
          }
        });
      }
      /* return isUsed; */
    },
    // 处理模板选择
    handleTemplateSelect(category, template, isSelected) {
      // 更新模板选中状态
      template.selected = isSelected;

      if (isSelected) {
        // 如果是选中，添加到组件列表
        /*  const newComponent = {
          ...template,
          type: template.dcb_type || "TextArea",
          lay_id: template.lay_id || "textArea",
          content: template.dcb_nr || "",
          attrs:
            typeof template.dcb_attrs === "string"
              ? JSON.parse(template.dcb_attrs)
              : template.dcb_attrs || [],
        };
        this.coms.push(newComponent); */
      } else {
        // 如果取消选中，从组件列表中移除
        const index = this.coms.findIndex(
          (com) => com.dcb_id === template.dcb_id
        );
        if (index !== -1) {
          this.coms.splice(index, 1);
        }
      }

      // 同步其他分类中相同模板的选中状态
      this.categoryList.forEach((cat) => {
        if (cat.id !== category.id) {
          const sameTemplate = cat.templates?.find(
            (t) => t.dcb_id === template.dcb_id
          );
          if (sameTemplate) {
            sameTemplate.selected = isSelected;
          }
        }
      });
    },
    // 初始化模板选中状态
    initTemplateSelection() {
      // 先重置所有选中状态
      this.resetAllTemplateSelections();

      // 然后根据已渲染组件更新选中状态
      this.coms.forEach((com) => {
        this.categoryList.forEach((category) => {
          const template = category.templates?.find(
            (t) => t.dcb_id === com.dcb_id
          );
          if (template) {
            template.selected = true;
          }
        });
      });
    },
    // 修改后的 handleDragEnd 方法
    handleDragEnd(evt) {
      // 检查是否是克隆操作
      if (!evt || !evt.item || evt.pullMode !== "clone") {
        return;
      }

      // 获取拖拽的数据
      const draggedData = evt.item.dataset;
      if (!draggedData) {
        return;
      }

      // 从拖拽的DOM元素中获取模板ID
      const templateId = evt.item.getAttribute("data-template-id");
      if (!templateId) {
        return;
      }

      // 查找对应的模板
      const draggedTemplate = this.categoryList
        .flatMap((category) => category.templates || [])
        .find((template) => template.dcb_id === templateId);

      if (draggedTemplate) {
        this.updateTemplateSelection(draggedTemplate, true);
      }
    },

    // 更新模板选中状态的通用方法
    updateTemplateSelection(template, isSelected) {
      // 更新所有分类中相同模板的选中状态
      this.categoryList.forEach((category) => {
        const sameTemplate = category.templates?.find(
          (t) => t.dcb_id === template.dcb_id
        );
        if (sameTemplate) {
          sameTemplate.selected = isSelected;
        }
      });
    },
    // 添加重置所有模板选中状态的方法
    resetAllTemplateSelections() {
      this.categoryList.forEach((category) => {
        if (category.templates) {
          category.templates.forEach((template) => {
            template.selected = false;
          });
        }
      });
    },
    // 处理搜索
    async handleSearch() {
      if (!this.searchKey.trim()) {
        return;
      }

      try {
        this.loading = true;
        const res = await pageDocument({
          page: 1,
          pageSize: 999,
          dcm_title: this.searchKey.trim(),
        });

        if (res.status === 200) {
          // 更新树形数据
          const searchResults = res.data.dataList.map((doc) => ({
            id: doc.dcm_id,
            label: doc.dcm_title,
            children: null,
          }));

          const searchResultNode = {
            id: "search-result", // 为搜索结果节点添加唯一ID
            label: "搜索结果",
            children: searchResults,
          };

          // 更新树形数据
          this.schemeData = [
            searchResultNode,
            /*  ...this.schemeData.filter(item => item.label !== "搜索结果") */
          ];

          // 更新需要展开的节点keys
          this.expandedKeys = [
            "search-result", // 展开搜索结果分类
            ...searchResults.map((item) => item.id), // 展开所有搜索结果项
          ];

          // 强制更新树形组件
          this.$nextTick(() => {
            if (this.$refs.documentTree) {
              this.$refs.documentTree.store.defaultExpandedKeys =
                this.expandedKeys;
              this.$refs.documentTree.updateKeyChildren();
            }
          });

          // 如果没有搜索结果，显示提示
          if (searchResults.length === 0) {
            this.$message.info("未找到匹配的文档");
          }
        }
      } catch (error) {
        console.error("搜索文档失败:", error);
        this.$message.error("搜索失败，请重试");
      } finally {
        this.loading = false;
      }
    },

    // 修改清空处理方法
    async handleClear() {
      this.searchKey = "";
      this.expandedKeys = []; // 清空展开的节点
      await this.searchArticle();

      // 重置树形组件的展开状态
      this.$nextTick(() => {
        if (this.$refs.documentTree) {
          this.$refs.documentTree.store.defaultExpandedKeys = [];
          this.$refs.documentTree.updateKeyChildren();
        }
      });
    },

    // 添加搜索处理方法
    async handleResourceSearch() {
      /*  const searchKey = this.resourceSearchKey.toLowerCase().trim();
      
      // 遍历所有分类
      this.categoryList.forEach(category => {
        if (category.templates) {
          // 过滤模板列表
          const filteredTemplates = category.templates.filter(template => 
            template.dcb_name.toLowerCase().includes(searchKey)
          );
          
          // 使用 Vue.set 确保响应式更新
          this.$set(category, 'templates', filteredTemplates);
        }
      }); */
      if (!this.templateSearchKey.trim()) {
        return;
      }

      try {
        // 调用搜索模板接口
        const res = await searchTemplate({
          page: 1,
          pageSize: 999,
          dcb_name: this.templateSearchKey.trim(),
        });

        if (res.status === 200) {
          // 保存当前分类的原始模板
          this.originalTemplateList = [...this.categoryList];

          // 处理搜索结果
          const searchResults = res.data.dataList.map((template) => {
            // 确保模板数据格式正确
            if (!template.attrs) {
              template.attrs = "[]";
            }
            try {
              template.attrs =
                typeof template.attrs === "string"
                  ? JSON.parse(template.attrs)
                  : template.attrs;
            } catch (error) {
              console.error("Error parsing template attrs:", error);
              template.attrs = [];
            }
            return template;
          });

          // 更新分类列表,将搜索结果放在一个特殊分类下
          this.categoryList = [
            {
              id: "search-results",
              name: "搜索结果",
              templates: searchResults.map((template) => ({
                ...template,
                selected: this.coms.some(
                  (com) => com.dcb_id === template.dcb_id
                ),
              })),
            },
          ];
        }
      } catch (error) {
        console.error("搜索模板失败:", error);
        this.$message.error("搜索失败，请重试");
      }
    },

    // 添加清除搜索处理方法
    handleResourceClear() {
      // 重置搜索并恢复原始列表
      this.resourceSearchKey = "";
      this.initCategoryList();
    },
    // 处理模板搜索
    async handleTemplateSearch() {
      /*  if (!this.templateSearchKey.trim()) {
        return;
      } */
      console.log(12);
      try {
        // 调用搜索模板接口
        const res = await searchTemplate({
          page: 1,
          pageSize: 999,
          dcb_name: this.templateSearchKey.trim(),
        });

        if (res.status === 200) {
          // 保存当前分类的原始模板
          this.originalTemplateList = [...this.categoryList];

          // 处理搜索结果
          const searchResults = res.data.dataList.map((template) => {
            // 确保模板数据格式正确
            if (!template.attrs) {
              template.attrs = "[]";
            }
            try {
              template.attrs =
                typeof template.attrs === "string"
                  ? JSON.parse(template.attrs)
                  : template.attrs;
            } catch (error) {
              console.error("Error parsing template attrs:", error);
              template.attrs = [];
            }
            return template;
          });

          // 更新分类列表,将搜索结果放在一个特殊分类下
          this.categoryList = [
            {
              id: "search-results",
              name: "搜索结果",
              templates: searchResults.map((template) => ({
                ...template,
                selected: this.coms.some(
                  (com) => com.dcb_id === template.dcb_id
                ),
              })),
            },
          ];
        }
      } catch (error) {
        console.error("搜索模板失败:", error);
        this.$message.error("搜索失败，请重试");
      }
    },

    // 清空搜索
    async handleTemplateClear() {
      this.templateSearchKey = "";
      // 如果有保存的原始列表，恢复它
      if (this.originalTemplateList.length > 0) {
        this.categoryList = [...this.originalTemplateList];
      } else {
        // 否则重新初始化分类列表
        await this.initCategoryList();
      }
    },

    // 添加一个用于检查产品是否已关联的方法
    isProductLinked(dcp_p_no) {
      return (
        this.docAttr.linkProduct &&
        this.docAttr.linkProduct.some((p) => p.dcp_p_no === dcp_p_no)
      );
    },

    // 修改文档属性更新方法
    updateDocAttr() {
      // ... 其他代码保持不变 ...
      if (this.docAttr.linkProduct && this.docAttr.linkProduct.length > 0) {
        this.docAttr.links = JSON.stringify(this.docAttr.linkProduct);
      }
      // ... 其他代码保持不变 ...
    },
    // 添加或修改以下方法
    getCategory(categoryId) {
      // 处理数组格式的categoryId
      if (Array.isArray(categoryId)) {
        categoryId = categoryId[categoryId.length - 1]; // 获取数组最后一个值
      }

      // 如果没有categoryId，直接返回空字符串
      if (!categoryId) return "";

      const findCategory = (list) => {
        if (!list || !Array.isArray(list)) return null;

        for (const category of list) {
          // 确保进行数字比较
          if (
            Number(category.id) === Number(categoryId) ||
            Number(category.dcb_category_id) === Number(categoryId)
          ) {
            return category.name || category.dcb_name;
          }

          // 检查templates
          if (category.templates) {
            const template = category.templates.find(
              (t) =>
                Number(t.dcb_category_id) === Number(categoryId) ||
                Number(t.category_id) === Number(categoryId)
            );
            if (template) {
              return category.name;
            }
          }

          // 递归检查子分类
          if (category.children) {
            const found = findCategory(category.children);
            if (found) return found;
          }
        }
        return null;
      };

      // 在分类列表中查找
      const categoryName = findCategory(this.categoryList);

      // 如果找到分类名称则返回，否则返回格式化后的分类ID
      return categoryName || (categoryId ? String(categoryId) : "");
    },

    // 添加目录编号更新方法
    updateDirectoryNumbers() {
      this.coms.forEach((com, moduleIndex) => {
        if (com.attrs) {
          // 获取当前模块中的所有目录类型属性
          const directoryAttrs = com.attrs.filter(
            (attr) => attr.type === "Directory"
          );

          // 更新每个目录的编号
          directoryAttrs.forEach((dir, index) => {
            // 生成新的编号
            const number = this.generateLevelPrefix(moduleIndex, dir.level);
            // 更新目录编号
            this.$set(dir, "number", number);
          });
        }
      });
    },

    // 简化拖拽完成处理
    onDragComplete() {
      this.$nextTick(() => {
        // 只在存在目录类型的属性时才更新编号
        if (
          this.coms.some(
            (com) =>
              com.attrs && com.attrs.some((attr) => attr.type === "Directory")
          )
        ) {
          this.updateDirectoryNumbers();
        }
        // 触发重建事件
        this.$emit("onRebuild", this.coms);
      });
    },

    // 简化拖拽结束处理
    onDragEnd() {
      // 可以添加其他拖拽结束后的处理逻辑
      this.$forceUpdate();
    },

    // 简化添加处理
    onAdd(evt) {
      console.log("Added new module:", evt.added);
      this.$nextTick(() => {
        if (
          this.coms.some(
            (com) =>
              com.attrs && com.attrs.some((attr) => attr.type === "Directory")
          )
        ) {
          this.updateDirectoryNumbers();
        }
        this.$emit("onRebuild", this.coms);
      });
    },

    // 保存模板
    async onSaveTemplate(item) {
      let data = {};

      // 遍历原始对象，只保留 dcb_ 开头的属性
      Object.keys(item).forEach((key) => {
        if (key.startsWith("dcb_")) {
          data[key] = item[key];
        }
      });

      // 特殊字段映射
      data.dcb_nr = item.content;
      data.dcb_attrs = JSON.stringify(item.attrs);
      data.dcb_type = item.type;
      data.dcb_name = item.name;

      // 处理分类ID
      if (Array.isArray(item.category_id)) {
        data.category_id = item.category_id[item.category_id.length - 1];
      } else {
        data.category_id = item.category_id;
      }

      data.status = 5;

      try {
        if (!item.dcb_id || this.saveAs) {
          const res = await createTemplate(data);
          if (res.code === 200) {
            item.id = res.data;
            this.$alert("模块信息保存成功");
            this.saveAs = false;
          }
        } else {
          const res = await updateTemplate(data);
          if (res.code === 200) {
            this.$alert("模块信息更新成功");
          }
        }

        item.selDisabled = false;
        item.valDisabled = false;
        this.$forceUpdate();
      } catch (error) {
        console.error("保存模板失败:", error);
        this.$message.error("保存失败：" + error.message);
      }
    },

    // 编辑/预览切换
    async onEdit(index, state) {
      try {
        if (this.isSaving) return;
        this.isSaving = true;

        // 保存当前组件的完整数据
        const currentCom = JSON.parse(JSON.stringify(this.coms[index]));

        if (state === 2) {
          // 从编辑切换到预览
          const componentRef = this.$refs[`textArea${index}`];
          if (componentRef && componentRef[0]) {
            await componentRef[0].save();
          }
        }

        // 更新编辑状态
        this.coms = this.coms.map((it, idx) => {
          if (idx === index) {
            return {
              ...currentCom, // 保持原有属性
              isEdit: state,
              attrs: currentCom.attrs || [], // 确保attrs不会丢失
              dcb_attrs: currentCom.dcb_attrs || [], // 确保dcb_attrs不会丢失
            };
          }
          return {
            ...it,
            isEdit: 2,
          };
        });

        // 更新当前索引
        this.comIndex = index;

        // 触发重建
        await this.onRebuild(this.coms);
      } catch (error) {
        /*  console.error("切换模式失败:", error);
        this.$message.error("切换模式失败：" + error.message); */
      } finally {
        this.isSaving = false;
      }
    },

    // 删除模块
    onRemove(index) {
      console.log(index);
      this.$confirm("此操作将删除该模块, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.coms.splice(index, 1);
          this.$emit("onRebuild", this.coms);
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },

    // 过滤属性
    filterAttrs(item) {
      if (!item.content && !item.dcb_nr) return;

      // 保存原始属性
      const originalAttrs = item.attrs || [];
      const originalDcbAttrs = item.dcb_attrs || [];

      // 从内容中提取ID
      const contentIds = (
        (item.content || item.dcb_nr).match(/{{([^}]+)}}/g) || []
      ).map((match) => match.slice(2, -2).trim());

      if (contentIds.length > 0) {
        // 只过滤掉确实不存在的ID
        item.attrs = originalAttrs.filter(
          (attr) =>
            attr &&
            (contentIds.includes(attr.id) ||
              attr.type === "ProductAttr" || // 保留特殊类型属性
              attr.type === "variableNull")
        );

        if (item.dcb_attrs) {
          item.dcb_attrs = originalDcbAttrs.filter(
            (attr) =>
              attr &&
              (contentIds.includes(attr.id) ||
                attr.type === "ProductAttr" ||
                attr.type === "variableNull")
          );
        }
      }
    },

    handleDragStart(event, data) {
      // 只允许拖拽一级目录
      if (data.level !== 1) {
        event.preventDefault();
        return;
      }
      // 存储被拖拽的目录项和对应的模块索引
      event.dataTransfer.setData(
        "text/plain",
        JSON.stringify({
          moduleIndex: data.moduleIndex,
          label: data.label,
        })
      );
    },

    handleDrop(event, targetData) {
      event.preventDefault();

      try {
        const dragData = JSON.parse(event.dataTransfer.getData("text/plain"));
        const sourceIndex = dragData.moduleIndex;
        const targetIndex = targetData.moduleIndex;

        // 确保是不同位置的拖放
        if (sourceIndex === targetIndex) {
          return;
        }

        // 1. 移动模块
        const movedModule = this.coms.splice(sourceIndex, 1)[0];
        this.coms.splice(targetIndex, 0, movedModule);

        // 2. 更新所有模块的目录编号
        this.updateDirectoryNumbers();

        // 3. 重新生成目录数据
        this.handleClick({ name: "catalog" });
      } catch (error) {
        console.error("Drop handling error:", error);
      }
    },

    updateDirectoryNumbers() {
      this.coms.forEach((module, moduleIndex) => {
        const directoryAttrs = module.attrs.filter(
          (attr) => attr.type === "Directory"
        );
        directoryAttrs.forEach((attr) => {
          // 更新目录的模块索引
          attr.moduleIndex = moduleIndex;

          // 更新目录编号
          const numbers = attr.number.split(".");
          numbers[0] = (moduleIndex + 1).toString();
          attr.number = numbers.join(".");

          // 更新显示的标签
          attr.content = attr.content.replace(/^\d+/, moduleIndex + 1);
        });
      });
    },
    allowDrop(draggingNode, dropNode, type) {
      // 只允许同级之间的拖放，不允许嵌套
      return type !== "inner";
    },
    allowDrag(draggingNode) {
      return draggingNode.level === 1;
    },
    handleDragEnd(event) {
      // 处理拖拽结束事件
      console.log("Drag end:", event);
    },
    // 处理拖拽结束事件
    handleDragEnd(draggingNode, dropNode, dropType) {
      if (!dropNode || !dropType) {
        console.log("无效的拖放操作");
        return;
      }

      console.log("拖拽节点:", draggingNode.data);
      console.log("目标节点:", dropNode.data);
      console.log("放置类型:", dropType);

      // 获取源模块和目标模块的索引
      const sourceIndex = draggingNode.data.moduleIndex;
      const targetIndex = dropNode.data.moduleIndex;

      if (typeof sourceIndex !== "number" || typeof targetIndex !== "number") {
        console.error("无法确定模块索引");
        return;
      }

      // 计算最终目标位置
      let finalTargetIndex = targetIndex;

      // 根据放置类型调整目标位置
      if (dropType === "next") {
        finalTargetIndex++;
      }

      // 如果源位置在目标位置之前，需要调整目标位置
      if (sourceIndex < finalTargetIndex) {
        finalTargetIndex--;
      }

      console.log("移动模块:", {
        from: sourceIndex,
        to: finalTargetIndex,
        type: dropType,
      });

      // 执行模块移动
      const [movedModule] = this.coms.splice(sourceIndex, 1);
      this.coms.splice(finalTargetIndex, 0, movedModule);

      // 更新所有模块的编号和目录结构
      this.$nextTick(() => {
        this.updateModulesAndDirectories();

        // 强制更新视图
        this.$forceUpdate();
      });
    },

    // 改进的查找模块索引方法
    findModuleIndex(nodeData) {
      console.log("查找模块索引:", nodeData);

      // 首先尝试使用直接的moduleIndex
      if (typeof nodeData.moduleIndex === "number") {
        return nodeData.moduleIndex;
      }

      // 然后尝试从编号中获取索引
      if (nodeData.number) {
        const moduleNumber = parseInt(nodeData.number.split(".")[0]);
        if (!isNaN(moduleNumber)) {
          // 因为编号是从1开始的，所以需要减1来获取索引
          return moduleNumber - 1;
        }
      }

      // 最后尝试在coms数组中查找匹配的模块
      return this.coms.findIndex((module) => {
        const directoryAttr = module.attrs?.find((attr) => {
          if (attr.type !== "Directory") return false;
          if (attr.level !== 1) return false;

          // 尝试多种匹配方式
          if (attr.id === nodeData.id) return true;
          if (attr.moduleIndex === nodeData.moduleIndex) return true;
          if (attr.number && nodeData.number && attr.number === nodeData.number)
            return true;

          return false;
        });
        return !!directoryAttr;
      });
    },

    // 更新模块和目录结构
    updateModulesAndDirectories() {
      console.log("开始更新模块和目录结构");
      console.log("更新前的模块列表:", JSON.parse(JSON.stringify(this.coms)));

      this.coms.forEach((module, moduleIndex) => {
        if (!module.attrs) return;

        const directoryAttrs = module.attrs.filter(
          (attr) => attr.type === "Directory"
        );

        directoryAttrs.forEach((attr) => {
          // 更新模块索引
          attr.moduleIndex = moduleIndex;

          // 更新编号
          const numbers = attr.number.split(".");
          numbers[0] = (moduleIndex + 1).toString();
          const newNumber = numbers.join(".");

          // 更新属性
          attr.number = newNumber;

          // 更新内容
          if (attr.content) {
            const contentParts = attr.content.split(" ");
            contentParts[0] = newNumber;
            attr.content = contentParts.join(" ");
          }
        });
      });

      console.log("更新后的模块列表:", JSON.parse(JSON.stringify(this.coms)));

      // 重新生成目录树
      this.$nextTick(() => {
        this.handleClick({ name: "catalog" });
      });
    },

    // 生成目录树数据
    generateCatalogData() {
      // 这里应该是你原有的生成目录数据的逻辑
      // 确保调用正确的方法来更新目录视图
      this.handleClick({ name: "catalog" });
    },
    toggleSchemePanel() {
      this.isSchemeCollapsed = !this.isSchemeCollapsed;
    },
    toggleResourcePanel() {
      this.isResourceCollapsed = !this.isResourceCollapsed;
    },
    // 更新目录结构
    updateCatalog(coms) {
      try {
        if (!Array.isArray(coms) || coms.length === 0) {
          this.catalogData = [];
          return;
        }

        let catalogData = [];

        coms.forEach((item, moduleIndex) => {
          if (!item || !item.attrs) return;

          // 获取所有Directory类型的属性并排序
          const directoryAttrs = item.attrs
            .filter((attr) => attr && attr.type === "Directory")
            .sort((a, b) => {
              if (!a || !b) return 0;
              return (a.number || "").localeCompare(b.number || "", undefined, {
                numeric: true,
              });
            });

          directoryAttrs.forEach((attr) => {
            if (!attr) return;

            // 确保目录内容正确显示
            const content = attr.content || attr.name || "";
            const number = this.generateDirectoryNumber(
              moduleIndex,
              attr.level
            );

            const catalogItem = {
              id: `${moduleIndex}-${attr.id || ""}`,
              label: `${number} ${content}`.trim(),
              level: attr.level || 1,
              moduleIndex: moduleIndex,
              number: number,
              children: [],
            };

            // 更新原始属性的编号和内容
            attr.number = number;
            attr.content = content;

            // 根据level确定目录层级
            if (attr.level === 1) {
              catalogData.push(catalogItem);
            } else {
              const parent = this.findParentDirectory(catalogData, number);
              if (parent) {
                parent.children = parent.children || [];
                parent.children.push(catalogItem);
              }
            }
          });
        });

        // 更新目录数据
        this.catalogData = this.sortCatalogData(catalogData);

        // 更新原始组件中的目录信息
        this.updateComponentDirectories(coms);
      } catch (error) {
        console.error("Error updating catalog:", error);
        this.catalogData = [];
      }
    },

    // 生成目录编号
    generateDirectoryNumber(moduleIndex, level) {
      let number = "";

      if (level === 1) {
        // 一级标题使用模块序号
        number = (moduleIndex + 1).toString();
      } else {
        // 查找父级目录编号
        const parentNumber = this.findParentNumber(moduleIndex, level);

        // 获取当前级别的计数
        const siblings = this.getSiblingDirectories(
          moduleIndex,
          level,
          parentNumber
        );
        const currentCount = siblings.length + 1;

        // 组合编号
        number = `${parentNumber}.${currentCount}`;
      }

      return number;
    },

    // 获取同级目录项
    getSiblingDirectories(moduleIndex, level, parentNumber) {
      const siblings = [];

      // 遍历所有模块查找同级目录
      for (let i = 0; i < moduleIndex; i++) {
        const module = this.coms[i];
        if (module.attrs) {
          module.attrs.forEach((attr) => {
            if (
              attr.type === "Directory" &&
              attr.level === level &&
              attr.number.startsWith(parentNumber)
            ) {
              siblings.push(attr);
            }
          });
        }
      }

      return siblings;
    },

    // 更新组件中的目录信息
    updateComponentDirectories(coms) {
      coms.forEach((com, moduleIndex) => {
        if (!com.attrs) return;

        com.attrs.forEach((attr) => {
          if (attr.type === "Directory") {
            // 更新目录编号
            const number = this.generateDirectoryNumber(
              moduleIndex,
              attr.level
            );
            attr.number = number;

            // 确保内容正确显示
            if (!attr.content || attr.content.includes("未命名目录")) {
              attr.content = attr.name || `第${number}章`;
            }

            // 更新moduleIndex
            attr.moduleIndex = moduleIndex;
          }
        });
      });
    },

    // 处理拖拽结束后的更新
    handleDragEnd(draggingNode, dropNode, dropType) {
      if (!dropNode || !dropType) {
        console.log("无效的拖放操作");
        return;
      }

      // 获取源模块和目标模块的索引
      const sourceIndex = this.findModuleIndex(draggingNode.data);
      const targetIndex = this.findModuleIndex(dropNode.data);

      if (typeof sourceIndex !== "number" || typeof targetIndex !== "number") {
        console.error("无法确定模块索引");
        return;
      }

      // 计算最终目标位置
      let finalTargetIndex = targetIndex;
      if (dropType === "next") {
        finalTargetIndex++;
      }
      if (sourceIndex < finalTargetIndex) {
        finalTargetIndex--;
      }

      // 执行模块移动
      const [movedModule] = this.coms.splice(sourceIndex, 1);
      this.coms.splice(finalTargetIndex, 0, movedModule);

      // 更新目录结构
      this.$nextTick(() => {
        this.updateCatalog(this.coms);
        this.$forceUpdate();
      });
    },

    // 改进的查找父目录方法
    findParentDirectory(catalogData, number) {
      if (!number || !number.includes(".")) return null;

      const parentNumber = number.split(".").slice(0, -1).join(".");

      const findInItems = (items) => {
        for (let item of items) {
          if (item.number === parentNumber) {
            return item;
          }
          if (item.children && item.children.length > 0) {
            const found = findInItems(item.children);
            if (found) return found;
          }
        }
        return null;
      };

      return findInItems(catalogData);
    },

    // 高亮当前选中的目录项
    highlightCurrentCatalogItem(moduleIndex) {
      if (!this.$refs.catalogTree) return;

      const findNode = (data) => {
        for (let item of data) {
          if (item.moduleIndex === moduleIndex) {
            this.$refs.catalogTree.setCurrentKey(item.id);
            return true;
          }
          if (item.children && item.children.length) {
            if (findNode(item.children)) return true;
          }
        }
        return false;
      };

      findNode(this.catalogData);
    },

    // 处理目录项点击
    handleCatalogClick(data) {
      // 如果正在编辑，不触发其他操作
      if (data.isEditing) return;

      // 其他点击处理逻辑...
      console.log("点击的目录项:", data);
    },

    // 处理组件内容更新
    onSetComs(newComs) {
      this.coms = newComs;
      this.updateCatalog(newComs);
    },

    // 处理拖拽结束后的目录更新
    handleDragEnd() {
      this.$nextTick(() => {
        this.updateCatalog(this.coms);
      });
    },

    // 添加 sortCatalogData 方法
    sortCatalogData(catalogData) {
      if (!Array.isArray(catalogData)) {
        return [];
      }

      // 递归排序函数
      const sortItems = (items) => {
        return items
          .sort((a, b) => {
            // 按照编号进行数字排序
            const aNum = a.number.split(".").map(Number);
            const bNum = b.number.split(".").map(Number);

            // 比较每一级的编号
            for (let i = 0; i < Math.min(aNum.length, bNum.length); i++) {
              if (aNum[i] !== bNum[i]) {
                return aNum[i] - bNum[i];
              }
            }

            // 如果前面的编号都相同，较短的编号在前
            return aNum.length - bNum.length;
          })
          .map((item) => {
            // 递归排序子目录
            if (item.children && item.children.length > 0) {
              item.children = sortItems(item.children);
            }
            return item;
          });
      };

      // 对顶层目录进行排序
      return sortItems(catalogData);
    },

    // 添加允许拖拽和放置的方法
    allowDrag(node) {
      // 允许所有节点拖拽
      return true;
    },

    allowDrop(draggingNode, dropNode, type) {
      // 不允许跨级拖拽，只允许同级拖拽
      return draggingNode.data.level === dropNode.data.level;
    },

    handleDragEnd(draggingNode, dropNode, dropType, ev) {
      if (!dropNode) return;

      // 获取拖拽节点和目标节点的模块索引
      const dragModuleIndex = draggingNode.data.moduleIndex;
      const dropModuleIndex = dropNode.data.moduleIndex;

      // 如果是同一级目录的拖拽
      if (draggingNode.data.level === dropNode.data.level) {
        // 更新模块顺序
        const dragModule = this.coms[dragModuleIndex];
        this.coms.splice(dragModuleIndex, 1);

        // 根据放置类型确定插入位置
        const targetIndex =
          dropType === "before" ? dropModuleIndex : dropModuleIndex + 1;

        this.coms.splice(targetIndex, 0, dragModule);

        // 重新生成目录编号
        this.updateDirectoryNumbers();
      }
    },

    // 更新目录编号的方法
    updateDirectoryNumbers() {
      this.coms.forEach((module, moduleIndex) => {
        const directories = module.attrs.filter(
          (attr) => attr.type === "Directory"
        );
        directories.forEach((dir) => {
          const { level } = dir;
          const { number, content } = this.generateNumberedContent(
            moduleIndex,
            level
          );
          dir.number = number;
          // 只更新编号部分，保留原有内容
          dir.content = dir.content.replace(/^[\d.]+/, number);
        });
      });

      // 强制更新视图
      this.$nextTick(() => {
        this.updateCatalog(this.coms);
        this.$forceUpdate();
      });
    },

    // 开始编辑目录
    handleStartEdit(data) {
      // 设置编辑状态和临时编辑内容
      this.$set(data, "isEditing", true);
      this.$set(
        data,
        "editingContent",
        data.label.split(" ").slice(1).join(" ")
      ); // 只编辑内容部分，保留编号

      // 等待DOM更新后聚焦输入框
      this.$nextTick(() => {
        if (this.$refs.editInput && this.$refs.editInput[0]) {
          this.$refs.editInput[0].focus();
        }
      });
    },

    // 完成编辑
    handleEditComplete(data) {
      if (!data.isEditing) return;

      // 获取原始编号
      const number = data.label.split(" ")[0];

      // 更新目录树节点的显示文本
      data.label = `${number} ${data.editingContent}`;

      // 更新对应模块的目录属性
      const { moduleIndex } = data;
      const module = this.coms[moduleIndex];
      if (module) {
        const directoryAttr = module.attrs.find(
          (attr) => attr.type === "Directory" && attr.number === number
        );

        if (directoryAttr) {
          directoryAttr.content = data.editingContent;
        }
      }

      // 清除编辑状态
      this.$delete(data, "isEditing");
      this.$delete(data, "editingContent");

      // 强制更新视图
      this.$forceUpdate();
    },

    // 添加新方法：更新目录显示
    updateDirectoryDisplay(com) {
      // 按级别和编号排序目录
      const directories = com.attrs
        .filter((attr) => attr.type === "Directory")
        .sort((a, b) => {
          if (a.level !== b.level) return a.level - b.level;
          return a.number.localeCompare(b.number, undefined, { numeric: true });
        });

      // 更新每个目录的显示内容
      directories.forEach((dir) => {
        const pattern = new RegExp(`{{${dir.id}}}`, "g");
        com.content = com.content.replace(
          pattern,
          `${dir.number} {{${dir.id}}}`
        );
      });
    },
    handleDirectoryDragEnd(event, data) {
      // 处理拖拽结束事件
      console.log("Drag end:", event);
      this.handleDirectorySave(data);
    },
    // ... existing code ...

    /* 插入产品属性 */
    onInsertProductAttr(e) {
      if (this.comIndex < 0) {
        this.$message.warning("请选择插入图层");
        return false;
      }

      const com = this.coms[this.comIndex];
      if (!com) {
        this.$message.warning("请先添加文档内容");
        return false;
      }

      // 生成唯一ID
      const attrId = `ProductAttr_${Date.now()}`;

      const data = {
        type: "ProductAttr",
        id: attrId,
        name: "商品属性",
        intro: "商品属性",
        content: e.content || "",
        attrs: e.attrs || {},
      };

      // 添加到组件属性中
      com.attrs.push(data);

      // 更新文本内容
      this.insertCmd = {
        content: `{{${attrId}}}`,
      };

      // 如果有产品信息，添加到文档关联商品
      if (e.productInfo) {
        if (!this.docAttr.linkProduct) {
          this.docAttr.linkProduct = [];
        }
        // 避免重复添加
        if (
          !this.docAttr.linkProduct.some(
            (p) => p.dcp_p_no === e.productInfo.dcp_p_no
          )
        ) {
          this.docAttr.linkProduct.push(e.productInfo);
        }
      }

      // 关闭产品属性选择框（如果有的话）
      this.showProductAttr = false;

      // 强制更新视图
      this.$nextTick(() => {
        this.$forceUpdate();
      });

      return true;
    },

    // 添加一个解析目录内容的方法
    parseDirectoryContent(content) {
      if (!content) return "";

      // 匹配 {{Directory_x_x_xxxxxxxxxx}} 格式的内容
      const directoryPattern = /{{(Directory_\d+_\d+_\d+)}}/g;

      return content.replace(directoryPattern, (match, directoryId) => {
        // 遍历所有组件查找对应的目录项
        for (const com of this.coms) {
          const directoryAttr = com.attrs.find(
            (attr) => attr.type === "Directory" && attr.id === directoryId
          );

          if (directoryAttr) {
            // 返回格式化的目录内容：编号 + 内容
            return `${directoryAttr.number} ${directoryAttr.content}`;
          }
        }
        return match; // 如果找不到对应的目录项，保持原样
      });
    },

    // 修改预览处理方法
    handlePreview() {
      this.showViewForm = true;

      // 处理预览内容
      const previewContent = this.coms.map((com) => {
        // 深拷贝以避免修改原始数据
        const previewCom = JSON.parse(JSON.stringify(com));

        // 如果有内容字段，处理目录内容
        if (previewCom.content) {
          previewCom.content = this.parseDirectoryContent(previewCom.content);
        }

        // 处理属性中的目录内容
        if (previewCom.attrs) {
          previewCom.attrs = previewCom.attrs.map((attr) => {
            if (attr.type === "Directory") {
              return {
                ...attr,
                content: `${attr.number} ${attr.content}`,
              };
            }
            return attr;
          });
        }

        return previewCom;
      });

      // 更新预览数据
      this.previewData = previewContent;
    },

    // 在 ViewForm 组件中添加内容解析
    // 确保 ViewForm 组件接收并正确处理目录内容
  },
};
</script>

<style lang="scss">
@import "./create.scss";

.el-collapse,
.el-collapse-item__wrap {
  border: none;
}
.el-collapse,
.el-collapse-item__header {
  border: none;
  .el-collapse-item__arrow {
    margin: 0;
  }
}
.borderless-collapse {
  border: none;
  ::v-deep .el-collapse-item__header,
  ::v-deep .el-collapse-item__wrap,
  ::v-deep .el-collapse-item__content,
  ::v-deep .el-collapse-item {
    border: none;
  }

  ::v-deep .el-collapse-item__wrap {
    border-bottom: none !important;
  }
}
.scrollable-container {
  overflow-x: auto;
  white-space: nowrap;
  width: 350px;
  padding-bottom: 10px;
}

.min-width-content {
  /*   display: inline-block;
  vertical-align: top; */
  min-width: 150px;
  white-space: normal;
}
// 树节点样式调整
::v-deep .el-tree-node__content {
  height: 32px;

  &:hover {
    background-color: #f5f7fa;
  }
}

::v-deep .el-tree-node.is-current > .el-tree-node__content {
  background-color: #f0f7ff;
  color: #409eff;
}
/*.el-collapse-item {
  display: inline-block;
  vertical-align: top;
} */

.resource-list {
  .resource-category {
    margin-bottom: 10px;

    .category-title {
      font-weight: bold;
      margin-bottom: 5px;
      color: #606266;
    }

    .resource-items {
      padding-left: 20px;

      .resource-item {
        margin: 5px 0;

        .el-checkbox {
          display: flex;
          align-items: center;
        }
      }
    }
  }
}

.template-content {
  .search-box {
    padding: 10px;
    border-bottom: 1px solid #ebeef5;

    .el-input {
      width: 300px;
    }
  }
}
.module-list-container {
  width: 320px;
  margin-top: 110px;
  /* position: absolute;
  top: 135px;
  right: 111px; */
  /*   border: 1px solid #dcdfe6; */
  border-radius: 4px;
  padding: 10px;

  .module-item {
    display: flex;
    align-items: center;
    padding: 10px;
    border-bottom: 1px solid #ebeef5;

    &:last-child {
      border-bottom: none;
    }

    &.active-module {
      background-color: #f5f7fa;
    }

    .drag-handle {
      cursor: move;
      margin-right: 15px;
    }

    .module-info {
      flex: 1;

      .module-category,
      .module-name {
        display: flex;
        align-items: center;
        margin-bottom: 5px;

        &:last-child {
          margin-bottom: 0;
        }

        .label {
          color: #606266;
          margin-right: 10px;
          min-width: 70px;
        }

        .value {
          color: #303133;
        }
      }
    }
  }
}

.custom-tree-node {
  cursor: move;
  user-select: none;
}

.custom-tree-node[draggable="false"] {
  cursor: default;
}

/* 拖拽时的视觉反馈 */
.is-drop-inner {
  border: 2px dashed #409eff;
}

.left_scheme,
.natural {
  transition: width 0.3s;
  overflow: hidden;

  &.collapsed {
    width: 50px !important;

    .scheme-header,
    .resource-header-title {
      padding: 10px;

      .title,
      .title-left {
        display: none;
      }

      .el-icon-menu {
        margin-left: 0;
      }
    }
  }

  .el-icon-menu {
    cursor: pointer;
    padding: 5px;
    transition: transform 0.3s;

    &:hover {
      color: #409eff;
    }
  }

  &.collapsed .el-icon-menu {
    transform: rotate(180deg);
  }
}

.catalog-content {
  .el-tree {
    background: transparent;

    .el-tree-node__content {
      height: auto;
      padding: 8px 0;

      &:hover {
        background-color: rgba(64, 158, 255, 0.1);
      }
    }

    .custom-tree-node {
      flex: 1;
      display: flex;
      align-items: center;
      padding-right: 8px;
      font-size: 14px;

      i {
        margin-right: 5px;
      }
    }
  }
}

// 添加模块高亮动画
@keyframes highlight-pulse {
  0% {
    background-color: transparent;
  }
  50% {
    background-color: rgba(64, 158, 255, 0.2);
  }
  100% {
    background-color: transparent;
  }
}

.highlight {
  animation: highlight-pulse 2s ease-in-out;
}

/* 添加到组件的 <style> 部分 */

.leftContent {
  .el-tree {
    .el-tree-node {
      position: relative;

      /* 为每个节点添加左侧垂直线 */
      &:before {
        content: "";
        position: absolute;
        left: 8px; /* 调整线条位置 */
        top: 0;
        bottom: 0;
        width: 2px;
        background-color: #1aad19; /* 线条颜色 */
        z-index: 1;
      }

      /* 移除最后一个子节点的垂直线延伸 */
      &:last-child:before {
        height: 20px; /* 调整到节点中心位置 */
      }

      /* 为每个节点添加水平连接线 */ /* 与垂直线对齐 */ /* 水平线长度 */
      /* .el-tree-node__content:before {
      content: "";
      position: absolute;
      left: 8px; 
      top: 50%;
      width: 16px; 
      height: 2px;
      background-color: #1aad19;
      z-index: 1;
    } */
    }

    /* 移除根节点的垂直线 */
    & > .el-tree-node:before {
      display: none;
    }

    /* 移除第一层节点的连接线 */
    & > .el-tree-node > .el-tree-node__content:before {
      display: none;
    }

    /* 调整节点内容的位置，为线条留出空间 */
    .el-tree-node__content {
      position: relative;
      /* 调整缩进 */
    }

    /* 确保展开箭头在正确位置 */
    .el-tree-node__expand-icon {
      padding: 6px;
      margin-left: 10px;
    }
  }
}

/* 自定义树节点样式 */
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 0 8px;
  font-size: 14px;

  /* 编辑输入框样式 */
  .el-input {
    margin-left: -4px;
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-right: 8px;
}

.directory-actions {
  opacity: 0;
  transition: opacity 0.2s;
}

.custom-tree-node:hover .directory-actions {
  opacity: 1;
}
.module-actions {
  display: flex;
  gap: 8px; /* 按钮之间的间距 */
  align-items: center;
  white-space: nowrap;
  flex-direction: column;
}
.module-actions .el-button {
  padding: 3px 0;
 margin-left: 0;
}
</style>
