wucl před 1 rokem
rodič
revize
918929a303

+ 4 - 4
.env.development

@@ -9,7 +9,7 @@ VUE_APP_BASE_WEB = ''
 VUE_CLI_BABEL_TRANSPILE_MODULES = true
 
 # host 地址,需要改成本机 IP 地址,不能是 127.0.0.1 或者 localhost
-VUE_APP_HOST=47.108.172.52
+VUE_APP_HOST=kps.scdayou.com
 
 # 端口号
 VUE_APP_PORT=8091
@@ -21,13 +21,13 @@ VUE_APP_API_PREFIX=/api
 VUE_APP_API_PORT=80
 
 # 业务服务地址  https://kps.scdayou.com/dfs/2023/08/03/real-report.docx
-VUE_APP_API_SERVER=http://$VUE_APP_HOST:$VUE_APP_API_PORT
+VUE_APP_API_SERVER=http://$VUE_APP_HOST
 
 # Onlyoffice 服务端口号
 VUE_APP_ONLYOFFICE_PORT=8091
 
 # Onlyoffice 服务地址
-VUE_APP_ONLYOFFICE_SERVER=http://$VUE_APP_HOST:$VUE_APP_ONLYOFFICE_PORT
+VUE_APP_ONLYOFFICE_SERVER=http://kps.scdayou.com:8091
 
 # Onlyoffice 接口前缀配置
 VUE_APP_ONLYOFFICE_API_PREFIX=/onlyofficeApi
@@ -42,7 +42,7 @@ VUE_APP_ONLYOFFICE_DOCBUILDER=192.168.0.108:8088/api/onlyoffice/callback
 VUE_APP_ONLYOFFICE_CONVERT=192.168.0.108:8088/api/onlyoffice/callback
 
 # Onlyoffice 入口 JS 文件
-VUE_APP_ONLYOFFICE_API_URL=$VUE_APP_ONLYOFFICE_SERVER/web-apps/apps/api/documents/api.js
+VUE_APP_ONLYOFFICE_API_URL=http://kps.scdayou.com:8091/web-apps/apps/api/documents/api.js
 
 
 # 只有以VUE_APP_开头的变量才会被webpack.DefinePlugin静态嵌入到客户端侧的包中

+ 35 - 0
.env.production

@@ -6,3 +6,38 @@ VUE_APP_BASE_API = '/api/'
 VUE_APP_BASE_API2 = '/api'
 VUE_APP_BASE_WEB = '/admin'
 
+# host 地址,需要改成本机 IP 地址,不能是 127.0.0.1 或者 localhost
+VUE_APP_HOST=kps.scdayou.com
+
+# 端口号
+VUE_APP_PORT=8091
+
+# 业务接口前缀配置
+VUE_APP_API_PREFIX=/api
+
+# 业务端口号
+VUE_APP_API_PORT=80
+
+# 业务服务地址  https://kps.scdayou.com/dfs/2023/08/03/real-report.docx
+VUE_APP_API_SERVER=http://$VUE_APP_HOST
+
+# Onlyoffice 服务端口号
+VUE_APP_ONLYOFFICE_PORT=8091
+
+# Onlyoffice 服务地址
+VUE_APP_ONLYOFFICE_SERVER=https://kps.scdayou.com/office
+
+# Onlyoffice 接口前缀配置
+VUE_APP_ONLYOFFICE_API_PREFIX=/onlyofficeApi
+
+# Onlyoffice 回调接口地址,相关文档:https://api.onlyoffice.com/editors/callback
+VUE_APP_ONLYOFFICE_CALLBACK=https://kps.scdayou.com/api/onlyoffice/callback
+
+# Onlyoffice 文档构建接口地址,相关文档:https://api.onlyoffice.com/editors/documentbuilderapi
+VUE_APP_ONLYOFFICE_DOCBUILDER=https://kps.scdayou.com/api/onlyoffice/callback
+
+# Onlyoffice 文档转换接口地址,相关文档:https://api.onlyoffice.com/editors/conversionapi
+VUE_APP_ONLYOFFICE_CONVERT=https://kps.scdayou.com/api/onlyoffice/callback
+
+# Onlyoffice 入口 JS 文件
+VUE_APP_ONLYOFFICE_API_URL=https://kps.scdayou.com/office/web-apps/apps/api/documents/api.js

+ 1 - 0
public/index.html

@@ -6,6 +6,7 @@
   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
   <meta name="renderer" content="webkit">
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
+  <!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> -->
   <link rel="shortcut icon" href="<%= BASE_URL %>dayou_favicon.ico">
   <title>大友评估主营业务系统</title>
 </head>

+ 31 - 18
public/ueditor/ueditor.all.js

