wucl 1 year ago
parent
commit
9c101159b9

+ 35 - 0
.env.development

@@ -8,6 +8,41 @@ 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_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:$VUE_APP_API_PORT
+
+# Onlyoffice 服务端口号
+VUE_APP_ONLYOFFICE_PORT=8091
+
+# Onlyoffice 服务地址
+VUE_APP_ONLYOFFICE_SERVER=http://$VUE_APP_HOST:$VUE_APP_ONLYOFFICE_PORT
+
+# 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=192.168.0.108:8088/api/onlyoffice/callback
+
+# Onlyoffice 文档转换接口地址,相关文档:https://api.onlyoffice.com/editors/conversionapi
+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_开头的变量才会被webpack.DefinePlugin静态嵌入到客户端侧的包中

+ 2 - 0
package.json

@@ -37,6 +37,8 @@
     "js-cookie": "^2.2.1",
     "js-md5": "^0.7.3",
     "jspdf": "^2.0.0",
+    "lodash": "^4.17.21",
+    "lodash.merge": "^4.6.2",
     "moment": "2.24.0",
     "normalize.css": "^8.0.1",
     "nprogress": "^0.2.0",

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

@@ -41,7 +41,7 @@
             'directionalityltr', 'directionalityrtl', 'indent', '|',
             'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
             'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
-            'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|',
+            'simpleupload', 'insertimage',  'scrawl', 'insertcode', 'pagebreak', 'template', '|',
             'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',
             'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
             'print', 'preview', 'searchreplace', 'drafts', 'help'
@@ -89,8 +89,8 @@
         //首行缩进距离,默认是2em
         //,indentValue:'2em'
 
-        //,initialFrameWidth:1000  //初始化编辑器宽度,默认1000
-        //,initialFrameHeight:320  //初始化编辑器高度,默认320
+        ,initialFrameWidth:800 //初始化编辑器宽度,默认1000
+        ,initialFrameHeight:600  //初始化编辑器高度,默认320
 
         //,readonly : false //编辑器初始化结束后,编辑区域是否是只读的,默认是false
 

+ 47 - 0
src/api/modules/onlyoffice.js

@@ -0,0 +1,47 @@
+import request from '../../utils/onlyoffice-request'
+
+// Onlyoffice 文档转换接口地址
+export function onlyofficeConversion (data) {
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_ONLYOFFICE_CONVERT,
+    data
+  })
+}
+
+// Onlyoffice 文档构建接口地址
+export function onlyofficeBuilder (data) {
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_ONLYOFFICE_DOCBUILDER,
+    data
+  })
+}
+
+// 保存文档信息
+export function forceSaveDocumentInfo (data) {
+  return request({
+    method: 'post',
+    url: '/api/v1/document/forceSave',
+    data
+  })
+}
+
+// 获取文档信息
+export function queryDocumentInfo (params) {
+  console.log("params",params)
+  return request({
+    method: 'get',
+    url: '/api/v1/document/documentInfo',
+    params
+  })
+}
+
+// 获取表格信息
+export function queryExcelInfo (params) {
+  return request({
+    method: 'get',
+    url: '/api/v1/document/excelInfo',
+    params
+  })
+}

+ 0 - 2
src/api/modules/operationLog.js

@@ -1,6 +1,4 @@
 import request from '@/utils/request'
-import { fileDown } from '../../utils/file'
-import md5 from 'js-md5'
 /*
 * 操作日志
 */

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

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

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

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

BIN
src/assets/gif/input_psw.gif


BIN
src/assets/gif/no-message.gif


BIN
src/assets/icon/message.png


+ 150 - 0
src/components/DocumentEditor/index.vue

