Bläddra i källkod

修改模板页面

yangg 6 månader sedan
förälder
incheckning
c3530eb272

+ 7 - 0
ui/src/layout/components/AppMain.vue

@@ -33,6 +33,13 @@ export default {
   width: 100%;
   position: relative;
   overflow: hidden;
+  // 当父元素有 no-layout 类时的样式
+  .no-layout & {
+    padding: 0;
+    margin: 0;
+    width: 100%;
+    min-height: 100vh;  // 使用视窗高度
+  }
 }
 
 .fixed-header + .app-main {

+ 99 - 66
ui/src/layout/index.vue

@@ -1,111 +1,144 @@
 <template>
-  <div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
-    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
-    <sidebar v-if="!sidebar.hide" class="sidebar-container"/>
-    <div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
-      <div :class="{'fixed-header':fixedHeader}">
-        <navbar/>
-        <tags-view v-if="needTagsView"/>
+  <div
+    :class="classObj"
+    class="app-wrapper"
+    :style="{ '--current-color': theme }"
+  >
+    <div
+      v-if="device === 'mobile' && sidebar.opened"
+      class="drawer-bg"
+      @click="handleClickOutside"
+    />
+    <sidebar v-if="!sidebar.hide && !isHideLayout" class="sidebar-container" />
+    <div
+      :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide,'no-layout': isHideLayout }"
+      class="main-container"
+    >
+      <div v-if="!isHideLayout" :class="{ 'fixed-header': fixedHeader }">
+        <navbar />
+        <tags-view v-if="needTagsView" />
       </div>
-      <app-main/>
-      <right-panel>
-        <settings/>
+      <app-main />
+      <right-panel v-if="!isHideLayout">
+        <settings />
       </right-panel>
     </div>
   </div>
 </template>
 
 <script>
-import RightPanel from '@/components/RightPanel'
-import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
-import ResizeMixin from './mixin/ResizeHandler'
-import { mapState } from 'vuex'
-import variables from '@/assets/styles/variables.scss'
+import RightPanel from "@/components/RightPanel";
+import { AppMain, Navbar, Settings, Sidebar, TagsView } from "./components";
+import ResizeMixin from "./mixin/ResizeHandler";
+import { mapState } from "vuex";
+import variables from "@/assets/styles/variables.scss";
 
 export default {
-  name: 'Layout',
+  name: "Layout",
   components: {
     AppMain,
     Navbar,
     RightPanel,
     Settings,
     Sidebar,
-    TagsView
+    TagsView,
   },
   mixins: [ResizeMixin],
   computed: {
     ...mapState({
-      theme: state => state.settings.theme,
-      sideTheme: state => state.settings.sideTheme,
-      sidebar: state => state.app.sidebar,
-      device: state => state.app.device,
-      needTagsView: state => state.settings.tagsView,
-      fixedHeader: state => state.settings.fixedHeader
+      theme: (state) => state.settings.theme,
+      sideTheme: (state) => state.settings.sideTheme,
+      sidebar: (state) => state.app.sidebar,
+      device: (state) => state.app.device,
+      needTagsView: (state) => state.settings.tagsView,
+      fixedHeader: (state) => state.settings.fixedHeader,
     }),
     classObj() {
       return {
         hideSidebar: !this.sidebar.opened,
         openSidebar: this.sidebar.opened,
         withoutAnimation: this.sidebar.withoutAnimation,
-        mobile: this.device === 'mobile'
-      }
+        mobile: this.device === "mobile",
+      };
     },
     variables() {
       return variables;
-    }
+    },
+    isHideLayout() {
+      // 检查当前路由是否需要隐藏布局
+      return this.$route.path === "/document/system/document/create";
+    },
   },
   methods: {
     handleClickOutside() {
-      this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
-    }
-  }
-}
+      this.$store.dispatch("app/closeSideBar", { withoutAnimation: false });
+    },
+  },
+};
 </script>
 
 <style lang="scss" scoped>
-  @import "~@/assets/styles/mixin.scss";
-  @import "~@/assets/styles/variables.scss";
+@import "~@/assets/styles/mixin.scss";
+@import "~@/assets/styles/variables.scss";
 
