|
@@ -0,0 +1,2379 @@
|
|
|
|
+<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" v-if="userInfo != null">
|
|
|
|
+ <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="
|
|
|
|
+ $store.state.user.name == 'admin' &&
|
|
|
|
+ type !== 'module' &&
|
|
|
|
+ type !== 'document' &&
|
|
|
|
+ !articleId
|
|
|
|
+ "
|
|
|
|
+ @click="onSaveUpload"
|
|
|
|
+ >保存</el-button
|
|
|
|
+ >
|
|
|
|
+ <!-- <el-button
|
|
|
|
+ type="primary"
|
|
|
|
+ v-if="
|
|
|
|
+ $store.state.user.name == 'admin' &&
|
|
|
|
+ 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 v-if="type !== 'module' && type == 'document'"
|
|
|
|
+ > -->
|
|
|
|
+ <el-button
|
|
|
|
+ type="primary"
|
|
|
|
+ size="mini"
|
|
|
|
+
|
|
|
|
+ @click="onOpenView"
|
|
|
|
+ >预览导出
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button type="primary" size="mini" @click="onClose">
|
|
|
|
+ 关闭文档
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="editor-content">
|
|
|
|
+ <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">
|
|
|
|
+ <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)"
|
|
|
|
+ :title="it.title"
|
|
|
|
+ style="
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden; /* 隐藏超出部分 */
|
|
|
|
+ text-overflow: ellipsis; /* 显示省略号 */
|
|
|
|
+ max-width: 100%;
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ 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)"
|
|
|
|
+ :title="it.title"
|
|
|
|
+ style="
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden; /* 隐藏超出部分 */
|
|
|
|
+ text-overflow: ellipsis; /* 显示省略号 */
|
|
|
|
+ width: 100%;
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ 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"
|
|
|
|
+ >
|
|
|
|
+ <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"
|
|
|
|
+ @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
|
|
|
|
+ :title="fiveIts.name"
|
|
|
|
+ style="
|
|
|
|
+ cursor: move;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden; /* 隐藏超出部分 */
|
|
|
|
+ text-overflow: ellipsis; /* 显示省略号 */
|
|
|
|
+ width: 100%;
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ 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
|
|
|
|
+ :title="its.name"
|
|
|
|
+ style="
|
|
|
|
+ cursor: move;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden; /* 隐藏超出部分 */
|
|
|
|
+ text-overflow: ellipsis; /* 显示省略号 */
|
|
|
|
+ width: 100%;
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ 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
|
|
|
|
+ :title="it.name"
|
|
|
|
+ style="
|
|
|
|
+ cursor: move;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden; /* 隐藏超出部分 */
|
|
|
|
+ text-overflow: ellipsis; /* 显示省略号 */
|
|
|
|
+ width: 100%;
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ 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
|
|
|
|
+ :title="it.name"
|
|
|
|
+ style="
|
|
|
|
+ cursor: move;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden; /* 隐藏超出部分 */
|
|
|
|
+ text-overflow: ellipsis; /* 显示省略号 */
|
|
|
|
+ width: 100%;
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ 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
|
|
|
|
+ :title="it.name"
|
|
|
|
+ style="
|
|
|
|
+ cursor: move;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden; /* 隐藏超出部分 */
|
|
|
|
+ text-overflow: ellipsis; /* 显示省略号 */
|
|
|
|
+ width: 100%;
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ 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="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>
|
|
|
|
+ </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' : ''"
|
|
|
|
+ >
|
|
|
|
+ <span class="name">目录信息</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div
|
|
|
|
+ class="item"
|
|
|
|
+ @click="onAttributeIndex(1)"
|
|
|
|
+ :class="AttributeIndex == 1 ? 'active-item' : ''"
|
|
|
|
+ >
|
|
|
|
+ <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>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <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-position="left"
|
|
|
|
+ label-width="100"
|
|
|
|
+ >
|
|
|
|
+ <el-form-item label="文档名称:" prop="title">
|
|
|
|
+ <el-input
|
|
|
|
+ v-model="docForm.title"
|
|
|
|
+ style="width: 60%"
|
|
|
|
+ class="input-item"
|
|
|
|
+ placeholder="请填写文档名称"
|
|
|
|
+ :disabled="docAttr.id > 0"
|
|
|
|
+ />
|
|
|
|
+ </el-form-item>
|
|
|
|
+
|
|
|
|
+ <el-form-item label="文档分类:" prop="category_id">
|
|
|
|
+ <el-select
|
|
|
|
+ v-model="docForm.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>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="创建人:">
|
|
|
|
+ {{ 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,
|
|
|
|
+ } 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,
|
|
|
|
+ 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: {
|
|
|
|
+ title: "",
|
|
|
|
+ category_id: "",
|
|
|
|
+ },
|
|
|
|
+ docRules: {
|
|
|
|
+ title: [{ required: true, message: "请输文档名称", trigger: "blur" }],
|
|
|
|
+ category_id: [
|
|
|
|
+ { required: true, message: "请选择文档分类", trigger: "change" },
|
|
|
|
+ ],
|
|
|
|
+ },
|
|
|
|
+ articleCategoryList: [],
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ 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,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ async mounted() {
|
|
|
|
+ console.log(this.$store.state.user);
|
|
|
|
+ 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 = 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";
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ methods: {
|
|
|
|
+ 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 = {
|
|
|
|
+ title: "",
|
|
|
|
+ category_id: "",
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ /* 确定新增模块*/
|
|
|
|
+ submitDoc() {
|
|
|
|
+ this.$refs.docRef.validate((valid) => {
|
|
|
|
+ if (valid) {
|
|
|
|
+ this.docAttr.title = this.docForm.title;
|
|
|
|
+ this.docAttr.category_id = this.docForm.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) {
|
|
|
|
+ console.log(newComs);
|
|
|
|
+ newComs.forEach((newCom, comIndex) => {
|
|
|
|
+ const oldCom = oldComs[comIndex];
|
|
|
|
+ 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) => {
|
|
|
|
+ com.attrs.forEach((attr) => {
|
|
|
|
+ // 只更新非 variableNull 类型的属性
|
|
|
|
+ if (attr.name === attrId && attr.type !== "variableNull") {
|
|
|
|
+ attr.content = newContent;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 如果是文本区域,更新内容中的占位符
|
|
|
|
+ if (com.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 });
|
|
|
|
+
|
|
|
|
+ // 设置默认值
|
|
|
|
+ if (!data.attrs || !data.type) {
|
|
|
|
+ Object.assign(data, {
|
|
|
|
+ attrs: "[]",
|
|
|
|
+ content: "请填写内容",
|
|
|
|
+ lay_id: "textArea",
|
|
|
|
+ type: "TextArea",
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置文档标题
|
|
|
|
+ document.title = data.name
|
|
|
|
+ ? `${data.name}-${settings.title}`
|
|
|
|
+ : "新建模块-" + settings.title;
|
|
|
|
+
|
|
|
|
+ // 解析属性
|
|
|
|
+ data.attrs = JSON.parse(data.attrs);
|
|
|
|
+
|
|
|
|
+ // 获取公式并更新属性
|
|
|
|
+ const {
|
|
|
|
+ data: { dataList },
|
|
|
|
+ } = await searchFormula({ page: 1, pageSize: 999 });
|
|
|
|
+ console.log(data);
|
|
|
|
+ data.attrs = data.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.content.match(/{{([^}]+)}}/g) || []).map(
|
|
|
|
+ (match) => match.slice(2, -2).trim()
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // 过滤 attrs,只保留在 content 中出现的 ID
|
|
|
|
+ data.attrs = data.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.$router.back(); */
|
|
|
|
+ window.close();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ 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(updatedComList) {
|
|
|
|
+ this.coms = [...updatedComList];
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.$forceUpdate();
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ //初始化当前用户信息
|
|
|
|
+ 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;
|
|
|
|
+ const res = await getDocumentInfo({ id });
|
|
|
|
+
|
|
|
|
+ if (res.status !== 200) {
|
|
|
|
+ throw new Error("Invalid response status");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.docAttr = {
|
|
|
|
+ id: res.data.id,
|
|
|
|
+ category_id: Number(res.data.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 templateData =
|
|
|
|
+ typeof res.data.data === "string"
|
|
|
|
+ ? JSON.parse(res.data.data)
|
|
|
|
+ : res.data.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();
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("Error in onLoadArticle:", error);
|
|
|
|
+ } finally {
|
|
|
|
+ this.loading = false;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ /* 加载模版信息 */
|
|
|
|
+ async onTemplateInfo(id) {
|
|
|
|
+ try {
|
|
|
|
+ this.loading = true;
|
|
|
|
+ // 获取文档信息
|
|
|
|
+ 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 formulaData = await searchFormula({ page: 1, pageSize: 999 });
|
|
|
|
+
|
|
|
|
+ // 处理组件数据
|
|
|
|
+ const updatedComs = documentData.map((docEl) => {
|
|
|
|
+ if (!docEl || !docEl.id) {
|
|
|
|
+ console.warn("无效的文档项:", docEl);
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 确保 attrs 是数组
|
|
|
|
+ let attrs = Array.isArray(docEl.attrs) ? docEl.attrs : [];
|
|
|
|
+ if (typeof docEl.attrs === "string") {
|
|
|
|
+ try {
|
|
|
|
+ attrs = JSON.parse(docEl.attrs);
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.warn("解析 attrs 失败:", e);
|
|
|
|
+ attrs = [];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 确保 content 是字符串
|
|
|
|
+ let content = docEl.content || "";
|
|
|
|
+ if (typeof content !== "string") {
|
|
|
|
+ content = String(content);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 处理目录项
|
|
|
|
+ const contentItems = (content.match(/{{([^}]+)}}/g) || []).map(
|
|
|
|
+ (match) => match.slice(2, -2)
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // 确保所有目录项存在
|
|
|
|
+ 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) || 1,
|
|
|
|
+ moduleIndex: parseInt(moduleIndex) || 0,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 处理公式数据
|
|
|
|
+ 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;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 返回完整的组件数据结构
|
|
|
|
+ return {
|
|
|
|
+ id: docEl.id,
|
|
|
|
+ content: content,
|
|
|
|
+ attrs: attrs,
|
|
|
|
+ title: docEl.title || "",
|
|
|
|
+ type: docEl.type || "normal",
|
|
|
|
+ status: docEl.status || 1,
|
|
|
|
+ sort: docEl.sort || 0,
|
|
|
|
+ is_template: docEl.is_template || 0,
|
|
|
|
+ created_at: docEl.created_at,
|
|
|
|
+ updated_at: docEl.updated_at,
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 过滤并设置组件
|
|
|
|
+ this.coms = updatedComs.filter(Boolean);
|
|
|
|
+ console.log("处理后的组件数据:", this.coms);
|
|
|
|
+
|
|
|
|
+ if (this.articleId !== undefined) {
|
|
|
|
+ document.title = `${this.docAttr.title}-${settings.title}`;
|
|
|
|
+ }
|
|
|
|
+ this.uptadeSearch();
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("加载文档信息时出错:", error);
|
|
|
|
+ this.$message.error("加载文档信息时出错,请稍后重试");
|
|
|
|
+ } finally {
|
|
|
|
+ this.loading = false;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ onRemove(index) {
|
|
|
|
+ this.coms.splice(index, 1);
|
|
|
|
+ },
|
|
|
|
+ /* 目录信息 */
|
|
|
|
+ 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.title = _this.docAttr.title;
|
|
|
|
+ this.docForm.category_id = _this.docAttr.category_id;
|
|
|
|
+ },
|
|
|
|
+ /* 保存 */
|
|
|
|
+ onSaveAs(e) {
|
|
|
|
+ let _this = this;
|
|
|
|
+ if (_this.coms.length <= 0) {
|
|
|
|
+ _this.$alert("请填写内容");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ _this.docAttr.id = "";
|
|
|
|
+ _this.docVisible = true;
|
|
|
|
+ this.docForm.title = _this.docAttr.title;
|
|
|
|
+ this.docForm.category_id = _this.docAttr.category_id;
|
|
|
|
+ },
|
|
|
|
+ //保存文档
|
|
|
|
+ onSave(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 = 0;
|
|
|
|
+ _this.docAttr.user_name = _this.$store.state.user.name;
|
|
|
|
+ _this.docAttr.user_id = _this.$store.state.user.id;
|
|
|
|
+ if (_this.docAttr.id > 0) {
|
|
|
|
+ updateDocument(_this.docAttr).then((res) => {
|
|
|
|
+ if (res.status != 200) return; //更新文档
|
|
|
|
+ _this.docAttr.id = res.data;
|
|
|
|
+ _this.$alert("文档更新成功");
|
|
|
|
+ _this.docVisible = false;
|
|
|
|
+ _this.docForm = {
|
|
|
|
+ title: "",
|
|
|
|
+ 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 = {
|
|
|
|
+ title: "",
|
|
|
|
+ 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;
|
|
|
|
+ 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;
|
|
|
|
+ /* 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":
|
|
|
|
+ this.insertProductAttr();
|
|
|
|
+ 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() {
|
|
|
|
+ if (this.docAttr.linkProduct.length <= 0) {
|
|
|
|
+ this.$alert("请选择文档关联商品信息");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ this.showProductAttr = true;
|
|
|
|
+ },
|
|
|
|
+ //插入目录
|
|
|
|
+ insertDirectory(e) {
|
|
|
|
+ let _this = this;
|
|
|
|
+ if (_this.comIndex < 0) {
|
|
|
|
+ _this.$alert("请选择插入图层");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let com = _this.coms[_this.comIndex];
|
|
|
|
+ let uniqueId = `Directory_${_this.comIndex}_${com.attrs.length + 1}`;
|
|
|
|
+
|
|
|
|
+ // 获取当前层级
|
|
|
|
+ let currentLevel = e.content.level || 1;
|
|
|
|
+
|
|
|
|
+ // 生成带有模块索引和层级的内容
|
|
|
|
+ let { number, content } = this.generateNumberedContent(
|
|
|
|
+ _this.comIndex,
|
|
|
|
+ currentLevel
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ let data = {
|
|
|
|
+ type: "Directory",
|
|
|
|
+ id: uniqueId,
|
|
|
|
+ name: "目录信息",
|
|
|
|
+ intro: "目录信息",
|
|
|
|
+ number: number,
|
|
|
|
+ content: content,
|
|
|
|
+ level: currentLevel,
|
|
|
|
+ moduleIndex: _this.comIndex,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // 使用 $set 来确保响应式更新
|
|
|
|
+ this.$set(com.attrs, com.attrs.length, data);
|
|
|
|
+
|
|
|
|
+ // 强制更新视图
|
|
|
|
+ this.$forceUpdate();
|
|
|
|
+
|
|
|
|
+ // 使用 nextTick 确保 DOM 更新后再检查
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ if (!com.attrs[com.attrs.length - 1].content) {
|
|
|
|
+ this.$set(com.attrs[com.attrs.length - 1], "content", content);
|
|
|
|
+ this.$forceUpdate();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 使用新的唯一 ID 在插入命令中
|
|
|
|
+ _this.insertCmd = {
|
|
|
|
+ content: `{{${uniqueId}}}`,
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ generateNumberedContent(moduleIndex, level) {
|
|
|
|
+ let number = this.generateLevelPrefix(moduleIndex, level);
|
|
|
|
+ let content = this.coms[moduleIndex].type === "TextArea" ? "" : "";
|
|
|
|
+
|
|
|
|
+ return { number, content };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ generateLevelPrefix(moduleIndex, level) {
|
|
|
|
+ let prefix = [];
|
|
|
|
+ let currentModule = this.coms[moduleIndex];
|
|
|
|
+
|
|
|
|
+ // 获取当前模块中已存在的目录项
|
|
|
|
+ let existingDirectories = currentModule.attrs.filter(
|
|
|
|
+ (attr) => attr.type === "Directory"
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // 计算当前层级的序号
|
|
|
|
+ let currentLevelCount =
|
|
|
|
+ existingDirectories.filter((dir) => dir.level === level).length + 1;
|
|
|
|
+
|
|
|
|
+ // 构建多级序号
|
|
|
|
+ for (let i = 1; i <= level; i++) {
|
|
|
|
+ if (i === 1) {
|
|
|
|
+ prefix.push(moduleIndex + 1);
|
|
|
|
+ } else if (i === level) {
|
|
|
|
+ prefix.push(currentLevelCount);
|
|
|
|
+ } else {
|
|
|
|
+ // 对于中间层级,找到最近的上级目录项
|
|
|
|
+ let parentLevel = existingDirectories
|
|
|
|
+ .filter((dir) => dir.level === i - 1)
|
|
|
|
+ .pop();
|
|
|
|
+ prefix.push(parentLevel ? parentLevel.number.split(".")[i - 1] : 1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return prefix.join(".");
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ onInsertProductAttr(e) {
|
|
|
|
+ let _this = this;
|
|
|
|
+ this.showProductAttr = false;
|
|
|
|
+ if (_this.comIndex < 0) {
|
|
|
|
+ _this.$alert("请选择插入图层");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let com = _this.coms[_this.comIndex];
|
|
|
|
+
|
|
|
|
+ let data = {
|
|
|
|
+ type: "ProductAttr",
|
|
|
|
+ id: "ProductAttr" + (com.attrs.length + 1),
|
|
|
|
+ dataId: e.id,
|
|
|
|
+ name: "商品属性",
|
|
|
|
+ intor: "商品属性",
|
|
|
|
+ content: "",
|
|
|
|
+ attrs: e,
|
|
|
|
+ };
|
|
|
|
+ com.attrs.push(data);
|
|
|
|
+ _this.insertCmd = {
|
|
|
|
+ content: "{{" + data.id + "}}",
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ //插入新记录
|
|
|
|
+ insertNew(e) {
|
|
|
|
+ let _this = this;
|
|
|
|
+ _this.coms.push(e);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ //插入分页
|
|
|
|
+ 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;
|
|
|
|
+ /* let res = await getAllCategory({list:1 });
|
|
|
|
+ if(res.status!=200)return;
|
|
|
|
+ let dataList=res.data;
|
|
|
|
+
|
|
|
|
+ for(var i=0;i<dataList.length;i++){
|
|
|
|
+ for (var j=0;j<dataList[i].children.length;j++){
|
|
|
|
+ let dataId=dataList[i].children[j].id;
|
|
|
|
+
|
|
|
|
+ for(var k=0;k<dataList[i].children[j].dataList.length;k++){
|
|
|
|
+ dataList[i].children[j].dataList[k].attrs=JSON.parse(dataList[i].children[j].dataList[k].attrs)
|
|
|
|
+ }
|
|
|
|
+ // dataList[i].children[j].dataList=await _this.getTemplateList(dataId)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // console.log("dataList",dataList)
|
|
|
|
+ _this.categoryList=dataList; */
|
|
|
|
+ let res = await searchTemplateCategory({
|
|
|
|
+ page: 1,
|
|
|
|
+ pageSize: 99,
|
|
|
|
+ parent_id: 0,
|
|
|
|
+ status: 5,
|
|
|
|
+ });
|
|
|
|
+ if (res.status != 200) return;
|
|
|
|
+ _this.categoryList = res.data.dataList;
|
|
|
|
+ for (var i = 0; i < _this.categoryList.length; i++) {
|
|
|
|
+ _this.categoryList[i].dataList = await _this.getTemplateList(
|
|
|
|
+ _this.categoryList[i].id
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ //获取模版列表
|
|
|
|
+
|
|
|
|
+ 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) => {
|
|
|
|
+ // 添加空值检查
|
|
|
|
+ if (!item.attrs) {
|
|
|
|
+ item.attrs = "[]";
|
|
|
|
+ }
|
|
|
|
+ if (!item.content) {
|
|
|
|
+ item.content = "";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 解析 attrs,添加错误处理
|
|
|
|
+ item.attrs =
|
|
|
|
+ typeof item.attrs === "string"
|
|
|
|
+ ? JSON.parse(item.attrs)
|
|
|
|
+ : item.attrs;
|
|
|
|
+
|
|
|
|
+ // 从 content 中提取所有 {{}} 包裹的 ID,添加空值检查
|
|
|
|
+ const contentIds = (
|
|
|
|
+ (item.content || "").match(/{{([^}]+)}}/g) || []
|
|
|
|
+ ).map((match) => match.slice(2, -2).trim());
|
|
|
|
+
|
|
|
|
+ // 确保 attrs 是数组
|
|
|
|
+ item.attrs = Array.isArray(item.attrs) ? item.attrs : [];
|
|
|
|
+
|
|
|
|
+ // 过滤 attrs,只保留在 content 中出现的 ID
|
|
|
|
+ item.attrs = item.attrs.filter(
|
|
|
|
+ (attr) => attr && attr.id && contentIds.includes(attr.id)
|
|
|
|
+ );
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("Error processing template item:", error);
|
|
|
|
+ item.attrs = [];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return item;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return dataList;
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ //获取文档列表
|
|
|
|
+ searchArticle() {
|
|
|
|
+ let _this = this;
|
|
|
|
+ pageDocument({
|
|
|
|
+ page: 1,
|
|
|
|
+ pageSize: 99,
|
|
|
|
+ }).then((res) => {
|
|
|
|
+ if (res.status != 200) return;
|
|
|
|
+ _this.articleList = res.data.dataList.filter(
|
|
|
|
+ (el) => el.is_template == 0
|
|
|
|
+ );
|
|
|
|
+ _this.templateList = res.data.dataList.filter(
|
|
|
|
+ (el) => el.is_template == 1
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ </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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*.el-collapse-item {
|
|
|
|
+ display: inline-block;
|
|
|
|
+ vertical-align: top;
|
|
|
|
+ } */
|
|
|
|
+ </style>
|
|
|
|
+
|