@@ -0,0 +1,150 @@
+<template>
+    <div v-bind="skeletonAttrs" :loading="loading">
+      <div :key="id" :id="id"></div>
+      <div v-if="$slots.actions" class="MT24 PB24"><slot name="actions"></slot></div>
+    </div>
+  </template>
+  
+  <script>
+  import merge from 'lodash.merge'
+  
+  let script
+  // 脚本标识
+  const scriptId = 'onlyoffice-editor'
+  // 异步加载 api.js
+  const loadScript = () => new Promise((resolve, reject) => {
+    const src = process.env.VUE_APP_ONLYOFFICE_API_URL
+    script = document.querySelector(`#${scriptId}`)
+    // 加载成功
+    const onLoad = () => {
+      resolve()
+      script.removeEventListener('load', onLoad)
+    }
+    // 加载失败
+    const onError = () => {
+      reject(new Error(`脚本 ${src} 加载失败`))
+      script.removeEventListener('error', onError)
+    }
+    if (!script) {
+      script = document.createElement('script')
+      script.id = scriptId
+      script.src = src
+      script.addEventListener('load', onLoad)
+      script.addEventListener('error', onError)
+      document.head.appendChild(script)
+    } else if (window.DocsAPI) {
+      resolve()
+    } else {
+      script.addEventListener('load', onLoad)
+      script.addEventListener('error', onError)
+    }
+  })
+  
+  export default {
+    props: {
+      config: {
+        type: Object,
+        default: null
+      },
+      loading: {
+        type: Boolean,
+        default: true
+      }
+    },
+    data () {
+      return {
+        // 编辑器配置项,完整配置项参见:https://api.onlyoffice.com/editors/config/
+        editorConfig: {
+          // 编辑器宽度
+          width: 1200,
+          // 编辑器高度
+          height: 600,
+          // 编辑器类型,支持 word、cell(表格)、slide(PPT)
+          documentType: 'word',
+          // 文档配置
+          document: {
+            // 权限
+            permissions: {
+              // 启用评论
+              comment: false,
+              // 启用下载
+              download: true,
+              // 启用编辑
+              edit: true,
+              // 启用导出
+              print: true,
+              // 启用预览
+              review: true
+            }
+          },
+          editorConfig: {
+            // 回调地址
+            callbackUrl: process.env.VUE_APP_ONLYOFFICE_CALLBACK,
+            // 设置语言
+            lang: 'zh-CN',
+            // customization 字段相关配置详解:https://api.onlyoffice.com/editors/config/editor/customization
+            customization: {
+              // 强制保存
+              forcesave: true,
+              features: {
+                // 关闭拼写检查
+                spellcheck: false
+              },
+              compactHeader: true
+            },
+          }
+        },
+        id: `editor-${new Date().getTime().toString('32')}`
+      }
+    },
+    computed: {
+      skeletonAttrs () {
+        return {
+          active: true,
+          style: { width: `${this.editorConfig.width}`,height: `${this.editorConfig.height}` },
+          paragraph: { rows: 10 }
+        }
+      }
+    },
+    watch: {
+      loading (newLoading) {
+        if (newLoading === false) this.initEditor()
+      },
+      config: {
+        handler () {
+          this.initEditor()
+        },
+        deep: true
+      }
+    },
+    mounted () {
+      this.initEditor()
+    },
+    beforeDestroy () {
+      // 组件销毁前销毁编辑器
+      if (this.editor) {
+        this.editor.destroyEditor()
+        this.editor = null
+      }
+    },
+    methods: {
+      // 初始化编辑器
+      initEditor () {
+        loadScript(this.src).then(this.createEditor)
+      },
+      // 创建编辑器
+      createEditor () {
+        if (this.editor) {
+          this.editor.destroyEditor()
+          this.editor = null
+        }
+        if (window.DocsAPI) {
+          let config = merge({}, this.editorConfig, this.config)
+          console.log("config",config)
+          this.editor = new window.DocsAPI.DocEditor(this.id, config)
+        }
+      }
+    }
+  }
+  </script>
+  

+ 101 - 0
src/components/DocumentWindow/index.vue