-  .app-wrapper {
-    @include clearfix;
-    position: relative;
-    height: 100%;
-    width: 100%;
+.app-wrapper {
+  @include clearfix;
+  position: relative;
+  height: 100%;
+  width: 100%;
 
-    &.mobile.openSidebar {
-      position: fixed;
-      top: 0;
-    }
-  }
-
-  .drawer-bg {
-    background: #000;
-    opacity: 0.3;
-    width: 100%;
-    top: 0;
-    height: 100%;
-    position: absolute;
-    z-index: 999;
-  }
-
-  .fixed-header {
+  &.mobile.openSidebar {
     position: fixed;
     top: 0;
-    right: 0;
-    z-index: 9;
-    width: calc(100% - #{$base-sidebar-width});
-    transition: width 0.28s;
   }
+}
 
-  .hideSidebar .fixed-header {
-    width: calc(100% - 54px);
-  }
+.main-container {
+  min-height: 100%;
+  transition: margin-left 0.28s;
+  margin-left: $base-sidebar-width;
+  position: relative;
 
-  .sidebarHide .fixed-header {
-    width: 100%;
-  }
+  &.no-layout {
+    margin-left: 0 !important;
+    width: 100% !important;
+    padding-top: 0 !important;
 
-  .mobile .fixed-header {
-    width: 100%;
+    :deep(.app-main) {
+      padding: 0 !important;
+      margin: 0 !important;
+    }
   }
+}
+
+.drawer-bg {
+  background: #000;
+  opacity: 0.3;
+  width: 100%;
+  top: 0;
+  height: 100%;
+  position: absolute;
+  z-index: 999;
+}
+
+.fixed-header {
+  position: fixed;
+  top: 0;
+  right: 0;
+  z-index: 9;
+  width: calc(100% - #{$base-sidebar-width});
+  transition: width 0.28s;
+}
+
+.hideSidebar .fixed-header {
+  width: calc(100% - 54px);
+}
+
+.sidebarHide .fixed-header {
+  width: 100%;
+}
+
+.mobile .fixed-header {
+  width: 100%;
+}
 </style>

+ 9 - 0
ui/src/router/index.js

@@ -106,6 +106,7 @@ export const dynamicRoutes = [
       }
     ]
   },
+  
   {
     path: '/system/role-auth',
     component: Layout,
@@ -161,6 +162,14 @@ export const dynamicRoutes = [
         meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
       }
     ]
+  },
+  {
+    path: '/document/system/document/create',
+    component: () => import('@/views/system/document/create'),
+    name: 'DocumentCreate',
+    meta: {
+      hideLayout: true  // 添加这个标记
+    }
   }
 ]
 

+ 270 - 19
ui/src/views/system/document/create.scss