@@ -14069,7 +14069,9 @@ UE.plugin.register('wordimage',function(){
                 var attrs = img.attrs,
                     flag = parseInt(attrs.width) < 128 || parseInt(attrs.height) < 43,
                     opt = me.options,
-                    src = opt.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif';
+                     //尝试当图片上传失败,富文本不保存 loadingHtml代码
+                    src = '';
+                    //opt.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif';
                 if (attrs['src'] && /^(?:(file:\/+))/.test(attrs['src'])) {
                     img.setAttr({
                         width:attrs.width,
@@ -17652,9 +17654,10 @@ UE.plugins['video'] = function (){
 
         var str;
         switch (type){
+            //尝试当图片上传失败,富文本不保存 loadingHtml代码
             case 'image':
-                str = '<img ' + (id ? 'id="' + id+'"' : '') + ' width="'+ width +'" height="' + height + '" _url="'+url+'" class="' + classname.replace(/\bvideo-js\b/, '') + '"'  +
-                    ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;'+(align ? 'float:' + align + ';': '')+'" />'
+                // str = '<img ' + (id ? 'id="' + id+'"' : '') + ' width="'+ width +'" height="' + height + '" _url="'+url+'" class="' + classname.replace(/\bvideo-js\b/, '') + '"'  +
+                //     ' src="' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif" style="background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;'+(align ? 'float:' + align + ';': '')+'" />'
                 break;
             case 'embed':
                 str = '<embed type="application/x-shockwave-flash" class="' + classname + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
@@ -23511,12 +23514,14 @@ UE.plugin.register('webapp', function (){
     var me = this;
     function createInsertStr(obj,toEmbed){
         return  !toEmbed ?
-            '<img title="'+obj.title+'" width="' + obj.width + '" height="' + obj.height + '"' +
-                ' src="' + me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif" _logo_url="'+obj.logo+'" style="background:url(' + obj.logo
-                +') no-repeat center center; border:1px solid gray;" class="edui-faked-webapp" _url="' + obj.url + '" ' +
-                (obj.align && !obj.cssfloat? 'align="' + obj.align + '"' : '') +
-                (obj.cssfloat ? 'style="float:' + obj.cssfloat + '"' : '') +
-                '/>'
+        //尝试当图片上传失败,富文本不保存 loadingHtml代码
+            ""
+            // '<img title="'+obj.title+'" width="' + obj.width + '" height="' + obj.height + '"' +
+            //     ' src="' + me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif" _logo_url="'+obj.logo+'" style="background:url(' + obj.logo
+            //     +') no-repeat center center; border:1px solid gray;" class="edui-faked-webapp" _url="' + obj.url + '" ' +
+            //     (obj.align && !obj.cssfloat? 'align="' + obj.align + '"' : '') +
+            //     (obj.cssfloat ? 'style="float:' + obj.cssfloat + '"' : '') +
+            //     '/>'
             :
             '<iframe class="edui-faked-webapp" title="'+obj.title+'" ' +
                 (obj.align && !obj.cssfloat? 'align="' + obj.align + '"' : '') +
@@ -23760,9 +23765,11 @@ UE.plugin.register('autoupload', function (){
         };
 
         if (filetype == 'image') {
-            loadingHtml = '<img class="loadingclass" id="' + loadingId + '" src="' +
-                me.options.themePath + me.options.theme +
-                '/images/spacer.gif" title="' + (me.getLang('autoupload.loading') || '') + '" >';
+            //尝试当图片上传失败,富文本不保存 loadingHtml代码
+            loadingHtml = ""
+            //  '<img class="loadingclass" id="' + loadingId + '" src="' +
+            //     me.options.themePath + me.options.theme +
+            //     '/images/spacer.gif" title="' + (me.getLang('autoupload.loading') || '') + '" >';
             successHandler = function(data) {
                 var link = urlPrefix + data.url,
                     loader = me.document.getElementById(loadingId);
@@ -23776,11 +23783,13 @@ UE.plugin.register('autoupload', function (){
                 }
             };
         } else {
-            loadingHtml = '<p>' +
-                '<img class="loadingclass" id="' + loadingId + '" src="' +
-                me.options.themePath + me.options.theme +
-                '/images/spacer.gif" title="' + (me.getLang('autoupload.loading') || '') + '" >' +
-                '</p>';
+            //尝试当图片上传失败,富文本不保存 loadingHtml代码
+            loadingHtml = ""
+            // '<p>' +
+            //     '<img class="loadingclass" id="' + loadingId + '" src="' +
+            //     me.options.themePath + me.options.theme +
+            //     '/images/spacer.gif" title="' + (me.getLang('autoupload.loading') || '') + '" >' +
+            //     '</p>';
             successHandler = function(data) {
                 var link = urlPrefix + data.url,
                     loader = me.document.getElementById(loadingId);
@@ -24513,7 +24522,11 @@ UE.plugin.register('simpleupload', function (){
                 var allowFiles = me.getOpt('imageAllowFiles');
 
                 me.focus();
-                me.execCommand('inserthtml', '<img class="loadingclass" id="' + loadingId + '" src="' + me.options.themePath + me.options.theme +'/images/spacer.gif" title="' + (me.getLang('simpleupload.loading') || '') + '" >');
+                me.execCommand('inserthtml', 
+                ''
+                 //尝试当图片上传失败,富文本不保存 loadingHtml代码
+                //'<img class="loadingclass" id="' + loadingId + '" src="' + me.options.themePath + me.options.theme +'/images/spacer.gif" title="' + (me.getLang('simpleupload.loading') || '') + '" >'
+                );
 
                 function callback(){
                     try{

+ 6 - 6
public/ueditor/ueditor.config.js

@@ -34,7 +34,7 @@
 
         //工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义
         , toolbars: [[
-            'fullscreen', 'source', '|', 'undo', 'redo', '|',
+            'source', '|', 'undo', 'redo', '|',
             'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
             'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
             'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
@@ -42,9 +42,9 @@
             'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
             'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
             'simpleupload', 'insertimage',  'scrawl', 'insertcode', 'pagebreak', 'template', '|',
-            'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',
+            'horizontal', 'date', 'time', 'spechars', 'wordimage', '|',
             'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
-            'print', 'preview', 'searchreplace', 'drafts', 'help'
+            'print', 'preview', 'searchreplace', 'help'
         ]]
         //当鼠标放在工具栏上时显示的tooltip提示,留空支持自动多语言配置,否则以配置值为准
         //,labelMap:{
@@ -61,7 +61,7 @@
         //,theme:'default'
         //,themePath:URL +"themes/"
 
-        //,zIndex : 900     //编辑器层级的基数,默认是900
+        ,zIndex : 10000    //编辑器层级的基数,默认是900
 
         //针对getAllHtml方法,会在对应的head标签中增加该编码设置。
         //,charset:"utf-8"
@@ -90,14 +90,14 @@
         //,indentValue:'2em'
 
         ,initialFrameWidth:800 //初始化编辑器宽度,默认1000
-        ,initialFrameHeight:600  //初始化编辑器高度,默认320
+        ,initialFrameHeight:650  //初始化编辑器高度,默认320
 
         //,readonly : false //编辑器初始化结束后,编辑区域是否是只读的,默认是false
 
         //,autoClearEmptyNode : true //getContent时,是否删除空的inlineElement节点(包括嵌套的情况)
 
         //启用自动保存
-        //,enableAutoSave: true
+        //,enableAutoSave: false
         //自动保存间隔时间, 单位ms
         //,saveInterval: 500
 

+ 0 - 3
src/api/modules/globalConfig.js

@@ -27,8 +27,5 @@ export default {
   getEnumByKey(params) { // 根据key获取枚举值
     return request.get(`globalConfig/getEnumByKey`, { params: params })
   },
-  getByKey(params) { // 根据key获取枚举值
-    return request.get(`globalConfig/byKey/${params}`)
-  }
 
 }

+ 6 - 0
src/api/modules/reportHeadline.js

@@ -23,5 +23,11 @@ export default {
    },
    getHeadlineTree(params){
     return request.get(`reportHeadline/tree/${params}`)
+   },
+   getAllHeadlineTree(){
+    return request.get(`reportHeadline/tree`)
+   },
+   getReportType(){
+    return request.get(`reportHeadline/root`)
    }
 }

+ 30 - 0
src/api/modules/reportMain.js

@@ -0,0 +1,30 @@
+import request from '@/utils/request'
+/*
+* 报告主表
+*/
+export default {
+  list(params) {
+    return request.get(`reportMain`, { params: params })
+  },
+  detail(params) {
+    return request.get(`reportMain/${params}`)
+  },
+  simpleAll() {
+    return request.get(`reportMain/simpleAll`)
+  },
+  add(params) {
+    return request.post(`reportMain`, params)
+  },
+  edit(params) {
+    return request.put(`reportMain`, params)
+  },
+   delete(params) {
+     return request.delete(`reportMain/${params}`)
+   },
+   getMainTree(params){
+    return request.get(`reportMain/tree/${params}`)
+   },
+   generateReport(params){
+    return request.get(`reportMain/generate/${params}`)
+   }
+}

+ 7 - 4
src/api/modules/reportSection.js

@@ -1,6 +1,6 @@
 import request from '@/utils/request'
 /*
-* 操作日志
+* 报告段落内容
 */
 export default {
   list(params) {
@@ -21,7 +21,10 @@ export default {
    delete(params) {
      return request.delete(`reportSection/${params}`)
    },
-   getReportSectionList(params){
-    return request.get(`reportSection/headline/${params}`)
-  },
+   calculate(params){
+    return request.post(`reportSection/calculate`, params)
+   },
+   structure(params){
+    return request.get(`reportSection/structure/${params}`)
+   }
 }

+ 27 - 0
src/api/modules/reportSectionTemplate.js

@@ -0,0 +1,27 @@
+import request from '@/utils/request'
+/*
+* 操作日志
+*/
+export default {
+  list(params) {
+    return request.get(`reportSectionTemplate`, { params: params })
+  },
+  detail(params) {
+    return request.get(`reportSectionTemplate/${params}`)
+  },
+  simpleAll() {
+    return request.get(`reportSectionTemplate/simpleAll`)
+  },
+  add(params) {
+    return request.post(`reportSectionTemplate`, params)
+  },
+  edit(params) {
+    return request.put(`reportSectionTemplate`, params)
+  },
+   delete(params) {
+     return request.delete(`reportSectionTemplate/${params}`)
+   },
+   getReportSectionList(params){
+    return request.get(`reportSectionTemplate/headline/${params}`)
+  },
+}

binární
src/assets/icon/jisuanqi.png


binární
src/assets/images/null.png


+ 7 - 4
src/components/DocumentWindow/index.vue

@@ -34,11 +34,14 @@
             // 文件类型
             fileType: 'docx',
             // 文档标识符
-            key: '123',
+            // key: this.$route.query.key,
+            key:'ea307c53b435ecaed4091410bdde9',
             // 文档地址,绝对路径
-            url: `${process.env.VUE_APP_API_SERVER}/dfs/2023/08/03/兴文县2023年第3批次建设用地风险评估报告.docx`,
+            // url: process.env.VUE_APP_API_SERVER + this.$route.query.url,
+            //url: process.env.VUE_APP_API_SERVER + '/dfs/2023/08/03/兴文县2023年第3批次建设用地风险评估报告.docx',
+            url: process.env.VUE_APP_API_SERVER + '/dfs/reports/20230905184400-746ea307c53b435ecaed4091410bdde9.docx',
             // 文档标题
-            title: '测试文档一.docx'
+            title: this.$route.query.title
           }
         }
       }
@@ -47,7 +50,7 @@
       OnlyofficeEditor
     },
     created() {
-      this.queryDocumentInfo()
+      this.queryDocumentInfo();
     },
     methods: {
       // 获取文档配置信息

+ 33 - 31
src/components/ReportContentCarousel/index.vue

@@ -2,17 +2,18 @@
     <div>
         <el-card class="box-card" shadow="never">
             <div>
-                <el-card v-for="(t,index) in tricks"  :key="index" class="chlid-box-card" shadow="hover">
+                <el-card v-for="(t, index) in tricks" :key="index" class="chlid-box-card" shadow="hover">
                     <div slot="header" class="cardHeader">
-                        段落模板:<el-tag effect="plain">{{t.name}}</el-tag> 
+                        段落模板:<el-tag effect="plain">{{ t.name }}</el-tag>
                     </div>
-                    <p class="trick" v-if="removeHtmlTag(t.section)!=null">{{ removeHtmlTag(t.section) }}
-                        <el-button plain>引用</el-button><el-button plain @click="prview(t.section)" type="primary">预览</el-button>
+                    <p class="trick" v-if="removeHtmlTag(t.section) != null">{{ removeHtmlTag(t.section) }}
+                        <el-button plain @click="reference(t.section)">引用</el-button><el-button plain
+                            @click="prview(t.section)" type="primary">预览</el-button>
                     </p>
                 </el-card>
             </div>
         </el-card>
-        <el-dialog  :visible.sync="dialogTableVisible" width="60%" center>
+        <el-dialog :visible.sync="dialogTableVisible" width="60%" center>
             <div class="dialog-bg">
                 <div class="like-word" v-html="htmlStr">
                 </div>
@@ -22,19 +23,13 @@
 </template>
 
 <script>
-import YUeditor from "@/components/YUeditor"
 export default {
-    components: {
-        YUeditor,
-    }
-    ,
-
     props: {
         tricks: {
             type: Array,
             required: false,
-            default:[]
-        }
+            default: []
+        },
     },
 
     computed: {
@@ -42,8 +37,8 @@ export default {
     },
     data() {
         return {
-            dialogTableVisible :false,
-            htmlStr : null,
+            dialogTableVisible: false,
+            htmlStr: null,
         }
 
     },
@@ -52,35 +47,41 @@ export default {
             this.dialogTableVisible = true
             this.htmlStr = htmlStr;
         },
-        removeHtmlTag(htmlStr){
-            if (htmlStr){
+        removeHtmlTag(htmlStr) {
+            if (htmlStr) {
                 let content = htmlStr.replace(/<[^>]+>/g, "");
-                return  content.length > 80 ? (content.slice(0, 80) + '...') : (content);
+                return content.length > 80 ? (content.slice(0, 80) + '...') : (content);
             }
-            else{
+            else {
                 return null;
             }
-           
+
+        },
+        reference(section) {
+            this.$emit('reference',section)
         }
     }
 }
 </script>
-<style >
+<style scoped>
 .box-card {
     width: 750px;
 }
-.cardHeader{
+.cardHeader {
     height: 20px;
     color: gray;
 }
+
 .chlid-box-card {
     width: 710px;
     height: 200px;
     margin-bottom: 30px;
 }
 
-.chlid-box-card :hover {
+.chlid-box-card:hover {
     color: black;
+    cursor: pointer;
+    font-weight: bold;
 }
 
 p {
@@ -89,24 +90,25 @@ p {
     letter-spacing: 2px;
     line-height: 1.5
 }
-.dialog-bg{
+
+.dialog-bg {
     width: 100%;
     height: 700px;
     position: relative;
     overflow: scroll;
 
 }
-.like-word{
+
+.like-word {
     width: 90%;
-    height: 600px;
+    height: auto;
     position: absolute;
-    top:20px;
+    top: 20px;
     left: 0;
     right: 0;
     margin: auto;
-    -moz-box-shadow: 3px 3px 4px rgb(255,228,227);
-    -webkit-box-shadow: 3px 3px 4px rgb(255,228,227);
+    -moz-box-shadow: 3px 3px 4px rgb(255, 228, 227);
+    -webkit-box-shadow: 3px 3px 4px rgb(255, 228, 227);
     box-shadow: 0 0 20px rgb(175, 175, 175);
     padding: 20px;
-}
-</style>
+}</style>

+ 774 - 86
src/components/ReportEditor/index.vue

@@ -1,116 +1,804 @@
 
 <template>
-    <div class="report">
-      <el-tabs  tab-position="top" style="height: auto;" type="border-card" @tab-click="pickHeadline1">
-        <el-tab-pane label="名词配置">
-          <div>
-            
-          </div>
-        </el-tab-pane>
-        <el-tab-pane v-for="(t,index) in headlineTree"  :key="index" :label="t.headline" :name="t.id+''">
-          <el-tabs v-loading="listLoading" v-model="activeName" v-if="t.children.length>0"  tab-position="top" style="height: auto;" @tab-click="pickHeadline2">
-            <el-tab-pane v-for="(tc,index) in t.children"  :key="index" :label="tc.headline" :name="tc.id+''" >
+  <div class="report">
+    <div v-if="processLoading" class="loader"></div>
+
+    <!-- 一级标题 -->
+    <el-tabs v-loading="listLoading" tab-position="top" style="height: auto; width: 99%;" type="border-card" @tab-click="pickHeadline1" >
+      <el-tab-pane label="名词配置">
+        <el-divider content-position="right" style="margin-top:100px;"><el-button type="success" @click="saveNouns" :disabled="ableAdd">保存</el-button>
+          <el-button type="danger" @click="generateReport" :disabled="ableAdd">生成报告</el-button>
+            </el-divider>
+        <div class="nouns-area">
+          <el-collapse v-model="activeNames">
+            <el-collapse-item  name="common">
+              <template slot="title">
+                <span style="margin-left: 40%; font-weight: bold;  color:gray ;letter-spacing: 2px;">通用名词</span>
+                <i class="el-icon-s-grid" style=" color:gray ;"></i>
+              </template>
               <div>
-                <el-row :gutter="900">
-                  <el-col :span="6">
+                <el-row :gutter="20" v-for="(n3, index) in commonNouns" :key="index" style="margin-bottom: 10px;">
+                  <el-col :span="8" v-for="(n, index) in n3" :key="index">
+                <el-card shadow="hover" :body-style="{ padding: '5px' }" class="cardHover">
+                  <div style="display: flex; float: right; margin-bottom: 5px;" >
+                    <div>
+                      <el-tag type="info">中文含义</el-tag>
+                      <input class="nounsInput" v-model="n.name"  disabled />
+ 
+                    </div>
                     <div>
-                      <YUeditor />
+                      <el-tag type="info">占位符</el-tag>
+                      <input class="nounsInput" v-model="n.placeholder" disabled/>
                     </div>
-                  </el-col>
-                  <el-col :span="6">
                     <div>
-                      <ReportContentCarousel :tricks="tricks" />
+                      <el-tag type="info" :style="setValueStyle(n.value)">替换值</el-tag>
+                      <input class="nounsInput" v-model="n.value" @blur="check($event)"/>
                     </div>
-                  </el-col>
-                </el-row>
+                  </div>
+                </el-card>
+              </el-col>
+            </el-row>
               </div>
-            </el-tab-pane>
-          </el-tabs>
-          <div v-else>
-            <el-row :gutter="900">
-                  <el-col :span="6">
+            </el-collapse-item>
+            <el-collapse-item  name="custom">
+              <el-divider content-position="right"><el-button type="success" @click="addCustomNoun" :disabled="ableAdd">添加</el-button>
+            </el-divider>
+              <template slot="title">
+                <span style="margin-left: 40%; font-weight: bold; color:gray ; letter-spacing: 2px;">自定义名词</span>
+                <i class="el-icon-s-grid" style="  color:gray ;"></i>
+              </template>
+              <div>
+                <el-row :gutter="20" v-for="(n3, index) in customNouns" :key="index" style="margin-bottom: 10px;">
+              <el-col :span="8" v-for="(n, index) in n3" :key="index">
+                <el-card shadow="hover" :body-style="{ padding: '5px' }"  class="cardHover">
+                  <div style="display: flex; float: right; margin-bottom: 5px;">
+                    <div>
+                      <el-tag type="info" :style="setValueStyle(n.name)">中文含义</el-tag>
+                      <input class="nounsInput" v-model="n.name" @blur="check($event)"  />
+                    </div>
                     <div>
-                      <YUeditor />
+                      <el-tag type="info" :style="setValueStyle(n.placeholder)">占位符</el-tag>
+                      <input class="nounsInput" v-model="n.placeholder" @blur="check($event)" />
                     </div>
-                  </el-col>
-                  <el-col :span="6">
                     <div>
-                      <ReportContentCarousel :tricks="tricks" />
+                      <i class="el-icon-error nouns-del" @click="deleteCard(n)"></i>
+                      <el-tag type="info" :style="setValueStyle(n.value)">替换值</el-tag>
+                      <input class="nounsInput" v-model="n.value" @blur="check($event)"/>
                     </div>
-                  </el-col>
-                </el-row>
-          </div>
-        </el-tab-pane>
-      </el-tabs>
+                  </div>
+                </el-card>
+              </el-col>
+            </el-row>
+              </div>
+            </el-collapse-item>
+          </el-collapse>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane v-for="(t, index) in headlineTree" :key="index" :label="t.headline" :name="t.id + ''" :lazy=true>
+        <!-- 二级标题 -->
+        <el-tabs v-loading="listLoading" v-model="activeName" v-if="t.children!=null && t.children.length > 0" tab-position="top"
+          style="height: auto;" @tab-click="pickHeadline2">
+          <el-tab-pane v-for="(tc, index) in t.children" :key="index" :label="tc.headline" :name="tc.id + ''" :lazy=true>
+            <span slot="label"><i class="el-icon-success" :style=setIstyle(tc.section)></i> {{ tc.headline }}</span>
+            <span slot="label" v-if="tc.action!=null">
+              <img src="../../assets/icon/jisuanqi.png" class="jisuan-icon"  alt="" @click="openTableDialog(tc.headline)"></span>
+            <!-- 三级标题 -->
+            <el-tabs v-loading="listLoading" v-model="activeName1" v-if="tc.children != null && tc.children.length > 0"
+              tab-position="top" style="height: auto;" @tab-click="pickHeadline3">
+              <el-tab-pane v-for="(tcc, index) in tc.children" :key="index" :label="tcc.headline" :name="tcc.id + ''" :lazy=true>
+                <span slot="label"><i class="el-icon-success" :style=setIstyle(tcc.section)></i> {{ tcc.headline }}</span>
+                <span slot="label" v-if="tcc.action!=null">
+                  <el-tooltip class="item" effect="dark" content="点击输入计算数据" placement="top-start">
+                    <img src="../../assets/icon/jisuanqi.png" class="jisuan-icon" alt="" @click="openTableDialog(tcc.headline)">
+                  </el-tooltip>
+                </span>
+                <div>
+                  <el-row :gutter="850">
+                    <el-col :span="6">
+                      <div class="editor-area">
+                        <YUeditor :content="tcc.section" :unique=tcc.sectionId  ref="euditor" :config={offsetWidth:1,offsetHeight:1} />
+                        <div style="text-align: center;">
+                          <el-button type="success" style="margin-top: 10px;"
+                            @click="saveSection(tcc.sectionId)">保存至文档</el-button>
+                        </div>
+                      </div>
+                    </el-col>
+                    <el-col :span="6">
+                      <div v-if="tricks.length > 0" class="section-area">
+                        <ReportContentCarousel :tricks="tricks" @reference="getSection" />
+                      </div>
+                      <div v-else class="null-area">
+                        <el-empty :image="require('../../assets/images/null.png')" :image-size=500
+                          description="还没有段落模板,快去创建吧。">
+                        </el-empty>
+                      </div>
+                    </el-col>
+                  </el-row>
+                </div>
+              </el-tab-pane>
+            </el-tabs>
+            <div v-else>
+              <el-row :gutter="850">
+                <el-col :span="6">
+                  <div class="editor-area">
+                    <YUeditor :content="tc.section" :unique=tc.sectionId ref="euditor" :config={offsetWidth:1,offsetHeight:1} />
+                    <div style="text-align: center;">
+                      <el-button type="success" style="margin-top: 10px;"
+                        @click="saveSection(tc.sectionId)">保存至文档</el-button>
+                    </div>
+                  </div>
+                </el-col>
+                <el-col :span="6">
+                  <div v-if="tricks.length > 0" class="section-area">
+                    <ReportContentCarousel :tricks="tricks" @reference="getSection" />
+                  </div>
+                  <div v-else class="null-area">
+                    <el-empty :image="require('../../assets/images/null.png')" :image-size=500
+                      description="还没有段落模板,快去创建吧。">
+                    </el-empty>
+                  </div>
+                </el-col>
+              </el-row>
+            </div>
+          </el-tab-pane>
+        </el-tabs>
+        <div v-else>
+          <div>
+              <el-row :gutter="850">
+                <el-col :span="6">
+                  <div class="editor-area">
+                    <YUeditor :content="t.section" :unique=t.sectionId ref="euditor" :config={offsetWidth:1,offsetHeight:1} />
+                    <div style="text-align: center;">
+                      <el-button type="success" style="margin-top: 10px;"
+                        @click="saveSection(t.sectionId)">保存至文档</el-button>
+                    </div>
+                  </div>
+                </el-col>
+                <el-col :span="6">
+                  <div v-if="tricks.length > 0" class="section-area">
+                    <ReportContentCarousel :tricks="tricks" @reference="getSection" />
+                  </div>
+                  <div v-else class="null-area">
+                    <el-empty :image="require('../../assets/images/null.png')" :image-size=500
+                      description="还没有段落模板,快去创建吧。">
+                    </el-empty>
+                  </div>
+                </el-col>
+              </el-row>
+            </div>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+    <div class="generator">
+      <el-tag style="margin-top: 3px;">{{ title }}</el-tag>
     </div>
-  </template>
+    <el-dialog :visible.sync="dialogVisible" width="80%"  center :title="dialogName" @closed="resetTableData">
+        <el-form label-width="550px" >
+            <el-card v-for="(t,index ) in inputData.inputTableData" :key=index>
+              <div slot="header" class="clearfix">
+                <el-tag style="font-size:larger;">{{ t.tableName }}</el-tag>
+                <el-button style="font-size:larger; float: right; padding: 3px 0" type="text" icon="el-icon-circle-plus" @click=addTableData(t.tableData,t.tableHead)>添加</el-button>
+                <el-button style="font-size:larger; float: right; padding: 3px 0" type="text" icon="el-icon-remove" @click=cleanTableData(index)>清除</el-button>
+              </div>
+                <el-table :data="t.tableData"  border style="width: 100%" >
+                  <el-table-column
+                    :label="t.label"
+                    :prop="t.prop"
+                    v-for="(t, index) in t.tableHead"
+                    :key="index"
+                  >
+                  <template slot-scope="scope">
+                    <el-input type="text" v-model.trim="scope.row[t.prop] " />
+                  </template>
+                  </el-table-column>
+              </el-table>
+            </el-card>
+            <el-card v-if="inputData.params">
+              <div slot="header" class="clearfix">
+                <el-tag style="font-size:larger;">固定参数</el-tag>
+              </div>
+              <div style="width: 50%;">
+                <el-form-item v-for="(i,index ) in inputData.params" :key=index :label=i.label :prop="i.name">
+                  <el-input  v-model.trim="i.value"/>
+                </el-form-item>
+              </div>
+            </el-card>
+        </el-form>
+        <span slot="footer" class="dialog-footer">
+            <el-button @click="dialogVisible = false">取 消</el-button>
+            <el-button type="primary" @click=saveTableData>保 存</el-button>
+        </span>
+    </el-dialog>
+  </div>
+
+</template>
   
-  <script>
-  import YUeditor from "@/components/YUeditor"
-  import ReportContentCarousel from "@/components/ReportContentCarousel"
-  export default {
-    components: {
-      YUeditor,
-      ReportContentCarousel
+<script>
+import YUeditor from "@/components/YUeditor"
+import ReportContentCarousel from "@/components/ReportContentCarousel"
+export default {
+  components: {
+    YUeditor,
+    ReportContentCarousel
+  },
+
+  props: {
+    headlineTree: {
+      type: Array,
+      require: true,
+    }
+
+  },
+  watch: {
+
+  },
+  computed: {
+
+  },
+  data() {
+    return {
+      dialogVisible:false,
+      processLoading: false,
+      listLoading: true,
+      activeName: null,
+      activeName1: null,
+      tricks: [],
+      pickedNode1Childrens: [],
+      pickedNode2Childrens: [],
+      activeNode: {
+        section: null,
+      },
+      filled: false,
+      reportId: this.$route.query.id,
+      title:this.$route.query.title,
+      nouns:{},
+      commonNouns1: [],
+      commonNouns: [],
+      customNouns: [],
+      customNouns1: [],
+      newNoun:{
+        "name": null, "placeholder": null, "value": null
+      },
+      reportMain:{
+        id:null,
+        reportNouns:{
+        }
+      },
+      activeNames:["common","custom"],
+      ableAdd:false,
+      dialogName:null,
+      inputData:{
+        params:[],
+        inputTableData:[
+          {
+            tableNo:null,
+            tableData:[]
+          }
+        ]
+      },
+      calculateData:{
+        action:null,
+        calculateDataDTO:{
+          sectionId:null,
+          tableData:[],
+          params:[]
+        },
+        jsonString:null
+      }
+    }
+  },
+
+  mounted(){
+
+  },
+  created() {
+    this.getNouns();
+  },
+  methods: {
+    getReportSectionList(headlineId) {
+      const that = this;
+      that.listLoading = true
+      that.$api.reportSectionTemplate.getReportSectionList(headlineId).then(res => {
+        if (res.code === 200) {
+          that.tricks = res.data;
+          that.listLoading = false;
+        }
+      }).catch(() => {
+        that.listLoading = false;
+      })
     },
-  
-    props:{
-        headlineTree :{
-            type: Array,
-            require: true,
+    pickHeadline1(tab, event) {
+      let tree = this.headlineTree;
+      let name = tab.name;
+      let pickedNode = tree.find(t => t.id.toString() === name)
+      if (typeof pickedNode != 'undefined') {
+        if (pickedNode.children != null && pickedNode.children.length > 0) {
+          this.pickedNode1Childrens = pickedNode.children,
+            this.activeName = pickedNode.children[0].id.toString();
+          if (pickedNode.children[0].children != null && pickedNode.children[0].children.length > 0) {
+            this.activeName1 = pickedNode.children[0].children[0].id.toString();
+            this.getReportSectionList(pickedNode.children[0].children[0].id);
+            this.activeNode = pickedNode.children[0].children[0];
+            this.pickedNode2Childrens = pickedNode.children[0].children;
+          } else {
+            this.getReportSectionList(pickedNode.children[0].id);
+            this.activeNode = pickedNode.children[0];
+            this.pickedNode2Childrens = [];
+          }
+        } else {
+          this.getReportSectionList(name);
+          this.activeNode = pickedNode;
+          this.pickedNode1Childrens = [];
         }
+      }
+    },
+    pickHeadline2(tab, event) {
+      let name = tab.name;
+      if (this.pickedNode1Childrens.length > 0) {
+        let pickedNode2 = this.pickedNode1Childrens.find(p => p.id.toString() === name);
+        if (typeof pickedNode2 != 'undefined') {
+          if (pickedNode2.children != null && pickedNode2.children.length > 0) {
+            this.pickedNode2Childrens = pickedNode2.children;
+            this.activeName1 = pickedNode2.children[0].id.toString();
+            this.getReportSectionList(pickedNode2.children[0].id);
+            this.activeNode = pickedNode2.children[0];
+            this.pickedNode2Childrens = pickedNode2.children;
+          } else {
+            this.getReportSectionList(name);
+            this.activeNode = pickedNode2;
+            this.pickedNode2Childrens = [];
+          }
+        }
+      }
 
     },
-    watch:{
+    pickHeadline3(tab, event) {
+      let name = tab.name;
+      this.getReportSectionList(name);
+      if (this.pickedNode2Childrens.length > 0) {
+        let pickedNode = this.pickedNode2Childrens.find(t => t.id.toString() === name);
+        this.activeNode = pickedNode;
+      }
+    },
+    //从子组件获取引用文本
+    getSection(section) {
+      this.listLoading = true
+      let all = [];
+      let commons = this.reportMain.reportNouns.common;
+      let customs = this.reportMain.reportNouns.custom;
+      if (typeof customs  != 'undefined' && customs!=null){
+        commons = commons.concat(customs);
+      }
+      for (let t in commons){
+          var reg = new RegExp(commons[t].placeholder,"g")
+          if (section.includes(commons[t].placeholder)){
+            section = section.replace(reg,commons[t].value)
+          }
+      
+      }
+      this.activeNode.section = section;
+      this.listLoading = false
+      
+    },
+    saveSection(sectionId) {
+      this.listLoading = true;
+      this.activeNode.children = [];
+      let content = this.$refs.euditor.find(e => e.unique === sectionId).getUEContent();
+      if (content==="" || content===null || typeof content ==='undefined'){
+        this.$notify({
+              title: '错误',
+              message: '文档段落还没有内容,请添加内容后保存。',
+              type: 'error',
+              duration: 2000
+            })
+            this.listLoading = false;
+            return ;
+      }
+      this.activeNode.section = content;
+      if (this.activeNode.sectionId != null && this.activeNode.section != null) {
+        this.$api.reportSection.edit(this.activeNode).then(res => {
+          if (res.code === 200) {
+            this.$notify({
+              title: '成功',
+              message: '文档段落保存成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.listLoading = false;
+          } else {
+            this.$notify({
+              title: '错误',
+              message: '文档段落引用失败,请联系管理员',
+              type: 'error',
+              duration: 2000
+            })
+            this.listLoading = false;
+          }
+        }).catch(() => {
+          this.listLoading = false;
+        })
+      }
+      this.listLoading = false;
+    },
+    setIstyle(section) {
+      if (section != null) {
+        return "color:green";
+      }
+    },
+    setValueStyle(value) {
+      if (typeof value ==='undefined' || value===null || value==="") {
+        return "color:red";
+      }
+    },
+    generateReport() {
+      let _this = this;
 
+      let reportId = _this.reportId;
+      if (reportId) {
+        _this.processLoading = true;
+        setTimeout(() => {
+          _this.$api.reportMain.generateReport(reportId).then(res => {
+            if (res.code === 200) {
+              _this.processLoading = false;
+              _this.$notify({
+                title: '成功',
+                message: '报告已生成,请返回上级页面预览或下载。',
+                type: 'success',
+                duration: 2000
+              })
+            }
+          }).catch(() => {
+            _this.processLoading = false;
+          })
+        }, 3500)
+      }
     },
-    data() {
-      return {
-        listLoading: true,
-        activeName:null,
-        tricks:[],
+    addCustomNoun() {
+      //将二维数组转一维
+      if (this.customNouns.length>0){
+        this.nouns.custom = this.customNouns.reduce(function(a,b){
+          return a.concat(b);
+        })
       }
-  
+      this.nouns.custom.push(this.newNoun);
+      let arr = JSON.parse(JSON.stringify(this.reportMain.reportNouns.custom))
+      this.customNouns = this.arrChange(JSON.parse(JSON.stringify(arr)))
     },
-  
-    created(){
-
-    },
-    methods: {
-        getReportSectionList(headlineId){
-            const that = this;
-            that.listLoading = true
-            that.$api.reportSection.getReportSectionList(headlineId).then(res=>{
-                if (res.code === 200){
-                    that.tricks = res.data;
-                    that.listLoading = false;
-                }
-            }).catch(()=>{
-                that.listLoading = false;
+    arrChange(arr) {
+      let xArry = [];
+      while (arr.length > 0) {
+        xArry.push(arr.splice(0, 3));
+      }
+      return xArry;
+    },
+    saveNouns(){
+      this.listLoading = true;
+      this.nouns.common = this.commonNouns.reduce(function(a,b){
+        return a.concat(b);
+      })
+      if (this.customNouns.length>0){
+        this.nouns.custom = this.customNouns.reduce(function(a,b){
+        return a.concat(b);
+      })
+      }
+      this.reportMain.reportNouns = this.nouns;
+      //需不需要判空逻辑
+      this.$api.reportMain.edit(this.reportMain).then(res =>{
+        if (res.code === 200) {
+            this.$notify({
+              title: '成功',
+              message: '名称配置已更新',
+              type: 'success',
+              duration: 2000
             })
-        },
-        pickHeadline1(tab,event){
-            let tree = this.headlineTree;
-            let name = tab.name;
-            let pickedNode = tree.find(t=> t.id.toString() === name )
-            if (pickedNode.children.length>0){
-                this.activeName = pickedNode.children[0].id.toString();
-                this.getReportSectionList(pickedNode.children[0].id);
-
-            }else{
-                this.getReportSectionList(name);
+            this.listLoading = false;
+          } else {
+            this.$notify({
+              title: '错误',
+              message: '操作失败,请联系管理员',
+              type: 'error',
+              duration: 2000
+            })
+            this.listLoading = false;
+          }
+      }).catch(() => {
+          this.listLoading = false;
+        })
+    },
+    check(event){
+      event.stopPropagation();
+      //检查是否为空值
+      let prevElement = event.currentTarget.previousElementSibling
+      if (prevElement.innerHTML==='中文含义' || prevElement.innerHTML==='替换值' ){
+        if (event.target.value ===null || event.target.value ===""){
+        prevElement.style.color = "red";
+        }else{
+          prevElement.style.color = "rgb(144, 147, 153)";
+        }
+      }
+     
+      //检查是否有重复的placeholder
+
+      if(prevElement.innerHTML==='占位符' || prevElement.innerHTML==='占位符有重复'){
+        let common = this.commonNouns.reduce(function(a,b){
+            return a.concat(b);
+          })
+          let custom = [];
+          if (this.customNouns.length>0){
+            custom = this.customNouns.reduce(function(a,b){
+            return a.concat(b);
+          })}
+          let all = common.concat(custom)
+          let newArray =  Array.from(all, ({placeholder}) => placeholder).filter(item => item !== null);
+          if (this.isRepeat(newArray) === event.target.value){
+            this.ableAdd = true;
+            prevElement.innerHTML = "占位符有重复"
+            prevElement.style.color = "red";
+          }else{
+            this.ableAdd = false;
+            prevElement.innerHTML = "占位符"
+            prevElement.style.color = "rgb(144, 147, 153)";
+          }
+          if (event.target.value ===null || event.target.value ==="" ||this.isRepeat(newArray)=== event.target.value){
+            prevElement.style.color = "red";
+          }else{
+            prevElement.style.color = "rgb(144, 147, 153)";
+          }
+      }
+      
+    },
+    getNouns(){
+      this.listLoading = true;
+      this.$api.reportMain.detail(this.reportId).then(res =>{
+      if (res.code === 200){
+          this.reportMain = res.data;
+          this.nouns = this.reportMain.reportNouns;
+          if (this.nouns.common!=null && this.nouns.common.length>0){
+            this.commonNouns = this.arrChange(JSON.parse(JSON.stringify(this.nouns.common)));
+          }
+          
+          if (typeof this.nouns.custom !='undefined' && this.nouns.custom !=null){
+            this.customNouns = this.arrChange(JSON.parse(JSON.stringify(this.nouns.custom)))
+          }else{
+            this.nouns.custom = [];
+          }
+          
+      }
+      this.listLoading = false;
+    }).catch(()=>{
+      this.listLoading = false;
+    })
+    },
+    deleteCard(card){
+      this.nouns.custom = this.customNouns.reduce(function(a,b){
+        return a.concat(b);
+      })
+      for(let n in this.nouns.custom){
+          if (this.nouns.custom[n].placeholder === card.placeholder){
+            this.nouns.custom.splice(this.nouns.custom.indexOf(this.nouns.custom[n]),1)
+            this.reportMain.reportNouns.custom = this.nouns.custom;
+            let arr = JSON.parse(JSON.stringify(this.reportMain.reportNouns.custom))
+            this.customNouns = this.arrChange(JSON.parse(JSON.stringify(arr)))
+            break;
+          }
+      }
+    },
+    isRepeat(arr){
+      var hash = {};
+      for(var i in arr) {
+        if(hash[arr[i]])
+          return arr[i];
+          hash[arr[i]] = true;
+        }
+      return false;
+    },
+    openTableDialog(headlineName){
+        this.dialogVisible =true;
+        this.dialogName = headlineName;
+        let headlineId = this.activeNode.id;
+        this.$api.reportSection.structure(headlineId).then(res=>{
+          if (res.code === 200){
+              this.inputData = res.data;
+        }
+      })
+    },
+    addTableData(tableData,tableHead){
+      let item = new Object();
+      for (let index in tableHead){
+        Object.defineProperty(item,tableHead[index].prop,{value:null,enumerable:true,writable:true,configurable:true});
+      }
+      tableData.push(item)
+    },
+    cleanTableData(index){
+      this.inputData.inputTableData[index].tableData = [];
+    },
+    saveTableData(){
+      this.listLoading = true;
+      for (let tableIndex in this.inputData.inputTableData){
+        let tableDatas = this.inputData.inputTableData[tableIndex].tableData;
+        let tableNo = this.inputData.inputTableData[tableIndex].tableNo;
+        for (let dataIndex in tableDatas){
+          for (let key in tableDatas[dataIndex]){
+            if (!tableDatas[dataIndex][key]){
+              this.$message.error('表格参数还有未填项!');
+                return;
             }
-        },
-        pickHeadline2(tab,event){
-            let name = tab.name;
-            this.getReportSectionList(name);
+          }
         }
+        let table = {"tableNo":tableNo,"data":tableDatas}
+        this.calculateData.calculateDataDTO.tableData.push(table)
+      }
+      for (let p in this.inputData.params){
+        for (let key in this.inputData.params[p]){
+              if (!this.inputData.params[p][key]){
+                this.$message.error('固定参数还有未填项!');
+                return;
+              }
+          }
+      }
+      this.calculateData.action = this.activeNode.action;
+      this.calculateData.calculateDataDTO.sectionId = this.activeNode.sectionId
+      this.calculateData.calculateDataDTO.params = this.inputData.params;
+      this.calculateData.jsonString = JSON.stringify(this.calculateData.calculateDataDTO);
+      this.calculateData.calculateDataDTO = null;
+      console.log(this.calculateData)
+      this.$api.reportSection.calculate(this.calculateData).then(res =>{
+        if (res.code === 200){
+          this.$notify({
+              title: '成功',
+              message: '计算结果已生成',
+              type: 'success',
+              duration: 2000
+            })
+            this.resetTableData();
+            this.getHeadlineTree();
+            this.listLoading = false;
+        }else {
+            this.$notify({
+              title: '错误',
+              message: '操作失败,请检查计算参数',
+              type: 'error',
+              duration: 2000
+            })
+            //this.resetTableData();
+            this.listLoading = false;
+          }
+      }).catch(() => {
+          this.listLoading = false;
+        })
+    },
+    resetTableData(){
+      this.calculateData = 
+              {action:null,
+                calculateDataDTO:{
+                  sectionId:null,
+                  tableData:[],
+                  params:[]
+                },
+                jsonString:null
+              }
+      this.inputData = {};
+    },
+
+    getHeadlineTree(){
+      if (this.reportId){
+        this.$api.reportMain.getMainTree(this.reportId).then(res=>{
+          if (res.code === 200){
+              this.headlineTree = res.data;
+          }
+        })
+      }
     }
   }
-  </script>
+}
+</script>
   
-  <style lang="css">
-  .report {
+<style lang="css" scoped>
+.report {
+  width: 100%;
+}
+
+.section-area {
+  height: 785px;
+  width: 800px;
+  overflow-y: scroll;
+  border: 1px rgb(212, 212, 212) solid;
+  border-radius: 4px;
+}
+
+.editor-area {
+  height: 830px;
+  width: 830px;
+  overflow-y: scroll;
+}
+
+.null-area {
+  height: 785px;
+  width: 800px;
+}
+
+.generator {
+  display: flex;
+  position: absolute;
+  top: -30px;
+  right: 10px;
+}
+
+.loader {
+  width: 100%;
+  height: 10px;
+  border-radius: 2px;
+  background-color: rgba(252, 251, 251, 0.2);
+  /* position: absolute; */
+
+}
+
+.loader::before {
+  content: "";
+  position: absolute;
+  background-color: rgb(9, 188, 9);
+  width: 0%;
+  height: 10px;
+  border-radius: 2px;
+  animation: load 3.5s ease-in-out infinite;
+  box-shadow: rgb(9, 188, 9) 0px 2px 29px 0px;
+}
+
+
+@keyframes load {
+  50% {
     width: 100%;
   }
-  </style>
+
+  100% {
+    right: 0;
+    left: unset;
+  }
+}
+
+.nouns-area {
+  width: 100%;
+
+}
+.nounsInfo{
+  font-size: small;
+  color: red;
+  text-align: center;
+}
+.nounsInput{
+  height: 32px; 
+  width: 175px;
+  border: rgb(220, 223, 230) 1px solid;
+  border-radius: 3px;
+  font-size: small;
+  color: gray;
+  padding-left: 5px;
+}
+
+.cardHover:hover{
+	z-index: 2;
+	box-shadow: 0 30px 30px rgba(0,0,0,.1);
+  background-color: rgb(244,244,245)
+ }
+ .nouns-del {
+  z-index: 2;
+  float: right; 
+  color: gray;
+ }
+
+ .nouns-del:hover{
+  cursor: pointer;
+ }
+
+/*选中样式*/
+::v-deep .el-tabs__item.is-active {
+  font-weight: bold;
+  /* background-color: #e1251b; */
+}
+.jisuan-icon{
+  width: 25px;
+  height: 25px;
+  margin-bottom: -8px;
+}
+
+</style>

+ 14 - 4
src/components/YUeditor/index.vue

@@ -2,8 +2,8 @@
 2019.3.05 姚政伟 创建
 -->
 <template>
-  <div style="line-height:normal;">
-    <script :id="id" type="text/plain" />
+  <div style="line-height:normal">
+    <script :id="id" type="text/plain"></script>
   </div>
 </template>
 
@@ -23,6 +23,10 @@
       },
       config: {
         type: Object
+      },
+      unique: {
+        type: Number,
+        required: false
       }
     },
     data() {
@@ -37,10 +41,15 @@
     },
     computed: {
       id() {
-        const ram = Math.random();
-        return 'editor' + ram
+        if (typeof this.unique != 'undefined' && this.unique!=null){
+          return 'editor' + this.unique
+        }else{
+          const ram = Math.random();
+          return 'editor' + ram
+        }
       }
     },
+
     watch: {
       'content': function (value) {
         const that = this;
@@ -56,6 +65,7 @@
         }
       }
     },
+
     mounted() {
       const _this = this;
       _this.editor = UE.getEditor(this.id, {..._this.defaultConfig, ..._this.config}); // 初始化UE

+ 6 - 0
src/router/urlMap.js

@@ -64,6 +64,9 @@ import _views_gis_visited from '@/views/gis/visited'
 import _views_brokerage_tech_deduction from '@/views/brokerage/deductionTech'
 import _views_report_land_risk from '@/views/reports/land/risk'
 import _views_report_section_template from '@/views/reports/section/list'
+import _views_report_main_edit from '@/views/reports/CommonEditReport'
+import _views_report_land_city_base from '@/views/reports/land/cityBasePrice'
+import _views_report_city_base_edit from '@/views/reports/CommonEditReport'
 
 export default {
   _views_set_menu,
@@ -117,4 +120,7 @@ export default {
   _views_brokerage_tech_deduction,
   _views_report_land_risk,
   _views_report_section_template,
+  _views_report_main_edit,
+  _views_report_land_city_base,
+  _views_report_city_base_edit
 }

+ 54 - 0
src/views/reports/CommonEditReport.vue

@@ -0,0 +1,54 @@
+
+<template>
+  <div>
+      <ReportEditor :headlineTree="headlineTree" />
+  </div>
+</template>
+
+<script>
+import ReportEditor from "@/components/ReportEditor"
+export default {
+  name:"CommonEditReport",
+  components: {
+    ReportEditor
+  },
+
+  data() {
+    return {
+      listLoading: true,
+      reportId:this.$route.query.id,
+      headlineTree:[]
+    }
+
+  },
+
+  created(){
+    this.getHeadlineTree();
+  },
+  methods: {
+
+    getHeadlineTree(){
+      if (this.reportId){
+        this.listLoading = true
+        this.$api.reportMain.getMainTree(this.reportId).then(res=>{
+          if (res.code === 200){
+              this.headlineTree = res.data;
+          }else{
+            setTimeout(() => {
+              this.listLoading = false
+          }, 200)
+          }
+        }).catch(() => {
+            this.listLoading = false
+          })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="css">
+.report {
+  width: 100%;
+}
+</style>

+ 285 - 0
src/views/reports/land/cityBasePrice.vue

@@ -0,0 +1,285 @@
+<template>
+    <div class="app-container">
+        <div class="title-container">
+            <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
+        </div>
+
+        <y-page-list-layout :page-list="pageData" :page-para="listQuery" :get-page-list="getList">
+            <template slot="left">
+                <el-button class-name="filter-item" type="danger" size="mini" round style="float: left"
+                    @click="dialogVisible = true">创建报告</el-button>
+                <el-input v-model="listQuery.title" placeholder="报告号" clearable
+                    style="margin-left: 20px; width: 220px;float: left;">
+                </el-input>
+                <el-input v-model="listQuery.creator" placeholder="创建人" clearable
+                    style="margin-left: 20px; width: 220px;float: left;">
+                </el-input>
+                <el-input v-model="listQuery.checker" placeholder="审核人" clearable
+                    style="margin-left: 20px; width: 220px;float: left;">
+                </el-input>
+                <el-select v-model="listQuery.status" filterable style="margin-left: 20px; width: 120px;float: left;" 
+                placeholder="请选择" clearable>
+                    <el-option
+                        v-for="(item,index) in statuses"
+                        :key="index"
+                        :label="item"
+                        :value="item"
+                    />
+                </el-select>
+                <el-button class="filter-item" style="margin-left: 10px;float: left;" type="primary" @click="searchList"
+                    round>搜索
+                </el-button>
+                <el-button class="filter-item" style="float: left;" round type="warning" @click="resetSearch()">重置
+                </el-button>
+            </template>
+            <parentTable v-loading="listLoading" :data="pageData.records" slot="table" style="width: 100%;">
+                <el-table-column label="报告号" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.title }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="报告类型" align="center" width="250">
+                    <template slot-scope="{row}">
+                        <span>{{ row.reportType==='LAND_CITY_PRICE'?'城区土地定级与基准地价技术报告':'' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="报告状态" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{row.status }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建人" align="center" width="180">
+                    <template slot-scope="{row}">
+                        <span>{{ row.creator }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="审核人" align="center" width="180">
+                    <template slot-scope="{row}">
+                        <span>{{ row.checker!=null?row.checker:'-' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="报告文档" align="center">
+                    <template slot-scope="{row}">
+                        <el-button v-if="row.url" type="success" plain round
+                            @click="downloadContract(row.url)">下载</el-button>
+                        <el-button v-else plain round disabled>下载</el-button>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建时间" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.created }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" align="center" width="250">
+                    <template slot-scope="{row}">
+                        <PermissionButton menu-code="_views_report_city_base_edit" class-name="filter-item" name=""
+                            type="primary" round size="mini" @click="edit(row.id)" :page-jump="true" :page-query="{ id: row.id,title:row.title }"  />
+                        <!-- <PermissionButton menu-code="_views_report_editor" class-name="filter-item" name=""
+                        type="warning" round size="mini" @click="documentEditor(row)"  /> -->
+                        <PermissionButton menu-code="_views_report_city_base_remove" class-name="filter-item" name=""
+                            type="danger" round size="mini" @click="deleteInfo(row.id)" />
+                    </template>
+                </el-table-column>
+            </parentTable>
+        </y-page-list-layout>
+        <el-dialog :visible.sync="dialogVisible" center @closed="closeDialog" width="25%" >
+            <div style="height: auto;">
+                <!-- <el-select style="width: 400px;" v-model="reportType" placeholder="请选择你要创建的报告类型">
+                <el-option v-for="(r, id) in reportTypes" :key="r.id" :label="r.headline" :value="r.id" />
+                </el-select> -->
+                <el-input placeholder="请输入报告主体名称" v-model="newObject.mainObject" ></el-input>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">取 消</el-button>
+                <el-button type="primary" @click="createReport" :disabled="newObject.mainObject==null">创 建</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import YPageListLayout from '@/components/YPageListLayout'
+import Breadcrumb from '@/components/Breadcrumb'
+import PermissionButton from '@/components/PermissionButton/PermissionButton'
+
+export default {
+    name: 'risk',
+    components: {
+        Breadcrumb,
+        YPageListLayout,
+        PermissionButton,
+    },
+    data() {
+        return {
+            dialogVisible: false,
+            pageData: { records: [] },
+            total: 20,
+            listLoading: true,
+            listQuery: {
+                page: 1,
+                size: 10,
+                descs: 'id',
+                reportType:'LAND_CITY_PRICE'
+            },
+            reportTypes: [],
+            reportType: null,
+            statuses:["编辑中","审核中","审核通过","审核拒绝","已完成","已归档"],
+            mainObject:null,
+            newObject:{
+                mainObject:null,
+                reportType:"LAND_CITY_PRICE",
+                prefix:"BASE"
+            }
+        }
+    },
+    created() {
+        this.getList();
+        this.getReportTypes();
+    },
+    methods: {
+        resetSearch() {
+            this.$router.push({ query: {} });
+            this.listQuery = {
+                current: 1,
+                size: 10,
+                descs: 'id',
+                reportType:'LAND_CITY_PRICE'
+            }
+            this.getList()
+        },
+        searchList() {
+            // 重置分页
+            this.listQuery.page = 1
+            this.listQuery.size = 20
+            this.getList()
+        },
+        getList() {
+            const that = this
+            this.listLoading = true
+            this.$api.reportMain.list(Object.assign({}, that.listQuery)).then((res) => {
+                that.pageData = res.data;
+                setTimeout(() => {
+                    that.listLoading = false
+                }, 200)
+            })
+                .catch(() => {
+                    that.listLoading = false
+                })
+        },
+        deleteInfo(id) {
+            const that = this
+            that.$confirm('请确认是否删除该数据?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+                center: true
+            }).then(() => {
+                that.$api.reportMain.delete(id).then(data => {
+                    that.loading = false
+                    if (data.code === 200) {
+                        that.getList()
+                    } else {
+                        this.$message({
+                            type: 'error',
+                            message: data.msg
+                        })
+                    }
+                })
+            }).catch(() => {
+            })
+        },
+        createReport() {
+            let that = this;
+            that.$confirm('请确认报告类型是否正确?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+                center: true
+            }).then(() => {
+                that.$api.reportMain.add(this.newObject).then(data => {
+                    that.loading = false
+                    if (data.code === 200) {
+                        that.getList();
+                        that.dialogVisible = false;
+                        that.$notify({
+                            title: '成功',
+                            message: '创建报告成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+                    } else {
+                        that.$message({
+                            type: 'error',
+                            message: data.msg
+                        })
+                    }
+                })
+            }).catch(() => {
+            })
+        },
+        getReportTypes() {
+            this.$api.reportHeadline.getReportType().then(res => {
+                if (res.code === 200) {
+                    this.reportTypes = res.data;
+                }
+            })
+        },
+        closeDialog() {
+            this.reportType = null;
+        },
+        downloadContract(url) {
+            var a = document.createElement('a');
+            var event = new MouseEvent('click');
+            a.download = url;
+            a.href = url;//路径前拼上前缀,完整路径
+            a.dispatchEvent(event);
+        },
+        documentEditor(row) {
+            let routeUrl = this.$router.resolve({
+                path: "/document/window",
+                query: {key:row.reportKey,url:row.url,title:row.title}
+        });
+        window.open(routeUrl.href, '_blank');
+        },
+    },
+}
+</script>
+<style lang="scss" scoped>
+.right {
+    flex: 1;
+
+    .title {
+        font-size: 16px;
+        font-weight: 500;
+        color: rgba(51, 51, 51, 1);
+        line-height: 35px;
+        margin-bottom: 8px;
+    }
+
+    .menu-2-box {
+        display: flex;
+        flex-wrap: wrap;
+        width: 100%;
+    }
+
+    .menu-2-item {
+        display: flex;
+        align-items: center;
+        color: #656565;
+        font-size: 12px;
+        width: 230px;
+        height: 101px;
+        background: rgb(255, 185, 129);
+        border-radius: 3px;
+        padding-left: 20px;
+        margin-right: 10px;
+        margin-bottom: 10px;
+        cursor: pointer;
+        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+
+        .text {
+            margin-left: 16px;
+        }
+    }
+}
+</style>
+  

+ 272 - 46
src/views/reports/land/risk.vue

@@ -1,56 +1,282 @@
-
 <template>
-  <div>
-      <ReportEditor :headlineTree="headlineTree" />
-  </div>
-</template>
+    <div class="app-container">
+        <div class="title-container">
+            <breadcrumb id="breadcrumb-container" class="breadcrumb-container" />
+        </div>
 
+        <y-page-list-layout :page-list="pageData" :page-para="listQuery" :get-page-list="getList">
+            <template slot="left">
+                <el-button class-name="filter-item" type="danger" size="mini" round style="float: left"
+                    @click="createReport">创建报告</el-button>
+                <el-input v-model="listQuery.title" placeholder="报告号" clearable
+                    style="margin-left: 20px; width: 220px;float: left;">
+                </el-input>
+                <el-input v-model="listQuery.creator" placeholder="创建人" clearable
+                    style="margin-left: 20px; width: 220px;float: left;">
+                </el-input>
+                <el-input v-model="listQuery.checker" placeholder="审核人" clearable
+                    style="margin-left: 20px; width: 220px;float: left;">
+                </el-input>
+                <el-select v-model="listQuery.status" filterable style="margin-left: 20px; width: 120px;float: left;" 
+                placeholder="请选择" clearable>
+                    <el-option
+                        v-for="(item,index) in statuses"
+                        :key="index"
+                        :label="item"
+                        :value="item"
+                    />
+                </el-select>
+                <el-button class="filter-item" style="margin-left: 10px;float: left;" type="primary" @click="searchList"
+                    round>搜索
+                </el-button>
+                <el-button class="filter-item" style="float: left;" round type="warning" @click="resetSearch()">重置
+                </el-button>
+            </template>
+            <parentTable v-loading="listLoading" :data="pageData.records" slot="table" style="width: 100%;">
+                <el-table-column label="报告号" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.title }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="报告类型" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.reportType==='LAND_RISK_FTL'?'社会风险稳定性评价报告':'' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="报告状态" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{row.status }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建人" align="center" width="180">
+                    <template slot-scope="{row}">
+                        <span>{{ row.creator }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="审核人" align="center" width="180">
+                    <template slot-scope="{row}">
+                        <span>{{ row.checker!=null?row.checker:'-' }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="报告文档" align="center">
+                    <template slot-scope="{row}">
+                        <el-button v-if="row.url" type="success" plain round
+                            @click="downloadContract(row.url)">下载</el-button>
+                        <el-button v-else plain round disabled>下载</el-button>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建时间" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.created }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="操作" align="center" width="250">
+                    <template slot-scope="{row}">
+                        <PermissionButton menu-code="_views_report_main_edit" class-name="filter-item" name=""
+                            type="primary" round size="mini" @click="edit(row.id)" :page-jump="true" :page-query="{ id: row.id,title:row.title }"  />
+                        <!-- <PermissionButton menu-code="_views_report_editor" class-name="filter-item" name=""
+                        type="warning" round size="mini" @click="documentEditor(row)"  /> -->
+                        <PermissionButton menu-code="_views_report_main_remove" class-name="filter-item" name=""
+                            type="danger" round size="mini" @click="deleteInfo(row.id)" />
+                    </template>
+                </el-table-column>
+            </parentTable>
+        </y-page-list-layout>
+        <!-- <el-dialog :visible.sync="dialogVisible" center @closed="closeDialog" width="25%" >
+            <div style="height: auto;">
+                <el-select style="width: 400px;" v-model="reportType" placeholder="请选择你要创建的报告类型">
+                <el-option v-for="(r, id) in reportTypes" :key="r.id" :label="r.headline" :value="r.id" />
+            </el-select>
+            </div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">取 消</el-button>
+                <el-button type="primary" @click="createReport" :disabled="reportType==null">创 建</el-button>
+            </span>
+        </el-dialog> -->
+    </div>
+</template>
 <script>
-import ReportEditor from "@/components/ReportEditor"
+import YPageListLayout from '@/components/YPageListLayout'
+import Breadcrumb from '@/components/Breadcrumb'
+import PermissionButton from '@/components/PermissionButton/PermissionButton'
+
 export default {
-  components: {
-    ReportEditor
-  },
+    name: 'risk',
+    components: {
+        Breadcrumb,
+        YPageListLayout,
+        PermissionButton,
+    },
+    data() {
+        return {
+            dialogVisible: false,
+            pageData: { records: [] },
+            total: 20,
+            listLoading: true,
+            listQuery: {
+                page: 1,
+                size: 10,
+                descs: 'id',
+                reportType:'LAND_RISK_FTL'
+            },
+            reportTypes: [],
+            reportType: null,
+            statuses:["编辑中","审核中","审核通过","审核拒绝","已完成","已归档",],
+            newReport:{
+                "reportType": 'LAND_RISK_FTL',
+                "prefix":"RISK"
+            }
+        }
+    },
+    created() {
+        this.getList();
+        this.getReportTypes();
+    },
+    methods: {
+        resetSearch() {
+            this.$router.push({ query: {} });
+            this.listQuery = {
+                current: 1,
+                size: 10,
+                descs: 'id',
+                reportType:'LAND_RISK_FTL'
+            }
+            this.getList()
+        },
+        searchList() {
+            // 重置分页
+            this.listQuery.page = 1
+            this.listQuery.size = 20
+            this.getList()
+        },
+        getList() {
+            const that = this
+            this.listLoading = true
+            this.$api.reportMain.list(Object.assign({}, that.listQuery)).then((res) => {
+                that.pageData = res.data;
+                setTimeout(() => {
+                    that.listLoading = false
+                }, 200)
+            })
+                .catch(() => {
+                    that.listLoading = false
+                })
+        },
+        deleteInfo(id) {
+            const that = this
+            that.$confirm('请确认是否删除该数据?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+                center: true
+            }).then(() => {
+                that.$api.reportMain.delete(id).then(data => {
+                    that.loading = false
+                    if (data.code === 200) {
+                        that.getList()
+                    } else {
+                        this.$message({
+                            type: 'error',
+                            message: data.msg
+                        })
+                    }
+                })
+            }).catch(() => {
+            })
+        },
+        createReport() {
+            let that = this;
+            that.$confirm('请确认报告类型是否正确?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+                center: true
+            }).then(() => {
+                that.$api.reportMain.add(this.newReport).then(data => {
+                    that.loading = false
+                    if (data.code === 200) {
+                        that.getList();
+                        that.dialogVisible = false;
+                        that.$notify({
+                            title: '成功',
+                            message: '创建报告成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+                    } else {
+                        that.$message({
+                            type: 'error',
+                            message: data.msg
+                        })
+                    }
+                })
+            }).catch(() => {
+            })
+        },
+        getReportTypes() {
+            this.$api.reportHeadline.getReportType().then(res => {
+                if (res.code === 200) {
+                    this.reportTypes = res.data;
+                }
+            })
+        },
+        closeDialog() {
+            this.reportType = null;
+        },
+        downloadContract(url) {
+            var a = document.createElement('a');
+            var event = new MouseEvent('click');
+            a.download = url;
+            a.href = url;//路径前拼上前缀,完整路径
+            a.dispatchEvent(event);
+        },
+        documentEditor(row) {
+            let routeUrl = this.$router.resolve({
+                path: "/document/window",
+                query: {key:row.reportKey,url:row.url,title:row.title}
+        });
+        window.open(routeUrl.href, '_blank');
+        },
+    },
+}
+</script>
+<style lang="scss" scoped>
+.right {
+    flex: 1;
 
-  data() {
-    return {
-      listLoading: true,
-     
-      headlineTree:[]
+    .title {
+        font-size: 16px;
+        font-weight: 500;
+        color: rgba(51, 51, 51, 1);
+        line-height: 35px;
+        margin-bottom: 8px;
     }
 
-  },
-
-  created(){
-    this.getHeadlineTree();
-  },
-  methods: {
-    documentEditor() {
-      let routeUrl = this.$router.resolve({
-        path: "/document/window",
-        query: {}
-      });
-      window.open(routeUrl.href, '_blank');
-    },
-    getHeadlineTree(){
-        this.$api.reportHeadline.getHeadlineTree(1).then(res=>{
-          if (res.code === 200){
-              this.headlineTree = res.data;
-          }else{
-            setTimeout(() => {
-            that.listLoading = false
-          }, 200)
-          }
-        }).catch(() => {
-            that.listLoading = false
-          })
+    .menu-2-box {
+        display: flex;
+        flex-wrap: wrap;
+        width: 100%;
     }
-  }
-}
-</script>
 
-<style lang="css">
-.report {
-  width: 100%;
+    .menu-2-item {
+        display: flex;
+        align-items: center;
+        color: #656565;
+        font-size: 12px;
+        width: 230px;
+        height: 101px;
+        background: rgb(255, 185, 129);
+        border-radius: 3px;
+        padding-left: 20px;
+        margin-right: 10px;
+        margin-bottom: 10px;
+        cursor: pointer;
+        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+
+        .text {
+            margin-left: 16px;
+        }
+    }
 }
-</style>
+</style>
+  

+ 0 - 540
src/views/reports/section/detail.vue

@@ -1,540 +0,0 @@
-<template>
-    <div class="app-container">
-      <div class="title-container">
-        <breadcrumb id="breadcrumb-container" class="breadcrumb-container"/>
-      </div>
-      <y-detail-page-layout @save="handleCreate" :edit-status="true" v-loading="vLoading" element-loading-text="处理中。。。" :list-query="listQuery">
-        <div style="padding-top: 30px;">
-          <el-tabs v-model="activeName">
-            <el-tab-pane label="项目信息" name="first">
-              <el-form ref="postForm" :model="postForm" class="form-container">
-                <div class="createPost-main-container">
-                  <div class="postInfo-container">
-                    <div style="margin-bottom: 30px">
-                      <h3 class="title">
-                        <div class="avatar-wrapper icon-title">基</div>
-                        <div class="icon-info">基本信息</div>
-                      </h3>
-                    </div>
-                    <el-row>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="项目名称:"
-                          prop="name"
-                          :rules="{required: true, message: '项目名称不能为空', trigger: 'blur'}"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input v-model="postForm.name" class="filter-item"/>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="归属单位:"
-                          prop="belongTo"
-                          :rules="{required: true, message: '归属单位不能为空', trigger: 'blur'}"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-select
-                            v-model="postForm.belongTo"
-                            placeholder="请选择"
-                            clearable
-                            filterable
-                            class="filter-item"
-                            style=" width: 100%"
-                            @change="changePrefix"
-                          >
-                            <el-option key="1" label="大友" value="DY"/>
-                            <el-option key="2" label="泰济诚" value="TJC"/>
-                          </el-select>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="项目编号:"
-                          prop="oaNo"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input v-model="postForm.oaNo" class="filter-item" :placeholder="tip" :disabled="oaNoDisable" :readonly="oaNoReadonly">
-                            <template slot="prepend">{{postForm.belongTo}}</template>
-                          </el-input>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="事业部流水号:"
-                          prop="businessNo"
-                          label-width="150px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input :value="postForm.businessNo" class="filter-item" placeholder="系统自动生成" :disabled="true" readonly/>
-                        </el-form-item>
-                      </el-col>
-                    </el-row>
-                    <el-row>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="项目类型:"
-                          prop="cate"
-                          :rules="{required: true, message: '项目类型不能为空', trigger: 'blur'}"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-select
-                            v-model="postForm.cate"
-                            placeholder="请选择"
-                            clearable
-                            filterable
-                            class="filter-item"
-                            style=" width: 100%"
-                          >
-                            <el-option v-for="item in cateList" :key="item.id" :label="item.name" :value="item.id"/>
-                          </el-select>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="客户名字:"
-                          prop="customerId"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-select v-model="customerInfo" filterable class="filter-item" style="float: left;width: 100%;" placeholder="请选择" @change="getCustomerDetail">
-                            <el-option
-                              v-for="item in customerOptions"
-                              :key="item.id"
-                              :label="item.name"
-                              :value="[item.id,item.name]"
-                            />
-                          </el-select>
-                          <el-select v-show="false" v-model="postForm.clientName" />
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="委托单位:"
-                          prop="clientUnit"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input :value="postForm.clientUnit" class="filter-item" readonly disabled/>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="联系方式:"
-                          prop="mobile"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input :value="postForm.mobile" class="filter-item" readonly disabled />
-                        </el-form-item>
-                      </el-col>
-                    </el-row>
-                    <el-row>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="客户经理:"
-                          prop="clientManager"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input :value="postForm.clientManager" class="filter-item" readonly disabled/>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="业务来源:"
-                          prop="businessSource"
-                          :rules="{required: true, message: '业务来源不能为空', trigger: 'blur'}"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-select
-                            v-model="postForm.businessSource"
-                            placeholder="请选择"
-                            clearable
-                            filterable
-                            class="filter-item"
-                            style=" width: 100%"
-                          >
-                            <el-option v-for="item in businessSourceList" :key="item.id" :label="item.name" :value="item.id"/>
-                          </el-select>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="项目负责人:"
-                          prop="skiller"
-                          :rules="{required: true, message: '项目负责人不能为空', trigger: 'blur'}"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input v-model="postForm.skiller" class="filter-item"/>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="签订日期:"
-                          prop="signDate"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-date-picker
-                            v-model="postForm.signDate"
-                            type="date"
-                            value-format="yyyy-MM-dd"
-                            style="width: 100%"
-                            placeholder="选择日期"
-                          />
-                        </el-form-item>
-                      </el-col>
-                    </el-row>
-                    <el-row>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="付款类型:"
-                          prop="paymentMethod"
-                          :rules="{required: true, message: '付款方式不能为空', trigger: 'blur'}"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-select
-                            v-model="postForm.paymentMethod"
-                            placeholder="请选择"
-                            clearable
-                            filterable
-                            class="filter-item"
-                            style=" width: 100%"
-                          >
-                            <el-option key="1" label="一次性付款" value="一次性付款"/>
-                            <el-option key="2" label="分期付款" value="分期付款"/>
-                          </el-select>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="合同金额:"
-                          prop="amount"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-input v-model.number="postForm.amount" class="filter-item" type="number">
-                            <i slot="suffix" style="font-size:normal;margin-right: 10px;line-height: 30px">元</i>
-                          </el-input>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item
-                          label="所属部门:"
-                          prop="departmentId"
-                          :rules="{required: true, message: '所属部门不能为空', trigger: 'blur'}"
-                          label-width="120px"
-                          class="postInfo-container-item"
-                        >
-                          <el-select
-                            v-model="postForm.departmentId"
-                            placeholder="请选择"
-                            clearable
-                            filterable
-                            class="filter-item"
-                            style=" width: 100%"
-                          >
-                            <el-option
-                              v-for="item in departmentsOptions"
-                              :key="item.id"
-                              :label="item.name"
-                              :value="item.id"
-                            />
-                          </el-select>
-                        </el-form-item>
-                      </el-col>
-                      <el-col :xs="24" :sm="12" :lg="6" :span="6">
-                        <el-form-item   label-width="120px" v-model="postForm.contractUrl" style=" width: 100%">
-                          <el-upload
-                            action="/api/upload"
-                            :limit="1" :on-success="changeres" :on-exceed="handleExceed" :on-preview="handleAttachmentPreview"
-                            :file-list="fileList" :before-remove="beforeRemove">
-                            <el-button type="primary">上传电子合同<i class="el-icon-upload el-icon--right"></i></el-button>
-                          </el-upload>
-                        </el-form-item>
-                      </el-col>
-                    </el-row>
-                    <div style="margin-top:20px;width:100%;height:1px;background:rgba(242,242,242,1);"/>
-                    <div style="margin-bottom: 30px">
-                      <h3 class="title">
-                        <div class="avatar-wrapper icon-title" style="background:rgba(255,175,41,1)">人</div>
-                        <div class="icon-info">
-                          人员配置
-                          <span style="color: orangered">*</span>
-                        </div>
-                      </h3>
-                    </div>
-                  </div>
-                  <el-transfer
-                    filterable
-                    :filter-method="filterMethod"
-                    filter-placeholder="请输入姓名"
-                    v-model="userIds"
-                    :titles="['所有员工', '所选员工']"
-                    :data="users"
-                  >
-                  </el-transfer>
-                </div>
-              </el-form>
-            </el-tab-pane>
-          </el-tabs>
-        </div>
-      </y-detail-page-layout>
-    </div>
-  </template>
-  <script>
-    import Breadcrumb from '@/components/Breadcrumb'
-    import YDetailPageLayout from '@/components/YDetailPageLayout'
-  
-    export default {
-      name: 'itemDetail',
-      components: {
-        Breadcrumb,
-        YDetailPageLayout,
-      },
-      data() {
-        return {
-          type: 'detail',
-          postForm: {
-            departmentId:'',
-            clientUnit:'',
-            mobile:'',
-            userId: this.$store.getters.userInfo.id,
-            clientManager:this.$store.getters.userInfo.name,
-            oaNo:''
-          },
-          dataId: this.$route.query.id,
-          activeName: 'first',
-          vLoading: false,
-          users:[],
-          listQuery:null,
-          userIds: [],
-          filterMethod(query, item) {
-            return item.label.indexOf(query) > -1;
-          },
-          departmentsOptions:[],
-          contractName:'',
-          fileList:[],
-          customerOptions:[],
-          customerInfo:[],
-          tip:null,
-          oaNoDisable:false,
-          oaNoReadonly:false,
-          cateList:[],
-          businessSourceList:[]
-        }
-      },
-      created() {
-        this.listQuery = this.$route.query.listQuery;
-        this.getAllUser();
-        this.getDepartment();
-        this.getDetail();
-        this.getCustomerSelect();
-        this.getCateList();
-        this.getBusinessSourceList();
-      },
-      methods: {
-  
-        getCateList(){
-          this.$api.dictData.simpleType("项目类型").then(res => {
-            this.cateList = res.data
-          })
-        },
-        getBusinessSourceList(){
-          this.$api.dictData.simpleType("业务来源").then(res => {
-            this.businessSourceList = res.data
-          })
-        },
-        getCustomerDetail(){
-          this.postForm.clientName = this.customerInfo[1];
-          this.postForm.customerId = this.customerInfo[0];
-          this.$api.customer.detail(this.postForm.customerId).then(res =>{
-            this.postForm.clientUnit = res.data.department;
-            this.postForm.mobile = res.data.mobile;
-          })
-        },
-        getCustomerSelect() {
-          this.$api.customer.simpleAll().then(res => {
-            this.customerOptions = res.data
-          })
-        }, handleAttachmentPreview(file){
-          window.open(file.url)
-        },
-        handleExceed(files, fileList) {
-          this.$message.warning(`当前限制选择 1个文件,本次选择了 ${files.length} 个文件`);
-        },
-        // 上传
-        changeres(res, file) {
-          if (res.code === 200){
-            this.postForm.contractUrl = res.data.url;
-            const arr = res.data.url.split("-");
-            this.contractName = arr[1];
-          }else {
-            this.$notify({
-              title: '错误',
-              message: '合同上传失败',
-              type: 'error',
-              duration: 2000
-            });
-            return;
-          }
-        },
-        changePrefix(e){
-          this.postForm.belongTo = e;
-          this.postForm.oaNo = '';
-          if (e === 'TJC'){
-            this.tip = '事业部流水号';
-            this.oaNoDisable = true;
-            this.oaNoReadonly = true;
-          }
-          if (e === 'DY'){
-            this.tip = null;
-            this.oaNoDisable = false;
-            this.oaNoReadonly = false;
-          }
-          this.postForm.oaNo = null;
-        },
-        getZero(num) {
-          // 单数前面加0
-          if (parseInt(num) < 10) {
-            num = '0' + num;
-          }
-          return num;
-        },
-        getAllUser() {
-          const that = this;
-          that.$api.user.simpleAll().then(data => {
-            if (data.code === 200) {
-              this.users = data.data.map((item) => {
-                return {
-                  key: item.id,
-                  label: item.name,
-                };
-              });
-            } else {
-              this.$message({
-                type: 'error',
-                message: data.msg
-              })
-            }
-          })
-        },
-        getDepartment(){
-          this.$api.department.simpleAll().then(res => {
-            this.departmentsOptions = res.data
-          })
-        },
-        getDetail() {
-          if (this.dataId) {
-            this.$api.item.detail(this.dataId).then(res => {
-              this.postForm = res.data;
-              this.customerInfo = res.data.clientName;
-              if (res.data.contractUrl){
-                const arr = res.data.contractUrl.split("-");
-                this.contractName = arr[1];
-                this.fileList.push({name: this.contractName, url:this.postForm.contractUrl});
-              }
-              this.userIds = res.data.userIds.map(item => {
-                return item
-              })
-            });
-          }
-        },
-        handleCreate() {
-          if (!this.postForm.customerId){
-              this.$notify({
-                title: '错误',
-                message: '客户名字不能为空',
-                type: 'error',
-                duration: 2000
-              });
-              return;
-          }
-          if (this.userIds.length==0){
-            this.$notify({
-              title: '错误',
-              message: '人员配置不能为空',
-              type: 'error',
-              duration: 2000
-            });
-            return;
-          }
-          if (this.postForm.contractUrl){
-            const date = new Date();
-            this.postForm.uploadDate = date.getFullYear() + "-" + (this.getZero(date.getMonth() + 1)) + "-" + this.getZero((date.getDate()));
-          }else {
-            this.postForm.uploadDate = null;
-          }
-          this.$refs.postForm.validate(valid => {
-            if (valid) {
-              if (this.dataId) {
-                this.$api.item.edit(Object.assign({}, this.postForm, {
-                  userIds: this.userIds.map(item => { return item }),
-                })).then(res => {
-                  if (res.code === 200) {
-                    this.$notify({
-                      title: '成功',
-                      message: '保存成功',
-                      type: 'success',
-                      duration: 2000
-                    });
-                    const back = this.$route.query.back;
-                    if (back) {
-                      this.$router.push(back)
-                    }
-                    this.initData();
-                    this.vLoading = false
-                  }
-                }).catch(() => {
-                  this.vLoading = false
-                })
-              } else {
-                this.$api.item.add(Object.assign({}, this.postForm, {
-                  userIds: this.userIds.map(item => { return item }),
-                })).then(res => {
-                  if (res.code === 200) {
-                    this.$notify({
-                      title: '成功',
-                      message: '新增成功',
-                      type: 'success',
-                      duration: 2000
-                    });
-                    const back = this.$route.query.back;
-                    if (back) {
-                      this.$router.push(back)
-                    }
-                    this.initData();
-                    this.vLoading = false
-                  }
-                }).catch(() => {
-                  this.vLoading = false
-                })
-              }
-            }
-          })
-        },
-        beforeRemove(file, fileList) {
-        this.$confirm(`确定移除 ${ file.name }?`, '警告', {
-            confirmButtonText: '确认',
-            cancelButtonText: '取消',
-            type: 'warning',
-          })
-            .then(async () => {
-              this.postForm.contractUrl = '';
-            })
-        }
-      }
-    }
-  </script>
-  <style lang="scss" scoped>
-  
-  </style>
-  

+ 159 - 38
src/views/reports/section/list.vue

@@ -6,17 +6,14 @@
 
         <y-page-list-layout :page-list="pageData" :page-para="listQuery" :get-page-list="getList">
             <template slot="left">
-                <el-button class-name="filter-item" type="primary" size="mini" round style="float: left">新增</el-button>
-                <el-input v-model="listQuery.name" placeholder="模板名称" clearable style="margin-left: 20px; width: 320px;float: left;">
+                <el-button class-name="filter-item" type="primary" size="mini" round style="float: left" @click="dialogVisible=true">新增</el-button>
+                <el-input v-model="listQuery.name" placeholder="模板名称" clearable
+                    style="margin-left: 20px; width: 320px;float: left;">
                 </el-input>
-                <el-select v-model="listQuery.reportType" placeholder="报告类型" clearable filterable
-                    style="margin-left: 20px;width: 320px;float: left;" class="filter-item">
-                    <el-option v-for="item in reportTypes" :key="item.id" :label="item.name" :value="item.id" />
-                </el-select>
-                <el-select v-model="listQuery.reportHeadline" placeholder="报告标题" clearable filterable
-                    style="margin-left: 20px;width: 320px;float: left;" class="filter-item">
-                    <el-option v-for="item in reportHeadlines" :key="item.id" :label="item.name" :value="item.id" />
-                </el-select>
+                <el-cascader v-model="listQuery.headlineId" :options="reports"
+                    :props="{ checkStrictly: true, expandTrigger: 'hover', emitPath: false }" clearable filterable
+                    placeholder="试试搜索:项目基本情况" style="margin-left: 20px; width: 700px;float: left;"
+                    @change="headlineChange"></el-cascader>
                 <el-button class="filter-item" style="margin-left: 10px;float: left;" type="primary" @click="searchList"
                     round>搜索
                 </el-button>
@@ -41,8 +38,12 @@
                 </el-table-column>
                 <el-table-column label="段落内容" align="center">
                     <template slot-scope="{row}">
-                        <span>{{ row.section }}</span>
+                        <el-popover placement="right-start" width="500" trigger="hover"
+                            :content="row.section.replace(/<[^>]+>/g, '')">
+                            <span slot="reference">{{ row.short }}</span>
+                        </el-popover>
                     </template>
+
                 </el-table-column>
                 <el-table-column label="创建人" align="center">
                     <template slot-scope="{row}">
@@ -56,35 +57,40 @@
                 </el-table-column>
                 <el-table-column label="操作" align="center" width="200">
                     <template slot-scope="{row}">
-                        <!-- <PermissionButton
-                menu-code="_views_log_detail"
-                class-name="filter-item"
-                name=""
-                type="primary"
-                :page-jump="true"
-                :page-query="{id: row.id,stageName:row.stageName,listQuery:listQuery}"
-                round
-                size="mini"
-              />
-              <PermissionButton
-                menu-code="_views_log_remove"
-                class-name="filter-item"
-                name=""
-                type="danger"
-                round
-                size="mini"
-                @click="deleteInfo(row.id)"
-              /> -->
+                        <PermissionButton menu-code="_views_section_detail" class-name="filter-item" name="" type="primary"
+                            round size="mini" @click="openDialog(row.id)" />
+                        <PermissionButton menu-code="_views_section_remove" class-name="filter-item" name="" type="danger"
+                            round size="mini" @click="deleteInfo(row.id)" />
                     </template>
                 </el-table-column>
             </parentTable>
         </y-page-list-layout>
+        <el-dialog :visible.sync="dialogVisible" fullscreen center @closed="closeDialog">
+            <el-form :model="sectionTemplate" :rules="rules" ref="ruleForm" label-width="550px">
+                <el-form-item label="模板名称:" prop="name">
+                    <el-input v-model="sectionTemplate.name" style="width: 60.5%;" placeholder="请给段落模板创建一个别名以便区分它们"></el-input>
+                </el-form-item>
+                <el-form-item label="插入位置:" prop="headlines">
+                    <el-cascader v-model="sectionTemplate.headlines" :options="reports" style="width: 60.5%;"  placeholder="请选段落插入报告的标题位置"
+                        :props="{ checkStrictly: true, expandTrigger: 'hover' }" clearable filterable
+                        @change="dialogHeadlineChange"></el-cascader>
+                </el-form-item>
+                <el-form-item label="模板内容:" prop="section">
+                    <YUeditor :content="sectionTemplate.section" ref="ueditor"></YUeditor>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">取 消</el-button>
+                <el-button type="primary" @click="saveSection">保 存</el-button>
+            </span>
+        </el-dialog>
     </div>
 </template>
 <script>
 import YPageListLayout from '@/components/YPageListLayout'
 import Breadcrumb from '@/components/Breadcrumb'
 import PermissionButton from '@/components/PermissionButton/PermissionButton'
+import YUeditor from "@/components/YUeditor"
 
 export default {
     name: 'ReportSection',
@@ -92,26 +98,45 @@ export default {
         Breadcrumb,
         YPageListLayout,
         PermissionButton,
+        YUeditor
     },
     data() {
         return {
+            dialogVisible: false,
             pageData: { records: [] },
             total: 20,
             listLoading: true,
             listQuery: {
                 page: 1,
                 size: 10,
-                // name: '',
-                // staffNo: '',
                 descs: 'id',
+                name: null,
+                headlineId: null
             },
             listQueryKey: 'keyword',
             reportHeadline: [],
-            reportTypes: []
+            reportTypes: [],
+            reports: [],
+            sectionTemplate: {
+                name: null,
+                headlineId: null,
+                headlines:[],
+                section:''
+
+            },
+            rules: {
+                name: [
+                    { required: true, message: '请给段落模板创建一个别名以便区分它们', trigger: 'blur' },
+                ],
+                headlines: [
+                    { required: true, message: '请选段落插入报告的标题位置', trigger: 'blur' }
+                ],
+            }
         }
     },
     created() {
-        this.getList()
+        this.getList();
+        this.getReports();
     },
     methods: {
         resetSearch() {
@@ -132,9 +157,13 @@ export default {
         getList() {
             const that = this
             this.listLoading = true
-            const key = {}
-            this.$api.reportSection.list(Object.assign({}, that.listQuery, key)).then((res) => {
-                that.pageData = res.data
+            this.$api.reportSectionTemplate.list(Object.assign({}, that.listQuery)).then((res) => {
+                let originData = res.data;
+                for (var i in originData.records) {
+                    let shortSection = this.removeHtmlTag(originData.records[i].section)
+                    originData.records[i].short = shortSection;
+                }
+                that.pageData = originData;
                 setTimeout(() => {
                     that.listLoading = false
                 }, 200)
@@ -151,7 +180,7 @@ export default {
                 type: 'warning',
                 center: true
             }).then(() => {
-                that.$api.reportSection.delete(id).then(data => {
+                that.$api.reportSectionTemplate.delete(id).then(data => {
                     that.loading = false
                     if (data.code === 200) {
                         that.getList()
@@ -164,7 +193,99 @@ export default {
                 })
             }).catch(() => {
             })
+        },
+        getReports() {
+            this.$api.reportHeadline.getAllHeadlineTree().then(res => {
+                if (res.code === 200) {
+                    this.reports = res.data;
+                }
+            })
+        },
+        headlineChange(value, event) {
+            this.listQuery.headlineId = value;
+        },
+        removeHtmlTag(htmlStr) {
+            if (htmlStr) {
+                let content = htmlStr.replace(/<[^>]+>/g, "");
+                return content.length > 12 ? (content.slice(0, 12) + '...') : (content);
+            }
+            else {
+                return null;
+            }
+        },
+        openDialog(id) {
+            this.dialogVisible = true;
+            if (id){
+                this.$api.reportSectionTemplate.detail(id).then(res => {
+                if (res.code === 200) {
+                  this.sectionTemplate = res.data;
+                }
+            })
+            }
+            
+        },
+        dialogHeadlineChange(value) {
+            this.sectionTemplate.headlineIds = value.toString();
+        },
+        closeDialog(){
+            this.sectionTemplate = {
+                name: null,
+                headlineId: null,
+                headlines:[],
+                section:" ",
+                id:null
+            };
+        },
+        saveSection(){
+            let _this = this;
+            let template = _this.sectionTemplate;
+            template.headlineId= template.headlines[template.headlines.length-1]
+            //获取富文本内容
+            template.section = this.$refs.ueditor.getUEContent();
+            if (template.id){
+                this.$api.reportSectionTemplate.edit(template).then(res=>{
+                if (res.code === 200){
+                    _this.$notify({
+                    title: '成功',
+                    message: '保存段落模板成功',
+                    type: 'success',
+                    duration: 2000
+                    })
+                    _this.dialogVisible = false
+                    _this.getList();
+                }else{
+                    _this.$notify({
+                    title: '失败',
+                    message: '保存段落模板失败',
+                    type: 'danger',
+                    duration: 2000
+                    })
+                }
+            }
+            )}
+            else{
+                this.$api.reportSectionTemplate.add(template).then(res=>{
+                if (res.code === 200){
+                    _this.$notify({
+                    title: '成功',
+                    message: '保存段落模板成功',
+                    type: 'success',
+                    duration: 2000
+                    })
+                    _this.dialogVisible = false
+                    _this.getList();
+                }else{
+                    _this.$notify({
+                    title: '失败',
+                    message: '保存段落模板失败',
+                    type: 'danger',
+                    duration: 2000
+                    })
+                }
+            }
+            )}
         }
+
     },
 }
 </script>