Przeglądaj źródła

修改预览导出,调整 文档模版渲染方式,修改文档显示名称

yangg 10 miesięcy temu
rodzic
commit
986a88d657

+ 1 - 1
.env.development

@@ -2,5 +2,5 @@
 ENV = 'development'
 port = 8080
 # base api
-VUE_APP_BASE_API = 'http://192.168.1.178:8000'
+VUE_APP_BASE_API = 'http://120.46.190.49:8000'
 #192.168.1.178

Plik diff jest za duży
+ 0 - 0
dist/index.html


+ 0 - 0
dist/static/css/chunk-6caebfaa.7131743c.css → dist/static/css/chunk-314db29e.7131743c.css


+ 0 - 0
dist/static/css/chunk-d78b9348.7131743c.css → dist/static/css/chunk-4d02cb1c.7131743c.css


Plik diff jest za duży
+ 0 - 0
dist/static/css/chunk-61b2aede.4cd10360.css


Plik diff jest za duży
+ 0 - 0
dist/static/js/app.679286b7.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-07c440fa.648f1ffe.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-07c440fa.b08e61f1.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-314db29e.7c7b35b2.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-4d02cb1c.eca1763f.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-61b2aede.4233fbb6.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-6caebfaa.5a7f26e7.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-d78b9348.56b3a6bb.js


Plik diff jest za duży
+ 0 - 0
dist/static/js/chunk-fc73c52a.decd9590.js


+ 3 - 3
src/views/dashboard/admin/components/TransactionTable.vue

@@ -7,7 +7,7 @@
     </el-table-column>
     <el-table-column label="时间" min-width="150">
       <template slot-scope="scope">
-        {{scope.row.createTime}}
+        {{scope.row.create_time}}
       </template>
     </el-table-column>
 
@@ -24,7 +24,7 @@
 </template>
 
 <script>