@@ -1,18 +1,17 @@
-
 .doc-container{
-  width:90%;
+  width:100%;
   min-height:90vh;
   position:relative;
   .editor-top{
     display: flex;
-    width:88%;
+    width:100%;
     height:60px;
     min-height: 60px;
     flex-direction: row;
     justify-content: space-between;
     align-items: center;
     position:fixed;
-    top:85px;
+    top:0;
     z-index: 999;
     background: #fff;
     border-bottom:1px solid #ebebeb;
@@ -56,10 +55,198 @@
     min-height:80vh;
     margin-top:60px;
     border:1px solid #ebebeb;
+    display: flex;
+    justify-content: space-between;
+    .left_scheme {
+      width: 250px;
+      border-right: 1px solid #e6e6e6;
+      height: 93vh;
+      
+      .scheme-header {
+        padding: 10px;
+        border-bottom: 1px solid #e6e6e6;
+    
+        .title {
+          font-size: 14px;
+          font-weight: bold;
+          margin-bottom: 10px;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+    
+          .count {
+            color: #666;
+            font-size: 12px;
+            font-weight: normal;
+          }
+        }
+    
+        .search {
+          margin-bottom: 10px;
+        }
+    
+        .action-btns {
+          display: flex;
+          gap: 10px;
+          margin-bottom: 10px;
+    
+          .el-button {
+            flex: 1;
+          }
+        }
+    
+        .current-scheme {
+          font-size: 13px;
+          color: #666;
+          margin-top: 5px;
+        }
+      }
+    
+      .scheme-content {
+        padding: 10px;
+        height: calc(100% - 180px);
+        overflow-y: auto;
+    
+        .el-tree {
+          background: transparent;
+        }
+    
+        .custom-tree-node {
+          display: flex;
+          align-items: center;
+          
+          i {
+            margin-right: 5px;
+            font-size: 16px;
+            color: #909399;
+          }
+        }
+      }
+    }
+    .natural{
+      width: 250px;
+      border-right: 1px solid #e6e6e6;
+      height: 93vh;
+      background: #fff;
+      .resource-header-title {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 10px 15px;
+        border-bottom: 1px solid #e6e6e6;
+        
+        .title-left {
+          display: flex;
+          align-items: center;
+          gap: 8px;
+          font-size: 14px;
+          
+          .resource-count {
+            color: #666;
+            font-size: 12px;
+          }
+        }
+        
+        .el-icon-menu {
+          color: #666;
+          font-size: 18px;
+          cursor: pointer;
+        }
+      }
+      .resource-container {
+        padding: 15px;
+
+        .resource-header {
+          margin-bottom: 15px;
+
+          .el-input {
+            margin-bottom: 10px;
+          }
+
+          .action-btns {
+            display: flex;
+            gap: 10px;
+            
+            .el-button {
+              flex: 1;
+              height: 32px;
+              padding: 0;
+              font-size: 12px;
+            }
+          }
+        }
+
+        .resource-status {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin: 10px 0;
+          color: #666;
+          font-size: 12px;
+        }
+
+        .resource-content {
+          .el-collapse {
+            border: none;
+            
+            .el-collapse-item {
+              margin-bottom: 2px;
+              
+              &__header {
+                background: #f7f7f7;
+                height: 40px;
+                line-height: 40px;
+                padding: 0 15px;
+                font-size: 13px;
+                position: relative;
+                
+                .el-icon-arrow-up {
+                  position: absolute;
+                  right: 15px;
+                  transition: transform 0.3s;
+                  font-size: 12px;
+                  
+                  .el-collapse-item.is-active & {
+                    transform: rotate(180deg);
+                  }
+                }
+              }
+              
+              &__content {
+                padding: 10px 0;
+              }
+            }
+          }
+
+          .resource-list {
+            .resource-item {
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+              padding: 8px 15px;
+              font-size: 12px;
+              
+              &:hover {
+                background: #f5f7fa;
+              }
+
+              .el-checkbox {
+                margin-right: 10px;
+              }
+
+              .el-icon-menu {
+                color: #999;
+                cursor: move;
+                font-size: 14px;
+              }
+            }
+          }
+        }
+      }
+    }
     .neary-doc{
       position:fixed;
-      top:145px;
-      left:203px;
+      left:0;
       width:205px;
       // min-height: 100%;
       height: 99vh;
@@ -112,20 +299,62 @@
     }
     .editor-main{
       width:65%;
-      margin:auto;
       overflow: hidden;
-      overflow-y: auto;
+      /* overflow-y: auto; */
       position:relative;
-      .menus-box{
-        position: fixed;
-        top:145px;
-        background:#FFF;
-        z-index:999;
-        width: 61.5%;
+      margin:0 auto;
+      .editor-tabs {
+        height: 100%;
+        
+        .el-tabs {
+          height: 100%;
+          
+          .el-tabs__content {
+            height: calc(100% - 40px);
+            
+            .el-tab-pane {
+              height: 100%;
+            }
+          }
+        }
       }
-
-      .editor-box{
-        margin-top:80px;
+      .catalog-content {
+        padding: 20px;
+        height: 100%;
+        overflow-y: auto;
+    
+        .el-tree {
+          .custom-tree-node {
+            flex: 1;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            font-size: 14px;
+            padding-right: 8px;
+          }
+    
+          .expand-icon {
+            color: #909399;
+          }
+        }
+      }
+      .template-content {
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+    
+        .menus-box{
+          position: absolute;
+          background: #FFF;
+          z-index: 3;
+          width: 100%;
+        }
+    
+        .editor-box {
+          margin-top:80px;
+          flex: 1;
+          // 原有的editor-box样式
+        }
       }
       .editor{
         width: 100%;
@@ -149,7 +378,7 @@
       width:255px;
       height: 100vh;
       position:fixed;
-      top:145px;
+      top:61px;
       right:0;
       border:1px solid #f0f0f0;
       z-index: 1000 !important;
@@ -159,7 +388,7 @@
         position: fixed;
         width:60px;
         right:254px;
-        top:165px;
+        top:65px;
         font-size:12px;
         .item{
             background-color: #fff;
@@ -223,4 +452,26 @@
 .active-item{
   background-color: #155bd4;
   color: #fff;
+}
+
+
+
+/* ::v-deep .el-collapse {
+  border: none;
+
+  .el-collapse-item__header {
+    background-color: #f5f7fa;
+    padding: 0 15px;
+    font-weight: bold;
+  }
+
+  .el-collapse-item__content {
+    padding: 10px 15px;
+  }
+} */
+
+::v-deep .el-collapse-item__header {
+  .el-collapse-item__arrow {
+    display: none; // 隐藏默认箭头
+  }
 }

+ 555 - 180
ui/src/views/system/document/create.vue

@@ -14,8 +14,9 @@
           <span>当前打开模版:</span
           >{{ docAttr.title == "" ? "新建模版" : docAttr.title }}
         </div>
-        <div class="creator" >
-          <span>创建者:</span><!-- {{ userInfo && userInfo.username }} -->
+        <div class="creator">
+          <span>创建者:</span
+          ><!-- {{ userInfo && userInfo.username }} -->
         </div>
       </div>
       <div class="right">
@@ -44,21 +45,13 @@
         > -->
         <el-button
           type="primary"
-          v-if="
-            type !== 'module' &&
-            type !== 'document' &&
-            !articleId
-          "
+          v-if="type !== 'module' && type !== 'document' && !articleId"
           @click="onSaveUpload"
           >保存</el-button
         >
         <el-button
           type="primary"
-          v-if="
-            type !== 'module' &&
-            type !== 'document' &&
-            articleId
-          "
+          v-if="type !== 'module' && type !== 'document' && articleId"
           @click="onUpload"
           >更新</el-button
         >
@@ -91,11 +84,176 @@
       </div>
     </div>
     <div class="editor-content">
-      <div class="neary-doc">
+      <div class="left_scheme">
+        <div class="scheme-header">
+          <div class="title">
+            请选择可用的方案
+            <span class="count">[方案数量:47]</span>
+            <i class="el-icon-menu"></i>
+          </div>
+          <div class="search">
+            <el-input
+              v-model="searchKey"
+              placeholder="请输入搜索"
+              prefix-icon="el-icon-search"
+              clearable
+            >
+            </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">
+          <el-tree
+            :data="schemeData"
+            :props="defaultProps"
+            @node-click="handleNodeClick"
+            :default-expanded-keys="expandedKeys"
+          >
+            <span class="custom-tree-node" slot-scope="{ node, data }">
+              <span>
+                <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">
+        <div class="resource-header-title">
+          <div class="title-left">
+            <span>请选择可用的资源</span>
+            <span class="resource-count">[资源明细] 资源数量:474</span>
+          </div>
+          <i class="el-icon-menu"></i>
+        </div>
+        <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">
+              <!-- DLP产品 -->
+              <el-collapse-item name="dlp">
+                <template slot="title">
+                  <span>DLP产品</span>
+                 <!--  <i class="el-icon-arrow-up" :class="{ 'is-active': activeCategories.includes('dlp') }"></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>
+
+              <!-- LED产品系列 -->
+              <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>
+      </div>
+
+      <!--  <div class="neary-doc">
         <div class="left-content">
-          <!--  <div class="search">
-            <el-input placeholder="搜索文档标题"></el-input>
-          </div> -->
           <div class="new-article">
             <div v-if="showView == 0 && type !== 'module'">
               <el-collapse v-model="activeNames">
@@ -138,71 +296,6 @@
               </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"
-                >
-                  <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"
-                    >
-                      <draggable
-                        v-model="child.dataList"
-                        :options="{
-                          group: { name: 'itxst', pull: 'clone' },
-                          sort: true,
-                        }"
-                        :disabled="type == 'module'"
-                      >
-                        <transition-group>
-                          <div
-                            class="sub-menus"
-                            v-for="(its, index) in child.dataList"
-                            :key="index"
-                          >
-                            <div>{{ its.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"
-                        v-for="(it, index) in item.dataList"
-                        :key="index"
-                      >
-                        <div>{{ it.name }}</div>
-                      </div>
-                    </transition-group>
-                  </draggable>
-                </el-collapse-item>
-              </el-collapse> -->
               <el-collapse
                 v-model="activeModel"
                 :accordion="true"
@@ -413,112 +506,187 @@
             模块列表
           </div>
         </div>
-      </div>
+      </div> -->
 
       <div class="editor-main">
-        <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
-            :coms="coms"
-            :comIndex="comIndex"
-            :isAdmin="isAdmin"
-            :templateCate="categoryList"
-            :insertCmd="insertCmd"
-            @onSetActiveIndex="onSetActiveIndex"
-            @onInsert="onInsert"
-            @onLoadArticle="onLoadArticle"
-            @onRebuild="onRebuild"
-            @onDelete="onRemove"
-            @onSetComs="onSetComs"
-          ></editor>
+        <!-- 添加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
+                  :data="catalogData"
+                  :props="catalogProps"
+                  default-expand-all
+                  @node-click="handleCatalogClick"
+                >
+                  <span class="custom-tree-node" slot-scope="{ data }"
+                    ><!-- node, -->
+                    <span>{{ data.label }}</span>
+                    <span v-if="data.children" class="expand-icon">
+                      <i class="el-icon-arrow-right"></i>
+                    </span>
+                  </span>
+                </el-tree>
+              </div>
+            </el-tab-pane>
+            <el-tab-pane label="模板内容" name="template">
+              <div class="template-content">
+                <!-- 原有的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
+                    :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>
 
-      <div class="editor-option">
-        <div class="editor-menu">
-          <div
-            v-if="type !== 'module' && type !== 'document'"
-            class="item"
-            @click="onSetActiveIndexs(3)"
-            :class="docuComIndex == 3 ? 'active-item' : ''"
-          >
-            <span class="name">模版属性</span>
-          </div>
-          <div
-            v-if="type !== 'module'"
-            class="item"
-            @click="onSetActiveIndex(9998)"
-            :class="comIndex == 9998 ? 'active-item' : ''"
-          >
-            <span class="name">模块管理</span>
-          </div>
-          <div
-            class="item"
-            @click="onCatalogIndex(9997)"
-            :class="catalogIndex == 9997 ? 'active-item' : ''"
+    <!-- 新增资源选择弹框 -->
+   <!--  <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
           >
-            <span class="name">目录信息</span>
+          </el-input>
+          <div class="action-btns">
+            <el-button type="primary" @click="createResource"
+              >新建资源</el-button
+            >
+            <el-button type="primary" @click="createResourceCategory"
+              >新建资源分类</el-button
+            >
           </div>
-          <div
-            class="item"
-            @click="onAttributeIndex(1)"
-            :class="AttributeIndex == 1 ? 'active-item' : ''"
+        </div>
+
+        <div class="resource-status">
+          已打开1个资源,已选择3个资源
+          <el-button size="small" plain @click="refreshResources"
+            >更新</el-button
           >
-            <span class="name">属性变量</span>
-          </div>
         </div>
 
-        <template
-          v-if="docuComIndex == 3 && type !== 'module' && type !== 'document'"
-        >
-          <docAttr :attrs="docAttr"></docAttr>
-        </template>
-        <template v-if="comIndex == 9998">
-          <comList
-            :coms="coms"
-            @onRemove="onRemove"
-            @onSetActive="onSetActiveIndex"
-            @onRebuild="onRebuild"
-          ></comList>
-        </template>
-        <template v-if="catalogIndex == 9997">
-          <Directory :coms="coms" />
-        </template>
-        <!-- comIndex != 9999 && comIndex != 9998 && comIndex != 9997 AttributeIndex==1-->
-        <!-- <template
-          v-if="
-            comIndex != 9999 &&
-            comIndex != 9998 &&
-            catalogIndex != 9997 &&
-            AttributeIndex != 1
-          "
-        >
-          <Attribute
-            :com="coms[comIndex]"
-            @onRefresh="initCategoryList"
-          ></Attribute>
-        </template> -->
-        <template v-if="AttributeIndex == 1">
-          <attributeVar
-            :com="coms[comIndex]"
-            @onRefresh="initCategoryList"
-          ></attributeVar>
-        </template>
-        <!-- <Directory :coms="coms" /> -->
+        <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>
-    </div>
+    </el-dialog> -->
 
     <el-dialog
       :visible.sync="showViewForm"
@@ -705,6 +873,99 @@ export default {
         ],
       },
       articleCategoryList: [],
+
+      //方案
+      searchKey: "",
+      currentScheme: "",
+      expandedKeys: [], // 默认展开的节点
+      schemeData: [
+        {
+          label: "LED项目",
+          children: [],
+        },
+        {
+          label: "LCD项目",
+          children: [],
+        },
+        {
+          label: "集成项目",
+          children: [
+            {
+              label: "方案一",
+            },
+            {
+              label: "方案二",
+            },
+            {
+              label: "方案三",
+            },
+          ],
+        },
+      ],
+      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: [
+        {
+          label: "1. 概述 4",
+          children: [
+            {
+              label: "1.1. 强大的显示功能",
+              children: [
+                { label: "1.1.1. 计算机信号显示" },
+                { label: "1.1.2. 视频信号显示" },
+                { label: "1.1.3. 海量流媒体信号接入" },
+                { label: "1.1.4. 网络信号显示" },
+                { label: "1.1.5. 信号综合处理" },
+                { label: "1.1.6. 显示效果及图像拼接" },
+              ],
+            },
+            { label: "1.2. 任意开窗漫游显示" },
+            { label: "1.3. 信号混合显示" },
+            { label: "1.4. 全数字连接" },
+          ],
+        },
+        {
+          label: "2. 系统设计",
+          children: [
+            { label: "2.1. 设计标准及规范" },
+            { label: "2.2. 系统规模及尺寸" },
+          ],
+        },
+      ],
+      catalogProps: {
+        children: "children",
+        label: "label",
+      },
     };
   },
   watch: {
@@ -744,7 +1005,7 @@ export default {
     if (templateId > 0) {
       this.loadTemplateInfo(templateId);
     }
-    this.isAdmin = 2//this.userInfo ? this.userInfo.roleInfo.is_admin : 2;
+    this.isAdmin = 2; //this.userInfo ? this.userInfo.roleInfo.is_admin : 2;
     this.initArticleCategoryList();
     if (this.type !== "module" && this.type !== "document") {
       document.title = "新建模版-" + settings.title;
@@ -765,6 +1026,109 @@ export default {
   },
 
   methods: {
+    /* 切换目录/模板 */
+    handleClick(val) {
+      if (val.name === "catalog") {
+        // 初始化目录数据
+        let catalogData = [];
+
+        this.coms.forEach((item, moduleIndex) => {
+          // 获取所有Directory类型的属性并排序
+          const directoryAttrs = item.attrs
+            .filter((attr) => attr.type === "Directory")
+            .sort((a, b) => {
+              // 首先按level排序
+              if (a.level !== b.level) {
+                return a.level - b.level;
+              }
+              // level相同时按number排序
+              return a.number.localeCompare(b.number, undefined, {
+                numeric: true,
+              });
+            });
+
+          directoryAttrs.forEach((attr) => {
+            const catalogItem = {
+              label: `${attr.number} ${attr.content}`,
+              level: attr.level,
+              moduleIndex: moduleIndex,
+              children: [],
+            };
+
+            // 根据level确定目录层级
+            if (attr.level === 1) {
+              // 一级目录直接添加到根
+              catalogData.push(catalogItem);
+            } else {
+              // 查找父级目录
+              let parent = this.findParentDirectory(catalogData, attr.number);
+              if (parent) {
+                parent.children.push(catalogItem);
+              }
+            }
+          });
+        });
+        console.log(catalogData);
+        // 更新目录数据
+        this.catalogData = catalogData;
+
+        // 强制更新视图
+        this.$nextTick(() => {
+          this.$forceUpdate();
+        });
+      }
+    },
+
+    // 查找父级目录的辅助方法
+    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) {
+      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) {
+      // 处理目录点击事件
+      console.log("点击的目录项:", data);
+    },
+
     handleItemVal(value) {
       this.$forceUpdate();
       this.loadChildren(value);
@@ -1253,8 +1617,7 @@ export default {
       this.showViewForm = true;
     },
     onClose() {
-      /* this.$router.back(); */
-      window.close();
+      this.$router.back();
     },
 
     loadArticle(e) {
@@ -1673,7 +2036,7 @@ export default {
         updateDocument(_this.docAttr).then((res) => {
           if (res.status != 200) return; //更新文档
           _this.docAttr.id = res.data;
-          _this.$alert("模版更成功");
+          _this.$alert("模版更��成功");
           _this.searchArticle();
         });
       } else { */
@@ -2287,7 +2650,19 @@ export default {
   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;

+ 0 - 0
微信存储/WeChat Files/wxid_iwkr69dui1bt12/FileStorage/File/2024-11/index.vue