@@ -0,0 +1,101 @@
+<template>
+    <div>
+        <onlyoffice-editor :loading="loading.editor" :config="editorConfig">
+      <!-- <span slot="actions">
+        <el-button type="primary" @click="onSave" :loading="loading.save">保存</el-button>
+      </span> -->
+    </onlyoffice-editor>
+    </div>
+    
+  </template>
+  
+  <script>
+  import OnlyofficeEditor from '@/components/DocumentEditor'
+  import { queryDocumentInfo, forceSaveDocumentInfo } from '@/api/modules/onlyoffice'
+  
+  export default {
+    data() {
+      return {
+        loading: {
+          editor: false,
+          save: false,
+          forceSave: false
+        },
+        detail: {},
+        editorConfig: {
+          // 编辑器宽度
+          width: '100%',
+          // 编辑器高度
+          height: '100%',
+          // 编辑器类型,支持 word(文档)、cell(表格)、slide(PPT)
+          documentType: 'word',
+          // 文档配置
+          document: {
+            // 文件类型
+            fileType: 'docx',
+            // 文档标识符
+            key: '123',
+            // 文档地址,绝对路径
+            url: `${process.env.VUE_APP_API_SERVER}/dfs/2023/08/03/兴文县2023年第3批次建设用地风险评估报告.docx`,
+            // 文档标题
+            title: '测试文档一.docx'
+          }
+        }
+      }
+    },
+    components: {
+      OnlyofficeEditor
+    },
+    created() {
+      this.queryDocumentInfo()
+    },
+    methods: {
+      // 获取文档配置信息
+      queryDocumentInfo() {
+        this.loading.editor = true
+        // queryDocumentInfo({ key: 'test4.docx', useJwtEncrypt: 'y' })
+        //   .then(res => {
+        //     // const data = res.data || {}
+        //     // const { id, remarks } = data
+        //     // this.detail = { id, remarks }
+        //     // this.editorConfig = data.editorConfig
+        //   })
+        //   .finally(() => {
+        //     this.loading.editor = false
+        //   })
+      },
+      // 保存
+      onSave() {
+        this.loading.forceSave = true
+        const { key } = this.editorConfig.document
+        const { id } = this.detail
+        // 如果开启了 JWT 加密,useJwtEncrypt 字段要传递 y
+        forceSaveDocumentInfo({ id, key, useJwtEncrypt: 'n' })
+          .then(res => {
+            if (res.code === 0) {
+              this.$message.success('保存成功')
+            } else {
+              this.$message.error(res.message)
+            }
+          })
+          .finally(() => {
+            this.loading.forceSave = false
+          })
+      }
+    }
+  }
+  </script>
+<style>
+    *{
+        margin: 0;
+        padding: 0;
+    }
+    html,body{
+        width: 100%;
+        height: 100%;
+    }
+    div{
+        width:100%;
+        height: 100%;
+    }
+</style>

+ 112 - 0
src/components/ReportContentCarousel/index.vue

@@ -0,0 +1,112 @@
+<template>
+    <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">
+                    <div slot="header" class="cardHeader">
+                        段落模板:<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>
+                </el-card>
+            </div>
+        </el-card>
+        <el-dialog  :visible.sync="dialogTableVisible" width="60%" center>
+            <div class="dialog-bg">
+                <div class="like-word" v-html="htmlStr">
+                </div>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import YUeditor from "@/components/YUeditor"
+export default {
+    components: {
+        YUeditor,
+    }
+    ,
+
+    props: {
+        tricks: {
+            type: Array,
+            required: false,
+            default:[]
+        }
+    },
+
+    computed: {
+
+    },
+    data() {
+        return {
+            dialogTableVisible :false,
+            htmlStr : null,
+        }
+
+    },
+    methods: {
+        prview(htmlStr) {
+            this.dialogTableVisible = true
+            this.htmlStr = htmlStr;
+        },
+        removeHtmlTag(htmlStr){
+            if (htmlStr){
+                let content = htmlStr.replace(/<[^>]+>/g, "");
+                return  content.length > 80 ? (content.slice(0, 80) + '...') : (content);
+            }
+            else{
+                return null;
+            }
+           
+        }
+    }
+}
+</script>
+<style >
+.box-card {
+    width: 750px;
+}
+.cardHeader{
+    height: 20px;
+    color: gray;
+}
+.chlid-box-card {
+    width: 710px;
+    height: 200px;
+    margin-bottom: 30px;
+}
+
+.chlid-box-card :hover {
+    color: black;
+}
+
+p {
+    text-indent: 2em;
+    color: gray;
+    letter-spacing: 2px;
+    line-height: 1.5
+}
+.dialog-bg{
+    width: 100%;
+    height: 700px;
+    position: relative;
+    overflow: scroll;
+
+}
+.like-word{
+    width: 90%;
+    height: 600px;
+    position: absolute;
+    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);
+    box-shadow: 0 0 20px rgb(175, 175, 175);
+    padding: 20px;
+}
+</style>

+ 116 - 0
src/components/ReportEditor/index.vue

@@ -0,0 +1,116 @@
+
+<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>
+                <el-row :gutter="900">
+                  <el-col :span="6">
+                    <div>
+                      <YUeditor />
+                    </div>
+                  </el-col>
+                  <el-col :span="6">
+                    <div>
+                      <ReportContentCarousel :tricks="tricks" />
+                    </div>
+                  </el-col>
+                </el-row>
+              </div>
+            </el-tab-pane>
+          </el-tabs>
+          <div v-else>
+            <el-row :gutter="900">
+                  <el-col :span="6">
+                    <div>
+                      <YUeditor />
+                    </div>
+                  </el-col>
+                  <el-col :span="6">
+                    <div>
+                      <ReportContentCarousel :tricks="tricks" />
+                    </div>
+                  </el-col>
+                </el-row>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+  </template>
+  
+  <script>
+  import YUeditor from "@/components/YUeditor"
+  import ReportContentCarousel from "@/components/ReportContentCarousel"
+  export default {
+    components: {
+      YUeditor,
+      ReportContentCarousel
+    },
+  
+    props:{
+        headlineTree :{
+            type: Array,
+            require: true,
+        }
+
+    },
+    watch:{
+
+    },
+    data() {
+      return {
+        listLoading: true,
+        activeName:null,
+        tricks:[],
+      }
+  
+    },
+  
+    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;
+            })
+        },
+        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);
+            }
+        },
+        pickHeadline2(tab,event){
+            let name = tab.name;
+            this.getReportSectionList(name);
+        }
+    }
+  }
+  </script>
+  
+  <style lang="css">
+  .report {
+    width: 100%;
+  }
+  </style>

+ 4 - 3
src/layout/components/AppMain.vue

@@ -8,7 +8,8 @@
   </section>
   <section class="app-main" v-else>
     <el-empty :image="require('../../assets/images/no-auth.png')" :image-size=700 description="Oops! 需要输入查询密码...">
-      <i class="el-icon-edit" :style="iconstyle"  @click="openDig" @mouseover="hoverIcon"></i>
+      <!-- <i class="el-icon-edit" :style="iconstyle"  @click="openDig" @mouseover="hoverIcon"></i> -->
+      <img src="../../assets/gif/input_psw.gif" :style="iconstyle" alt="" @click="openDig" @mouseover="hoverIcon">
     </el-empty>
   </section>
 </template>
@@ -50,7 +51,7 @@ export default {
   },
   data(){
     return {
-      iconstyle:"color:blue;font-size: 20px;",
+      iconstyle:"width: 30px;",
       messageId:null,
     }
   },
@@ -74,7 +75,7 @@ export default {
       eventBus.$emit("openDig",true)
     },
     hoverIcon(){
-      this.iconstyle = "color:blue;font-size: 20px; cursor:pointer"
+      this.iconstyle = "width:30px ;cursor:pointer"
     },
 
     getMessageId(){

+ 3 - 3
src/layout/components/Navbar.vue

@@ -5,7 +5,7 @@
     </div>
     <div class="titleDiv"><img src="../../assets/images/logo.png" style="height: 50px;margin-top: 5px;"></div>
     <div class="right-menu" background-color="rgba(42,143,227,1)">
-      <el-dropdown class="message-container right-menu-item" trigger="click" placement="bottom-start">
+      <el-dropdown class="message-container right-menu-item" trigger="hover" placement="bottom-start">
 
         <div class="message-wrapper-nb">
           <el-badge :value= messageNum>
@@ -32,11 +32,11 @@
             </el-card>
           </el-dropdown-item>
           <el-dropdown-item v-else>
-            <el-empty :image="require('../../assets/images/no-message.png')" :image-size=400 description="还没有消息哟~"></el-empty>
+            <el-empty :image="require('../../assets/gif/no-message.gif')" :image-size=300 description="还没有消息哟~"></el-empty>
           </el-dropdown-item>
         </el-dropdown-menu>
       </el-dropdown>
-      <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
+      <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover">
         <div class="avatar-wrapper-nb">
           <img :src="avatar" class="user-avatar">
           <span style="margin-left: 10px;font-size: 14px;">{{ userInfo.name }}</span>

+ 0 - 1
src/layout/index.vue

@@ -154,7 +154,6 @@ export default {
     },
 
     getMessageId(messageId){
-      console.log("shoudao messageid")
       if (messageId){
         this.$refs.navbar.setRead(messageId);
       }

+ 4 - 0
src/router/index.js

@@ -67,6 +67,10 @@ VueRouter.prototype.push = function push(location, onResolve, onReject) {
       path: '/401',
       component: () => import('@/views/error-page/401')
     },
+    {
+      path: '/document/window',
+      component: () => import('@/components/DocumentWindow')
+    }
   ];
 
 const files = require.context('./modules', false, /\.js$/);

+ 6 - 1
src/router/urlMap.js

@@ -62,6 +62,9 @@ import _views_item_transfer from '@/views/item/transfer'
 import _views_gis_user from '@/views/gis/user'
 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'
+
 export default {
   _views_set_menu,
   _view_department,
@@ -111,5 +114,7 @@ export default {
   _views_item_transfer,
   _views_gis_user,
   _views_gis_visited,
-  _views_brokerage_tech_deduction
+  _views_brokerage_tech_deduction,
+  _views_report_land_risk,
+  _views_report_section_template,
 }

+ 14 - 0
src/utils/onlyoffice-request.js

@@ -0,0 +1,14 @@
+import axios from 'axios'
+
+const request = axios.create({
+  timeout: 60000,
+  baseURL: ''
+})
+
+// 请求拦截器
+request.interceptors.request.use(config => config)
+
+// 响应拦截器
+request.interceptors.response.use(res => res.data)
+
+export default request

+ 16 - 7
src/views/item/detail.vue

@@ -21,7 +21,7 @@
                       <el-form-item
                         label="项目名称:"
                         prop="name"
-                        :rules="{required: true, message: '请输入项目名称', trigger: 'blur'}"
+                        :rules="{required: true, message: '项目名称不能为空', trigger: 'blur'}"
                         label-width="120px"
                         class="postInfo-container-item"
                       >
@@ -32,7 +32,7 @@
                       <el-form-item
                         label="归属单位:"
                         prop="belongTo"
-                        :rules="{required: true, message: '归属单位', trigger: 'blur'}"
+                        :rules="{required: true, message: '归属单位不能为空', trigger: 'blur'}"
                         label-width="120px"
                         class="postInfo-container-item"
                       >
@@ -78,7 +78,7 @@
                       <el-form-item
                         label="项目类型:"
                         prop="cate"
-                        :rules="{required: true, message: '项目类型', trigger: 'blur'}"
+                        :rules="{required: true, message: '项目类型不能为空', trigger: 'blur'}"
                         label-width="120px"
                         class="postInfo-container-item"
                       >
@@ -148,7 +148,7 @@
                       <el-form-item
                         label="业务来源:"
                         prop="businessSource"
-                        :rules="{required: true, message: '请输入业务来源', trigger: 'blur'}"
+                        :rules="{required: true, message: '业务来源不能为空', trigger: 'blur'}"
                         label-width="120px"
                         class="postInfo-container-item"
                       >
@@ -168,7 +168,7 @@
                       <el-form-item
                         label="项目负责人:"
                         prop="skiller"
-                        :rules="{required: true, message: '请输入项目负责人', trigger: 'blur'}"
+                        :rules="{required: true, message: '项目负责人不能为空', trigger: 'blur'}"
                         label-width="120px"
                         class="postInfo-container-item"
                       >
@@ -197,7 +197,7 @@
                       <el-form-item
                         label="付款类型:"
                         prop="paymentMethod"
-                        :rules="{required: true, message: '请输入付款方式', trigger: 'blur'}"
+                        :rules="{required: true, message: '付款方式不能为空', trigger: 'blur'}"
                         label-width="120px"
                         class="postInfo-container-item"
                       >
@@ -230,7 +230,7 @@
                       <el-form-item
                         label="所属部门:"
                         prop="departmentId"
-                        :rules="{required: true, message: '请选择所属部门', trigger: 'blur'}"
+                        :rules="{required: true, message: '所属部门不能为空', trigger: 'blur'}"
                         label-width="120px"
                         class="postInfo-container-item"
                       >
@@ -449,6 +449,15 @@
         }
       },
       handleCreate() {
+        if (!this.postForm.customerId){
+            this.$notify({
+              title: '错误',
+              message: '客户名字不能为空',
+              type: 'error',
+              duration: 2000
+            });
+            return;
+        }
         if (this.userIds.length==0){
           this.$notify({
             title: '错误',

+ 0 - 1
src/views/log/list.vue

@@ -87,7 +87,6 @@
   import YPageListLayout from '@/components/YPageListLayout'
   import Breadcrumb from '@/components/Breadcrumb'
   import PermissionButton from '@/components/PermissionButton/PermissionButton'
-  import { fileDown } from '../../utils/file'
 
   export default {
     name: 'ViewsLogList',

+ 1 - 1
src/views/market/customer/detail.vue

@@ -48,7 +48,7 @@
                   <el-row>
                     <el-col :xs="24" :sm="12" :lg="6" :span="6">
                       <el-form-item
-                        label="部门:"
+                        label="单位:"
                         prop="department"
                         label-width="120px"
                         class="postInfo-container-item"

+ 1 - 1
src/views/market/index.vue

@@ -10,7 +10,7 @@
           <y-d-v-over-view style="width: 220px" title="本年已签约" :typeId="4" :ico="require('@/assets/statics/pg9.png')" :data="[{text:marketStaticsInfo.yearSaleDone,value:'元'}]" @click.native="toItemPage()"></y-d-v-over-view>
           <y-d-v-over-view style="width: 220px" title="本年已回款" :typeId="5" :ico="require('@/assets/statics/pg9.png')" :data="[{text:marketStaticsInfo.yearPaymentDone,value:'元'}]" @click.native="toPaymentPage('year')"></y-d-v-over-view>
           <y-d-v-over-view style="width: 220px" title="本月已回款" :typeId="6" :ico="require('@/assets/statics/pg9.png')" :data="[{text:marketStaticsInfo.monthPaymentDone,value:'元'}]" @click.native="toPaymentPage('month')"></y-d-v-over-view>
-          <el-tooltip class="item" effect="dark" content="年度回款目标完成率" placement="bottom">
+          <el-tooltip class="item" effect="dark" content="当月回款完成率" placement="bottom">
             <el-progress  style=" margin-left:12px ;width: 91%" :text-inside="true" :stroke-width="24" :percentage="percentage" status="success" />
           </el-tooltip>
         </div>

+ 56 - 0
src/views/reports/land/risk.vue

@@ -0,0 +1,56 @@
+
+<template>
+  <div>
+      <ReportEditor :headlineTree="headlineTree" />
+  </div>
+</template>
+
+<script>
+import ReportEditor from "@/components/ReportEditor"
+export default {
+  components: {
+    ReportEditor
+  },
+
+  data() {
+    return {
+      listLoading: true,
+     
+      headlineTree:[]
+    }
+
+  },
+
+  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
+          })
+    }
+  }
+}
+</script>
+
+<style lang="css">
+.report {
+  width: 100%;
+}
+</style>

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

@@ -0,0 +1,540 @@
+<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>
+  

+ 210 - 0
src/views/reports/section/list.vue

@@ -0,0 +1,210 @@
+<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="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-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-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.name }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="所属报告类型" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.reportType }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="所属报告标题" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.reportHeadline }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="段落内容" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.section }}</span>
+                    </template>
+                </el-table-column>
+                <el-table-column label="创建人" align="center">
+                    <template slot-scope="{row}">
+                        <span>{{ row.userName }}</span>
+                    </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="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)"
+              /> -->
+                    </template>
+                </el-table-column>
+            </parentTable>
+        </y-page-list-layout>
+    </div>
+</template>
+<script>
+import YPageListLayout from '@/components/YPageListLayout'
+import Breadcrumb from '@/components/Breadcrumb'
+import PermissionButton from '@/components/PermissionButton/PermissionButton'
+
+export default {
+    name: 'ReportSection',
+    components: {
+        Breadcrumb,
+        YPageListLayout,
+        PermissionButton,
+    },
+    data() {
+        return {
+            pageData: { records: [] },
+            total: 20,
+            listLoading: true,
+            listQuery: {
+                page: 1,
+                size: 10,
+                // name: '',
+                // staffNo: '',
+                descs: 'id',
+            },
+            listQueryKey: 'keyword',
+            reportHeadline: [],
+            reportTypes: []
+        }
+    },
+    created() {
+        this.getList()
+    },
+    methods: {
+        resetSearch() {
+            this.$router.push({ query: {} });
+            this.listQuery = {
+                current: 1,
+                size: 10,
+                descs: 'id',
+            }
+            this.getList()
+        },
+        searchList() {
+            // 重置分页
+            this.listQuery.page = 1
+            this.listQuery.size = 20
+            this.getList()
+        },
+        getList() {
+            const that = this
+            this.listLoading = true
+            const key = {}
+            this.$api.reportSection.list(Object.assign({}, that.listQuery, key)).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.reportSection.delete(id).then(data => {
+                    that.loading = false
+                    if (data.code === 200) {
+                        that.getList()
+                    } else {
+                        this.$message({
+                            type: 'error',
+                            message: data.msg
+                        })
+                    }
+                })
+            }).catch(() => {
+            })
+        }
+    },
+}
+</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>
+