-  import{searchDocument,deleteDocument} from'@/api/document';
+  import{searchDocument,deleteDocument,pageDocument} from'@/api/document';
 export default {
   filters: {
     statusFilter(status) {
@@ -48,7 +48,7 @@ export default {
   },
   methods: {
     fetchData() {
-      searchDocument({
+      pageDocument({
            page:1,
            pageSize:8,
            title:'',

+ 1 - 0
src/views/document/com/components/TextArea/index.vue

@@ -85,6 +85,7 @@ export default {
         if (val == null) return;
         if (val.content == undefined || val.content == null) return;
         try {
+          console.log("com",val);
           let res = await _this.replaceData(val.content);
           _this.content = res;
           _this.$nextTick(() => {

+ 204 - 37
src/views/document/com/components/TextView/index.vue

@@ -1,11 +1,11 @@
 <template>
   <div class="template-textarea">
-    <div class="rich-editor" v-html="replaceData(com.content)" @input="handleInput"></div>
+    <div class="rich-editor" v-html="processedContent"></div>
   </div>
 </template>
 
 <script>
-// import CKEditor from "ckeditor4-vue";
+import CKEditor from "ckeditor4-vue"; //@input="handleInput"
 import { findData } from "@/api/sourceData";
 export default {
   name: "app",
@@ -32,7 +32,9 @@ export default {
   watch: {
     com: {
       handler(val) {
-        console.log("val", val);
+        if (val && val.content) {
+          this.updateProcessedContent();
+        }
         /*  let _this = this;
         if (val == null) return;
         if (val.content == undefined || val.content == null) return;
@@ -48,44 +50,203 @@ export default {
   data() {
     return {
       content: "",
+      processedContent: "",
     };
   },
   methods: {
-    replaceData(data) {
-      for (var i = 0; i < this.com.attrs.length; i++) {
-        let attrId = this.com.attrs[i].id;
-        if (this.com.attrs[i].type == "variable") {
-          //全局变量
-          data = data.replace(
-            "{{" + this.com.attrs[i].id + "}}",
-            `<input type="text" class="text-input-box" :value="${this.com.attrs[i].content}" @input="updateContent('${this.com.attrs[i].id}', $event)" id="${this.com.attrs[i].id}">`
-          );
-        } else if (this.com.attrs[i].type == "Directory") {
-          //处理目录
-          data = data.replace(
-            "<p>{{" + attrId + "}}</p>",
-            "<h1>" + this.com.attrs[i].content + "</h1>"
-          );
-          data = data.replace(
-            "<div>{{" + attrId + "}}</div>",
-            "<h1>" + this.com.attrs[i].content + "</h1>"
-          );
-          data = data.replace(
-            "<span>{{" + attrId + "}}</span>",
-            "<h1>" + this.com.attrs[i].content + "</h1>"
-          );
+    async updateProcessedContent() {
+      this.processedContent = await this.replaceData(this.com.content);
+    },
+    async replaceData(data) {
+      let _this = this;
+      for (var i = 0; i < _this.com.attrs.length; i++) {
+        let attrId = _this.com.attrs[i].id;
+        if (_this.com.attrs[i].type == "variable") {
+          let item = _this.com.attrs[i];
+          if (item.data.value_type == 2) {
+            //多选
+            let dataItem = item.data.value_item.split(",");
+            let selectHtml =
+              '<select id="' +
+              attrId +
+              '"  data-index="' +
+              i +
+              '" class="text-input-box">';
+            for (var l = 0; l < dataItem.length; l++) {
+              if (item.content == dataItem[l]) {
+                selectHtml +=
+                  '<option value="' +
+                  dataItem[l] +
+                  '" selected>' +
+                  dataItem[l] +
+                  "</option>";
+              } else {
+                selectHtml +=
+                  '<option value="' +
+                  dataItem[l] +
+                  '">' +
+                  dataItem[l] +
+                  "</option>";
+              }
+            }
+            selectHtml += "</select>";
+            data = data.replace("{{" + item.id + "}}", selectHtml);
+          } else {
+            //文本
+            data = data.replace(
+              "{{" + attrId + "}}",
+              /* `<input type="text" class="text-input-box"  data-index="${i}" value="${_this.com.attrs[i].content}" @input="updateContent('${_this.com.attrs[i].id}', $event)" id="${attrId}">`, */
+              '<input type="text" ref="input_' +
+                attrId +
+                '" name="' +
+                _this.com.attrs[i].name +
+                '" id="' +
+                attrId +
+                '"  data-index="' +
+                i +
+                '" class="text-input-box" value="' +
+                _this.com.attrs[i].content +
+                '">'
+            );
+          }
+        } else if (_this.com.attrs[i].type == "ProductAttr") {
+          //处理产品属性值
+          let item = _this.com.attrs[i];
+          let prodAttrId = item.id + "_" + i;
+          if (item.content == "") {
+            item.content = item.attrs.value;
+          }
+          if (item.attrs.type == 1) {
+            //输入框
+            data = data.replace(
+              "{{" + item.id + "}}",
+              '<input type="text" id="' +
+                prodAttrId +
+                '"  data-index="' +
+                i +
+                '" class="text-input-box" value="' +
+                item.content +
+                '">'
+            );
+          } else {
+            //选择框
+            let dataItem = item.attrs.valueItems.split(",");
+            let selectHtml =
+              '<select id="' +
+              prodAttrId +
+              '"  data-index="' +
+              i +
+              '" class="text-input-box">';
+            for (var l = 0; l < dataItem.length; l++) {
+              if (item.content == dataItem[l]) {
+                selectHtml +=
+                  '<option value="' +
+                  dataItem[l] +
+                  '" selected>' +
+                  dataItem[l] +
+                  "</option>";
+              } else {
+                selectHtml +=
+                  '<option value="' +
+                  dataItem[l] +
+                  '">' +
+                  dataItem[l] +
+                  "</option>";
+              }
+            }
+            selectHtml += "</select>";
+            data = data.replace("{{" + item.id + "}}", selectHtml);
+          }
+        } else if (_this.com.attrs[i].type == "formual") {
+          //// console.log('attrs',_this.com.attrs[i]);
+          //处理计算公式 不处理
+          let formual = await _this.analysisFormual(_this.com.attrs[i]);
+
+          formual = await _this.getRemote(formual);
+          _this.com.attrs[i].content = eval(formual);
+          data = data.replace("{{" + attrId + "}}", eval(formual));
+        } else if (_this.com.attrs[i].type == "sourceData") {
+          let result = await _this.getRemote1(_this.com.attrs[i].formula);
+          data = data.replace("{{" + attrId + "}}", result);
+        } else if (_this.com.attrs[i].type == "Directory") {
+          const directoryContent = _this.com.attrs[i].content;
+          const attrId = _this.com.attrs[i].id;
+
+          // Create a more flexible regex pattern
+          const directoryRegex = new RegExp(`{{\\s*${attrId}\\s*}}`, "g");
+
+          // Replace the content, preserving surrounding HTML tags
+          data = data.replace(directoryRegex, (match, offset, string) => {
+            // Check if the match is inside a tag
+            const precedingText = string.substring(0, offset);
+            const followingText = string.substring(offset + match.length);
+            const precedingTag = precedingText.match(/<([^>]+)>$/);
+            const followingCloseTag = followingText.match(/^<\/([^>]+)>/);
+
+            if (
+              precedingTag &&
+              followingCloseTag &&
+              precedingTag[1] === followingCloseTag[1]
+            ) {
+              // If it's inside matching tags, replace the entire element
+              return `<h1>${directoryContent}</h1>`;
+            } else {
+              // Otherwise, just replace the placeholder
+              return directoryContent;
+            }
+          });
         } else {
-          data = data.replace(
-            "{{" + this.com.attrs[i].id + "}}",
-            this.com.attrs[i].content
-          );
+          //处理常量及其它
+          data = data.replace("{{" + attrId + "}}", _this.com.attrs[i].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)");
+        }
+      }
+      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;
+    },
     updateContent(id, event) {
-      console.log(id,event);
-      const attr = this.com.attrs.find(attr => attr.id === id);
+      const attr = this.com.attrs.find((attr) => attr.id === id);
       if (attr) {
         attr.content = event.target.value;
       }
@@ -230,16 +391,22 @@ export default {
     //获取本地文档模块数据
     async getModuleData(code, attrName) {
       let _this = this;
-      let item = _this.coms.filter((o) => o.code == code);
+      // 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) {
-          let content = parseFloat(attr[0].content);
-          if (!isNaN(content)) {
-            return content;
-          }
+          // console.log(`返回的值:`, attr[0].content);
+          return parseFloat(attr[0].content);
         }
       }
+      // console.log("未找到匹配的模块或属性,返回 0");
       return 0;
     },
   },

+ 229 - 160
src/views/document/com/editor.vue

@@ -1,185 +1,254 @@
 <template>
   <div class="editor">
-      <draggable v-model="comList"  @add="onAdd"   @update="onDragEnd"  group="itxst" animation="300" style="width:100%;">
-          <transition-group>
-            <template v-for="(it,index) in comList">
-              <div class="layers" draggable :key="index" :class="comIndex==index?'active-layer':''">
-                  <div class="main" @click="onSetActive(index)">
-                      <component
-                      :is="it.type"
-                      :com="it"
-                      :coms="comList"
-                      :currentIndex="index"
-                      :isAdmin="isAdmin"
-                      :insertCmd="insertCmd"
-                      @onUpdate="onUpdate"
-                      @onUpdateAttr="onUpdateAttr"
-                      @onUpdateProdAttr="onUpdateProdAttr"
-                      :isEdit="it.isEdit"
-                      />
-                  </div>
-                  <div class="label">
-                    {{it.name}}
-                    <div class="del">
-                        <svg-icon @click="onEdit(index,1)" v-if="it.isEdit!==1" icon-class="edit" style="color:#FFF;margin-right:10px;"/>
-                        <svg-icon @click="onEdit(index,2)" v-else  icon-class="view" style="color:#FFF;margin-right:10px;"/>
-                        <svg-icon @click="onRemove(index)" icon-class="delete" style="color:#FFF;margin-left:10px;"/>
-                    </div>
-                  </div>
+    <draggable
+      v-model="comList"
+      @add="onAdd"
+      @update="onDragEnd"
+      group="itxst"
+      animation="300"
+      style="width: 100%"
+      handle=".drag-handle"
+      :scroll="true"
+      :scrollSensitivity="100"
+      :scrollSpeed="20"
+    >
+      <transition-group>
+        <template v-for="(it, index) in comList">
+          <div
+            class="layers"
+            :key="index"
+            :class="comIndex == index ? 'active-layer' : ''"
+          >
+            <div class="drag-handle" draggable>
+              <svg-icon icon-class="drag" />
+            </div>
+            <div class="main" @click="onSetActive(index)">
+              <component
+                :is="it.type"
+                :com="it"
+                :coms="comList"
+                :currentIndex="index"
+                :isAdmin="isAdmin"
+                :insertCmd="insertCmd"
+                @onUpdate="onUpdate"
+                @onUpdateAttr="onUpdateAttr"
+                @onUpdateProdAttr="onUpdateProdAttr"
+                :isEdit="it.isEdit"
+              />
+            </div>
+            <div class="label">
+              {{ it.name }}
+              <div class="del">
+                <svg-icon
+                  @click="onEdit(index, 1)"
+                  v-if="it.isEdit !== 1"
+                  icon-class="edit"
+                  style="color: #fff; margin-right: 10px"
+                />
+                <svg-icon
+                  @click="onEdit(index, 2)"
+                  v-else
+                  icon-class="view"
+                  style="color: #fff; margin-right: 10px"
+                />
+                <svg-icon
+                  @click="onRemove(index)"
+                  icon-class="delete"
+                  style="color: #fff; margin-left: 10px"
+                />
               </div>
-            </template>
-            <template v-if="comList.length<=0">
-                <div class="editor-empty" :key="-1"> <el-empty description="请拖放组件至当前页面" /></div>
-            </template>
-          </transition-group>
-
-      </draggable>
+            </div>
+          </div>
+        </template>
+        <template v-if="comList.length <= 0">
+          <div class="editor-empty" :key="-1">
+            <el-empty description="请拖放组件至当前页面" />
+          </div>
+        </template>
+      </transition-group>
+    </draggable>
   </div>
-
 </template>
 
 <script>
-  import draggable from 'vuedraggable'
-  import Table from "./components/Table"
-  import TextArea from "./components/TextArea"
-  import Empty from "./components/Empty"
-  export default{
-    name:"editor",
-    emits:['onSetActiveIndex','onDelete','onInsert','onLoadArticle','onRebuild','onSetComs'],
-    components:{
-      Table,TextArea,draggable,Empty
+import draggable from "vuedraggable";
+import Table from "./components/Table";
+import TextArea from "./components/TextArea";
+import Empty from "./components/Empty";
+export default {
+  name: "editor",
+  emits: [
+    "onSetActiveIndex",
+    "onDelete",
+    "onInsert",
+    "onLoadArticle",
+    "onRebuild",
+    "onSetComs",
+  ],
+  components: {
+    Table,
+    TextArea,
+    draggable,
+    Empty,
+  },
+  props: {
+    coms: {
+      type: Array,
+      default: null,
     },
-    props:{
-      coms:{
-        type:Array,
-        default:null
-      },
-      comIndex:{
-        type:Number,
-        default:0,
-      },
-      templateCate:{
-        type:Array,
-        default:()=>{
-          return [];
-        }
-      },
-      insertCmd:{
-        type:Object,
-        default:null,
-      },
-      isAdmin:{
-        type:Number,
-        default:2
+    comIndex: {
+      type: Number,
+      default: 0,
+    },
+    templateCate: {
+      type: Array,
+      default: () => {
+        return [];
       },
     },
-    watch:{
-        'coms':{
-          handler(val){
-             if(val==null)return;
-             this.comList=JSON.parse(JSON.stringify(val));
-          },
-          immediate: true,//立即执行
-          deep: true
-        },
-        'comIndex':{
-          handler(val){
-            if(val<=0)return;
-            this.comList=this.comList.map((it)=>{
-              it.isEdit=2;
-              return it;
-            })
-          },
-          immediate: true,//立即执行
-          deep: true
-        }
-
+    insertCmd: {
+      type: Object,
+      default: null,
     },
-    data(){
-      return{
-        showEditor:false,
-        operation:'',
-        id:0,
-        comList:[],
-      }
+    isAdmin: {
+      type: Number,
+      default: 2,
     },
-
-
-    methods:{
-      //更新产品属性
-      onUpdateProdAttr(comIndex,attrIndex,data){
-
-
-        this.comList[comIndex].attrs[attrIndex].content=data;
-
-        let attrName=this.comList[comIndex].attrs[attrIndex].attrs.name;
-        let attrType=this.comList[comIndex].attrs[attrIndex].attrs.type;
-
-        for(var i=0;i<this.comList.length;i++){
-          for(var j=0;j<this.comList[i].attrs.length;j++){
-            if(this.comList[i].attrs[j].type=='ProductAttr'){
-                if(this.comList[i].attrs[j].attrs.name==attrName && this.comList[i].attrs[j].attrs.type==attrType){
-                  this.comList[i].attrs[j].content=data;
-                }
+  },
+  watch: {
+    coms: {
+      handler(val) {
+        if (val == null) return;
+        this.comList = JSON.parse(JSON.stringify(val));
+      },
+      immediate: true, //立即执行
+      deep: true,
+    },
+    comIndex: {
+      handler(val) {
+        if (val <= 0) return;
+        this.comList = this.comList.map((it) => {
+          it.isEdit = 2;
+          return it;
+        });
+      },
+      immediate: true, //立即执行
+      deep: true,
+    },
+  },
+  data() {
+    return {
+      showEditor: false,
+      operation: "",
+      id: 0,
+      comList: [],
+    };
+  },
+
+  methods: {
+    //更新产品属性
+    onUpdateProdAttr(comIndex, attrIndex, data) {
+      this.comList[comIndex].attrs[attrIndex].content = data;
+
+      let attrName = this.comList[comIndex].attrs[attrIndex].attrs.name;
+      let attrType = this.comList[comIndex].attrs[attrIndex].attrs.type;
+
+      for (var i = 0; i < this.comList.length; i++) {
+        for (var j = 0; j < this.comList[i].attrs.length; j++) {
+          if (this.comList[i].attrs[j].type == "ProductAttr") {
+            if (
+              this.comList[i].attrs[j].attrs.name == attrName &&
+              this.comList[i].attrs[j].attrs.type == attrType
+            ) {
+              this.comList[i].attrs[j].content = data;
             }
           }
         }
-        this.$emit("onRebuild",this.comList);
-      },
-
-      onUpdateAttr(comIndex,attrIndex,data){
+      }
+      this.$emit("onRebuild", this.comList);
+    },
 
-        this.comList[comIndex].attrs[attrIndex].content=data;
+    onUpdateAttr(comIndex, attrIndex, data) {
+      this.comList[comIndex].attrs[attrIndex].content = data;
 
-        let dataType=this.comList[comIndex].attrs[attrIndex].type;
-        let dataId=this.comList[comIndex].attrs[attrIndex].data;
+      let dataType = this.comList[comIndex].attrs[attrIndex].type;
+      let dataId = this.comList[comIndex].attrs[attrIndex].data;
 
-        for(var i=0;i<this.comList.length;i++){
-          for(var j=0;j<this.comList[i].attrs.length;j++){
-            if(this.comList[i].attrs[j].type==dataType && this.comList[i].attrs[j].id==dataId){
-              this.comList[i].attrs[j].content=data;
-            }
+      for (var i = 0; i < this.comList.length; i++) {
+        for (var j = 0; j < this.comList[i].attrs.length; j++) {
+          if (
+            this.comList[i].attrs[j].type == dataType &&
+            this.comList[i].attrs[j].id == dataId
+          ) {
+            this.comList[i].attrs[j].content = data;
           }
         }
-        this.$emit("onRebuild",this.comList);
-      },
-      onRemove(index){
-        this.$emit("onDelete",index);
-      },
-      onEdit(e,state){
-        this.comList=this.comList.map((it)=>{
-          it.isEdit=2;
-          return it;
-        })
-        if(state==1){
-          this.comList[e].isEdit=1;
-          this.onSetActive(e);
-        }
-
-        this.$emit("onRebuild",this.comList);
-      },
-      onAdd(e){
-        e.preventDefault();
-        e.stopPropagation();
-        this.$emit("onRebuild",this.comList);
-      },
-      onDragEnd(e) {
-        e.preventDefault();
-        e.stopPropagation();
-        this.$emit("onRebuild",this.comList);
-      },
-      onUpdate(index,content){
-         let _this=this;
-         this.coms[index].content=content;
-      },
-      //激活当前层
-      onSetActive(e){
-        this.$emit("onSetActiveIndex",e);
+      }
+      this.$emit("onRebuild", this.comList);
+    },
+    onRemove(index) {
+      this.$emit("onDelete", index);
+    },
+    onEdit(e, state) {
+      this.comList = this.comList.map((it) => {
+        it.isEdit = 2;
+        return it;
+      });
+      if (state == 1) {
+        this.comList[e].isEdit = 1;
+        this.onSetActive(e);
       }
 
-    }
-  }
+      this.$emit("onRebuild", this.comList);
+    },
+    onAdd(e) {
+      e.preventDefault();
+      e.stopPropagation();
+      this.$emit("onRebuild", this.comList);
+    },
+    onDragEnd(e) {
+      e.preventDefault();
+      e.stopPropagation();
+      this.$emit("onRebuild", this.comList);
+    },
+    onUpdate(index, content) {
+      let _this = this;
+      this.coms[index].content = content;
+    },
+    //激活当前层
+    onSetActive(e) {
+      this.$emit("onSetActiveIndex", e);
+    },
+  },
+};
 </script>
 <style lang="scss">
-@import './editor.scss';
+@import "./editor.scss";
+.layers {
+  margin-left: 26px;
+  .drag-handle {
+    position: absolute;
+    top: 0;
+    left: -27px;
+    cursor: move;
+    padding: 0 5px;
+    display: flex;
+    align-items: center;
+    background-color: #f0f0f0;
+
+    &:hover {
+      background-color: #e0e0e0;
+    }
+  }
+
+  .content-wrapper {
+    flex-grow: 1;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .main {
+    flex-grow: 1;
+  }
+}
 </style>

+ 50 - 39
src/views/document/com/view.vue

@@ -1,10 +1,11 @@
 <template>
   <div class="com-viewer">
     <div class="content" ref="content">
-      <template v-for="(item, index) in coms">
+      <template v-for="(item, index) in coms"
+        ><!-- getComponentType() -->
         <component
           :key="index"
-          :is="getComponentType(item.type)"
+          :is="item.type"
           :com="item"
           :coms="comList"
           :currentIndex="index"
@@ -14,7 +15,13 @@
       </template>
     </div>
     <div class="export">
-      <el-button @click="onExport" type="primary">导出</el-button>
+      <el-button
+        @click="onExport"
+        type="primary"
+        :loading="exporting"
+        :disabled="exporting"
+        >导出</el-button
+      >
     </div>
   </div>
 </template>
@@ -64,6 +71,7 @@ export default {
     return {
       comList: [],
       content: "",
+      exporting: false, // 新增:用于跟踪导出状态
     };
   },
   methods: {
@@ -77,14 +85,11 @@ export default {
 
               formual = await this.getRemote(formual);
               el.content = eval(formual);
-              
-              /* data = data.replace("{{" + attrId + "}}", eval(formual)); */
-            } catch (error) {
-            }
+            } catch (error) {}
           }
         }
       }
-      this.$emit('update:coms', [...this.comList])
+      //this.$emit('update:coms', [...this.comList])
       return data;
     },
     //分析公式
@@ -113,7 +118,6 @@ export default {
           formual = formual.replace(itemName, "(0)");
         }
       }
-      // console.log("分析后的公式:", formual);
       return formual;
     },
     async getFormualData(formualItem) {
@@ -253,43 +257,50 @@ export default {
     onUpdateData(index, data) {
       this.comList[index].content = data;
       this.rebuildContent();
-      this.$emit('update:coms', [...this.comList])
+      //this.$emit('update:coms', [...this.comList])
     },
     rebuildContent() {
       this.content = this.comList.map((item) => item.content).join("");
-      console.log(this.content);
     },
-    onExport() {
-      this.$emit('update:coms', [...this.comList])
-      // Clone the content element to avoid modifying the original DOM
-      let contentClone = this.$refs.content.cloneNode(true);
+    async onExport() {
+      if (this.exporting) return; // 如果正在导出,直接返回
+      this.exporting = true; // 设置导出状态为 true
 
-      // Replace all input elements with their values
-      contentClone.querySelectorAll('input[type="text"]').forEach((input) => {
-        const span = document.createElement("span");
-        span.textContent = input.value;
-        input.parentNode.replaceChild(span, input);
-      });
-      console.log(contentClone);
-      let contentData = `<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body><p class="header1"></p> ${contentClone.innerHTML} </body></html>`;
-      contentData = contentData
-        .replaceAll("<table ", `<table style="border-collapse: collapse;" `)
-        .replaceAll("<td>", `<td style="border: 1px solid black;">`);
+      try {
+        let contentClone = this.$refs.content.cloneNode(true);
 
-      exportDocument({ content: contentData, title: this.docAttr.title }).then(
-        (res) => {
-          if (res.status != 200) {
-            this.$alert(res.errMsg);
-            return;
-          }
-          let a = document.createElement("a");
-          a.href = res.data.file_path; // Use the file_path from the response
-          a.download = res.data.file_name; // Set the download attribute to the file_name
-          document.body.appendChild(a);
-          a.click();
-          document.body.removeChild(a);
+        contentClone.querySelectorAll('input[type="text"]').forEach((input) => {
+          const span = document.createElement("span");
+          span.textContent = input.value;
+          input.parentNode.replaceChild(span, input);
+        });
+
+        let contentData = `<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body><p class="header1"></p> ${contentClone.innerHTML} </body></html>`;
+        contentData = contentData
+          .replaceAll("<table ", `<table style="border-collapse: collapse;" `)
+          .replaceAll("<td>", `<td style="border: 1px solid black;">`);
+
+        const res = await exportDocument({
+          content: contentData,
+          title: this.docAttr.title,
+        });
+
+        if (res.status != 200) {
+          this.$alert(res.errMsg);
+          return;
         }
-      );
+
+        let a = document.createElement("a");
+        a.href = res.data.file_path;
+        a.download = res.data.file_name;
+        document.body.appendChild(a);
+        a.click();
+        document.body.removeChild(a);
+      } catch (error) {
+        this.$alert("导出文档时发生错误,请稍后重试。");
+      } finally {
+        this.exporting = false; // 无论成功还是失败,都将导出状态设置回 false
+      }
     },
 
     /* onExport() {

+ 2 - 2
src/views/document/components/dataList.vue

@@ -20,13 +20,13 @@
         width="150"
       />
       <el-table-column
-        prop="category.name"
+        prop="type_name"
         label="所属分类"
         align="center"
         width="150"
       />
       <el-table-column
-        prop="createTime"
+        prop="create_time"
         label="创建时间"
         align="center"
         width="150"

+ 101 - 97
src/views/document/create.vue

@@ -55,62 +55,44 @@
             <el-input placeholder="搜索文档标题"></el-input>
           </div>
           <div class="new-article">
-            <el-collapse
-              v-model="activeNames"
-              :accordion="true"
-              @change="handleItemClick"
-            >
-              <el-collapse-item title="最新文档" name="-1" v-if="showView == 0">
-                <div
-                  v-for="(it, index) in articleList"
-                  draggable
-                  :key="it.id"
-                  :data-index="index"
-                  data-type="article"
-                  class="sub-menus"
-                >
-                  <div @click="onLoadArticle(it)">{{ 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 v-if="showView == 0">
+              <el-collapse v-model="activeNames">
+                <el-collapse-item title="最新文档" name="-1">
+                  <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)">{{ it.title }}</div>
+                  </div>
+                </el-collapse-item>
+                <el-collapse-item
+                  title="模版列表"
+                  name="-2"
+                  v-if="showView == 0"
                 >
-                  <div @click="onTemplateInfo(it)">{{ it.title }}</div>
-                </div>
-              </el-collapse-item>
-
-              <!--     <template v-for="(item, itemIndex) in categoryList">
-                <div class="sub-title">{{ item.name }}</div>
-                <template v-for="(subItem, subIndex) in item.children">
-                  <el-collapse-item :title="subItem.name" :name="subItem.id">
-                    <draggable
-                      v-model="subItem.dataList"
-                      :options="{
-                        group: { name: 'itxst', pull: 'clone' },
-                        sort: true,
-                      }"
-                      animation="300"
-                    >
-                      <transition-group>
-                        <div
-                          class="sub-menus"
-                          v-for="(it, index) in subItem.dataList"
-                          :key="index"
-                        >
-                          <div>{{ it.name }}</div>
-                        </div>
-                      </transition-group>
-                    </draggable>
-                  </el-collapse-item>
-                </template>
-              </template> -->
-              <div v-if="showView == 1">
+                  <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)">{{ it.title }}</div>
+                  </div>
+                </el-collapse-item>
+              </el-collapse>
+            </div>
+            <div v-if="showView == 1">
+              <el-collapse
+                v-model="activeModel"
+                :accordion="true"
+                @change="handleItemClick"
+              >
                 <el-collapse-item
                   v-for="(item, itemIndex) in categoryList"
                   :key="itemIndex"
@@ -118,6 +100,7 @@
                   :name="item.id"
                 >
                   <el-collapse
+                    v-if="item.children && item.children.length"
                     v-model="item.activeChildren"
                     @change="handleItemVal"
                     v-show="item.children"
@@ -165,8 +148,8 @@
                     </transition-group>
                   </draggable>
                 </el-collapse-item>
-              </div>
-            </el-collapse>
+              </el-collapse>
+            </div>
           </div>
         </div>
         <div class="right-sidebarew">
@@ -195,7 +178,13 @@
             :comArr="coms"
           ></menus>
         </div>
-        <div class="editor-box" ref="tabHtml" v-loading="loading">
+        <div
+          class="editor-box"
+          ref="tabHtml"
+          v-loading="loading"
+          element-loading-text="加载中..."
+          element-loading-spinner="el-icon-loading"
+        >
           <editor
             :coms="coms"
             :comIndex="comIndex"
@@ -314,7 +303,7 @@
 <script>
 import { findData } from "@/api/sourceData";
 import utils from "@/utils/fun"; // 方法类
-import { searchDocument,pageDocument } from "@/api/document";
+import { searchDocument, pageDocument } from "@/api/document";
 import menus from "./com/menus";
 import editor from "./com/editor";
 import Attribute from "./com/components/Attribute";
@@ -364,6 +353,7 @@ export default {
       activeNames: "-1",
       nestedActiveNames: [],
       articleList: [],
+      activeModel: "",
       templateList: [],
       categoryList: [],
       //组件相关
@@ -405,7 +395,6 @@ export default {
     coms: {
       handler(newComs, oldComs) {
         this.updateAttrs(newComs, oldComs);
-        
       },
       immediate: true, //立即执行
       deep: true,
@@ -452,8 +441,8 @@ export default {
 
     updateGlobalAttr(attrId, newContent) {
       // 遍历所有组件,更新匹配的属性
-      this.coms.forEach(com => {
-        com.attrs.forEach(attr => {
+      this.coms.forEach((com) => {
+        com.attrs.forEach((attr) => {
           if (attr.name === attrId) {
             attr.content = newContent;
           }
@@ -486,7 +475,7 @@ export default {
 
               formual = await this.getRemote(formual);
               el.content = eval(formual);
-              
+
               /* data = data.replace("{{" + attrId + "}}", eval(formual)); */
             } catch (error) {
               console.error("处理公式时出错:", error);
@@ -494,7 +483,6 @@ export default {
           }
         }
       }
-      console.log(this.coms);
       return data;
     },
     //分析公式
@@ -654,7 +642,6 @@ export default {
       return result;
     },
 
-/*  */
     handleItemVal(value) {
       this.$forceUpdate();
     },
@@ -781,12 +768,13 @@ export default {
 
     loadArticle(e) {
       let _this = this;
-      getDocumentInfo({
+      _this.onLoadArticle(e);
+      /* getDocumentInfo({
         id: e,
       }).then((res) => {
         if (res.status != 200) return;
         _this.onLoadArticle(res.data);
-      });
+      }); */
     },
 
     handleDragStart(e) {
@@ -827,40 +815,56 @@ export default {
     //加载文档信息
     onLoadArticle(e) {
       let _this = this;
-      console.log(e);
-      _this.docAttr = {
-        id: e.id,
-        category_id: e.category_id * 1,
-        title: e.title,
-        content: "",
-        status: e.status,
-        is_template: e.is_template,
-        linkProduct: e.linkProduct,
-        links: e.links,
-        linkProject: e.linkProject,
-        projects: e.projects,
-      };
-      _this.coms = JSON.parse(e.data);
-      
+      this.loading = true; // Set loading to true
+      getDocumentInfo({ id: e })
+        .then((res) => {
+          this.loading = false; // Set loading to false after data is loaded
+          if (res.status !== 200) return;
+          _this.docAttr = {
+            id: res.data.id,
+            category_id: res.data.category_id * 1,
+            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,
+          };
+          _this.coms = JSON.parse(res.data.data);
+        })
+        .catch(() => {
+          this.loading = false; // Ensure loading is false on error
+        });
+
       this.uptadeSearch();
     },
     /* 加载模版信息 */
     onTemplateInfo(e) {
       let _this = this;
-      _this.docAttr = {
-        id: e.id,
-        category_id: e.category_id * 1,
-        title: e.title,
-        content: "",
-        status: e.status,
-        is_template: e.is_template,
-        linkProduct: e.linkProduct,
-        links: e.links,
-        linkProject: e.linkProject,
-        projects: e.projects,
-      };
-      _this.coms = JSON.parse(e.data);
-      console.log(JSON.parse(e.data));
+      this.loading = true;
+      getDocumentInfo({ id: e })
+        .then((res) => {
+          this.loading = false; // Set loading to false after data is loaded
+          if (res.status !== 200) return;
+          _this.docAttr = {
+            id: res.data.id,
+            category_id: res.data.category_id * 1,
+            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,
+          };
+          _this.coms = JSON.parse(res.data.data);
+        })
+        .catch(() => {
+          this.loading = false; // Ensure loading is false on error
+        });
       this.uptadeSearch();
     },
     onRemove(index) {
@@ -1412,7 +1416,7 @@ export default {
     //获取文档列表
     searchArticle() {
       let _this = this;
-      searchDocument({
+      pageDocument({
         page: 1,
         pageSize: 99,
       }).then((res) => {

+ 2 - 2
src/views/document/temList/components/dataList.vue

@@ -14,13 +14,13 @@
         min-width="180"
       />
       <el-table-column
-        prop="category.name"
+        prop="type_name"
         label="所属分类"
         align="center"
         width="150"
       />
       <el-table-column
-        prop="createTime"
+        prop="create_time"
         label="创建时间"
         align="center"
         width="150"

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików