瀏覽代碼

发布前的备份

洪海涛 4 年之前
父節點
當前提交
0d929a1c35
共有 26 個文件被更改,包括 6072 次插入181 次删除
  1. 32 0
      src/api/qualityMonthlyReport/edit.js
  2. 10 10
      src/components/affix/affix.vue
  3. 14 0
      src/icons/svg/data-plus.svg
  4. 1 1
      src/store/index.js
  5. 0 7
      src/store/modules/monthlyReport/edit.js
  6. 292 0
      src/store/modules/monthlyReport/edit/index.js
  7. 155 0
      src/store/modules/monthlyReport/edit/utils.js
  8. 36 0
      src/utils/index.js
  9. 81 0
      src/views/monthlyReport/childrenPage/editReport/components/CascaderInfo.vue
  10. 281 0
      src/views/monthlyReport/childrenPage/editReport/components/MrTable.vue
  11. 77 0
      src/views/monthlyReport/childrenPage/editReport/components/MultiplePeopleInfo.vue
  12. 49 0
      src/views/monthlyReport/childrenPage/editReport/components/RichText.vue
  13. 103 0
      src/views/monthlyReport/childrenPage/editReport/components/VarText.vue
  14. 86 0
      src/views/monthlyReport/childrenPage/editReport/components/content.vue
  15. 159 0
      src/views/monthlyReport/childrenPage/editReport/components/core.vue
  16. 108 0
      src/views/monthlyReport/childrenPage/editReport/components/createdItem.vue
  17. 99 0
      src/views/monthlyReport/childrenPage/editReport/components/fixedText.vue
  18. 108 0
      src/views/monthlyReport/childrenPage/editReport/components/markingIssues.vue
  19. 146 0
      src/views/monthlyReport/childrenPage/editReport/components/menu.vue
  20. 64 0
      src/views/monthlyReport/childrenPage/editReport/deepSearch.js
  21. 208 131
      src/views/monthlyReport/childrenPage/editReport/index.vue
  22. 1233 0
      src/views/monthlyReport/childrenPage/editReport/newData.js
  23. 2570 0
      src/views/monthlyReport/childrenPage/editReport/reportData.js
  24. 146 27
      src/views/monthlyReport/components/anchor.vue
  25. 14 5
      src/views/monthlyReport/components/menu.vue
  26. 0 0
      test.js

+ 32 - 0
src/api/qualityMonthlyReport/edit.js

@@ -0,0 +1,32 @@
+// 质量月报
+import request from '@/utils/request'
+import { projectManagementUrl } from '@/apiConfig/api'
+
+// 获取月报
+export function getMonthlyReport(reportId) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/get',
+    method: 'get',
+    params: {
+      reportId
+    }
+  })
+}
+
+// 更新整个月报
+export function updateMonthlyReport(data) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/update',
+    method: 'post',
+    data
+  })
+}
+
+// 仅更新子月报
+export function updatSettingMonthlyReport(data) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/updatSetting',
+    method: 'post',
+    data
+  })
+}

+ 10 - 10
src/components/affix/affix.vue

@@ -47,22 +47,24 @@ export default {
       required: false,
       default: () => null
     },
-    /* 用户自定义函数*/
+    /* 用户自定义函数: 暂时去掉*/
     userFun: {
       type: Function,
       required: false,
-      default: () => {
-      }
+      default: () => {}
     },
     /* 定义节流函数执行间隔时间 */
     listenTime: {
       type: Number,
       required: false,
-      default: () => 300
+      default: () => 700
     }
   },
   data() {
-    this.lazyUpdatePosition = _.throttle(this.lazyUpdatePosition, this.listenTime)
+    this.lazyUpdatePosition = _.throttle(
+      this.lazyUpdatePosition,
+      this.listenTime
+    )
     return {
       placeholderNodeStyle: '',
       fixedNodeStyle: '',
@@ -92,10 +94,7 @@ export default {
         entity.eventHandlers[eventName] = addDOMEventListener(
           targetNode,
           eventName,
-          () => {
-            this.lazyUpdatePosition()
-            this.userFun()
-          }
+          this.lazyUpdatePosition
         )
       })
       this.lazyUpdatePosition()
@@ -121,6 +120,7 @@ export default {
     lazyUpdatePosition() {
       const targetNode = this.target()
       const offsetTop = this.getOffsetTop()
+      this.$emit('change', { scrollTop: targetNode.scrollTop })
       // console.log(102, this.$refs, targetNode.scrollTop)
       if (targetNode.scrollTop < offsetTop) {
         this.prepareMeasure()
@@ -159,4 +159,4 @@ export default {
 }
 </script>
 
-<style scoped lang='less'></style>
+<style scoped lang="less"></style>

+ 14 - 0
src/icons/svg/data-plus.svg

@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #409eff;
+      }
+    </style>
+  </defs>
+  <g id="添加_2_" data-name="添加 (2)" transform="translate(-138.581 -138.581)">
+    <path id="路径_13078" data-name="路径 13078" class="cls-1" d="M271.147,491.958h-7.309c-.186,0-.328-.095-.328-.219s.142-.219.328-.219h7.309c.186,0,.328.095.328.219S271.333,491.958,271.147,491.958Z" transform="translate(-121.911 -346.152)"/>
+    <path id="路径_13079" data-name="路径 13079" class="cls-1" d="M491.739,271.482c-.124,0-.219-.142-.219-.329v-7.315c0-.186.095-.329.219-.329s.219.142.219.329v7.315C491.958,271.339,491.863,271.482,491.739,271.482Z" transform="translate(-346.158 -121.91)"/>
+    <path id="路径_13080" data-name="路径 13080" class="cls-1" d="M151.468,152.581H139.695a1.115,1.115,0,0,1-1.113-1.114V139.7a1.115,1.115,0,0,1,1.113-1.114h11.773a1.115,1.115,0,0,1,1.113,1.114V151.48A1.12,1.12,0,0,1,151.468,152.581ZM139.695,139.35a.362.362,0,0,0-.346.346v11.771a.362.362,0,0,0,.346.346h11.773a.344.344,0,0,0,.346-.346V139.7a.362.362,0,0,0-.346-.346Z" transform="translate(0 0)"/>
+  </g>
+</svg>

+ 1 - 1
src/store/index.js

@@ -6,7 +6,7 @@ import settings from './modules/settings'
 import data from './modules/data'
 import global from './modules/global'
 import project from './modules/project'
-import monthlyReportEdit from './modules/monthlyReport/edit'
+import monthlyReportEdit from './modules/monthlyReport/edit/index'
 import monthlyReportSeting from './modules/monthlyReport/setting'
 
 Vue.use(Vuex)

+ 0 - 7
src/store/modules/monthlyReport/edit.js

@@ -1,7 +0,0 @@
-export default {
-  /* 月报编辑 */
-  namespaced: true,
-  state: {},
-  mutations: {},
-  actions: {}
-}

+ 292 - 0
src/store/modules/monthlyReport/edit/index.js

@@ -0,0 +1,292 @@
+import { uuid10 } from '@/utils'
+import {
+  getMonthlyReport,
+  updateMonthlyReport
+} from '@/api/qualityMonthlyReport/edit'
+import { reportDataBack, setReportData, setTabActive } from './utils'
+import _ from 'lodash'
+
+export default {
+  /* 月报编辑 */
+  namespaced: true,
+  state: {
+    pageDate: null,
+    tabsList: [],
+    tabsActive: '',
+    tabPageData: null, // 单个标签页数据
+    treeActive: '',
+    treeData: [],
+    reportData: [], // 所有标签页数据
+    editKeys: [],
+    subTabsActive: [], // 当前页签中所有已切换的数据
+    domKeys: [], // 记录所有元素区域的唯一标识
+    offsetList: [],
+    selectEnum: [] // 部门数据
+  },
+  mutations: {
+    // 页面基础数据赋值
+    INIT_PAGE_DATA(state, params) {
+      state.pageDate = { ...params }
+      delete state.pageDate.subReports
+      const subReports = [...params.subReports]
+      // 设置部门数据
+      state.selectEnum = [...params.dependence.deptArch.children]
+      if (subReports.length) {
+        state.tabsList = []
+        subReports.forEach((elm, index) => {
+          // 设置tabs数据
+          state.tabsList.push({
+            label: elm.reportName,
+            name: `tab_${elm.id}`
+          })
+        })
+        // 设置tabs数据
+        state.tabsActive = state.tabsList[0].name
+        // table页签
+        state.reportData = [...subReports]
+        // console.log(state.reportData)
+      }
+    },
+    // 单个tab页面数据初始化设置
+    INIT_TAB_PAGE_DATA(state, tabsActive = '') {
+      const setKey = (arr, depth) => {
+        if (arr && arr.length) {
+          arr.forEach((elm) => {
+            elm.domKey = uuid10()
+            elm.depth = depth
+            if (arr.children && arr.children.length) {
+              setKey(arr.children, depth + 1)
+            }
+            if (arr.content && arr.content.length) {
+              setKey(arr.content, depth + 1)
+            }
+          })
+        }
+      }
+      // console.log(54)
+      state.reportData.forEach((elm) => {
+        setKey(elm.reportCatalog.children, 0)
+      })
+      // 从其他页面跳转过来
+      const [tabPageData] = state.reportData.filter((elm) => {
+        return (
+          `${elm.id}` === setTabActive('tab_', tabsActive || state.tabsActive)
+        )
+      })
+      if (tabsActive) {
+        state.tabsActive = `tab_${tabsActive}`
+      }
+      // state.tabPageData = setReportData(tabPageData)
+      const { newObj, domKeys } = setReportData(tabPageData.reportCatalog)
+      state.tabPageData = newObj
+      state.domKeys = domKeys
+    },
+    // 切换页面之后数据维护
+    TAB_ACTIVE_CHANGE(state, tabsActive) {
+      // 获取原来页签的选中对象的id
+      const newTabsActive = setTabActive('tab_', tabsActive)
+      // tabPageData => 后台源数据结构
+      const oldTabPageData = reportDataBack({ ...state.tabPageData })
+      let newTabPageData = {}
+      const reportData = state.reportData.map((elm) => {
+        // 找出新页面的数据    && newTabsActive !== oldTabPageData.id
+        if (newTabsActive === `${elm.id}`) {
+          newTabPageData = { ...elm }
+        }
+        // 将上一个被选中的页签数据赋值给源数据(reportData)
+        if (elm.id === oldTabPageData.id) {
+          return {
+            ...elm,
+            reportCatalog: { ...oldTabPageData }
+          }
+        }
+        return elm
+      })
+      state.reportData = [...reportData]
+      // 对新数据进行转换
+      const { newObj, domKeys } = setReportData(
+        newTabPageData.reportCatalog,
+        108
+      )
+      state.tabPageData = newObj
+      state.domKeys = domKeys
+      // 页面恢复待编辑状态
+      state.editKeys = []
+      // 子页面页签切换,清空原来的tabs选中状态
+      state.subTabsActive = []
+    },
+    // 添加行
+    ADD_EDIT_KEYS(state, key) {
+      const index = state.editKeys.indexOf(key)
+      if (index < 0) {
+        state.editKeys.push(key)
+      }
+    },
+    INIT_EDIT_KEYS(state) {
+      state.editKeys = []
+    },
+    // 子页签数据切换
+    SUB_TABS_ACTIVE(state, { key, oldKey }) {
+      const index = state.subTabsActive.indexOf(oldKey)
+      // console.log(index, key, oldKey)
+      if (index < 0) {
+        state.subTabsActive.push(key)
+      } else {
+        state.subTabsActive.splice(index, 1, key)
+      }
+    },
+    // 删除行
+    /**
+     * @param params.domKey   String   当前表格唯一标识
+     * @param params.btnItem  Object   点击按钮的基础数据
+     * @param params.scope    Object   当前行的数据
+     * @constructor
+     */
+    DELETE_TABLE_LINE(state, params) {
+      //         const { btnItem, scope } = params
+      //
+      // const deepDeleteArray = (arr, key) =>{
+      //           arr.forEach(elm=>{
+      //             if(elm.content && elm.content.length){
+      //               elm.content.forEach(item )
+      //             }
+      //           })
+      // }
+      //
+      //       state.tabPageData.children.forEach((elm) => {
+      //         elm.content.forEach((item) => {
+      //           item.domKey = uuid10(4)
+      //           if (item.type === 'table') {
+      //             setTableHeader(item.tableHeaders)
+      //             item.tableRows = arrToObj(item.tableRows, item.tableHeaders)
+      //           }
+      //         })
+      //       })
+    },
+    // 切换tabs之后,重新生成左侧树
+    CREATE_TREE_DATA(state) {},
+    // 菜单添加子项setInit
+    ADD_MENU_CHILDREN(state, params) {},
+    // 获取子页面所有距离顶部的集合基础信息
+    GET_ALL_OFFSETTOP(state) {
+      const getOffsetTop = (id) => {
+        const dom = document.getElementById(id)
+        if (!dom) return 0.9527
+        return dom.getBoundingClientRect().top
+      }
+      const list = []
+      state.domKeys.forEach((elm) => {
+        const top = getOffsetTop(elm)
+        if (top > 0 && top !== 0.9527) {
+          list.push({
+            domKey: elm,
+            top: getOffsetTop(elm)
+          })
+        }
+      })
+      state.offsetList = [...list]
+    },
+    // 删除某一条数据
+    DELETE_ITEM(state, domKey) {
+      const tabPageData = [...state.tabPageData.children]
+      const delDom = (arr, key) => {
+        if (arr && _.isArray(arr) && arr.length) {
+          for (let i = 0; i < arr.length; i++) {
+            if (arr[i].domKey === key) {
+              arr.splice(i, 1)
+              return
+            }
+
+            if (arr[i].content && arr[i].content.length) {
+              delDom(arr[i].content, key)
+            }
+            if (arr[i].children && arr[i].children.length) {
+              delDom(arr[i].children, key)
+            }
+          }
+        }
+      }
+      delDom(tabPageData, domKey)
+      state.tabPageData.children = [...tabPageData]
+    },
+    /**
+     * 添加同级或者子集
+     * @param state   Object  数据源
+     * @param domKey  String  当前点击元素的唯一标识
+     * @param params  Object  要添加的内容
+     * @param isSub   Boolean 要添加的内容(true:添加子项|false:添加同级)
+     * @constructor
+     */
+    ADD_ITEM(state, { domKey, params, isSub = false }) {
+      if (domKey && params) {
+        const tabPageData = [...state.tabPageData.children]
+        const addItem = (arr, key) => {
+          if (arr && _.isArray(arr) && arr.length) {
+            for (let i = 0; i < arr.length; i++) {
+              if (arr[i].domKey === key) {
+                // 添加子项
+                if (isSub) {
+                  arr[i].children = [...arr[i].children, { ...params }]
+                }
+                // 添加同级
+                if (!isSub) {
+                  arr.splice(i + 1, 0, params)
+                }
+                return
+              }
+              if (arr[i].content && arr[i].content.length) {
+                addItem(arr[i].content, key)
+              }
+              if (arr[i].children && arr[i].children.length) {
+                addItem(arr[i].children, key)
+              }
+            }
+          }
+        }
+        addItem(tabPageData, domKey)
+        state.tabPageData.children = [...tabPageData]
+      }
+    }
+  },
+  actions: {
+    // 月报数据获取
+    async initPageData(context, id) {
+      const res = await getMonthlyReport(id)
+      if (res.code === 200 && res.data) {
+        context.commit('INIT_PAGE_DATA', { ...res.data })
+        context.commit('INIT_TAB_PAGE_DATA')
+      }
+    },
+    // 月报提交
+    async upDateReport({ commit, state }, id) {
+      const params = { ...state.pageDate,
+        subReports: [...state.reportData]
+      }
+      const tabsActive = setTabActive('tab_', state.tabsActive)
+
+      const reportData = state.reportData.map((elm) => {
+        // 将上一个被选中的页签数据赋值给源数据(reportData)
+        if (elm.id === tabsActive) {
+          return {
+            ...elm,
+            reportCatalog: { ...oldTabPageData }
+          }
+        }
+        return elm
+      })
+      state.reportData = [...reportData]
+      // 转换数据结构
+      // tabsActive
+
+      console.log(reportDataBack)
+
+      console.log(params)
+      if (!params) {
+        const res = await updateMonthlyReport()
+        if (res.code === 200) {
+          this.$router.push({ path: '/monthlyReport/index' })
+        }
+      }
+    }
+  }
+}

+ 155 - 0
src/store/modules/monthlyReport/edit/utils.js

@@ -0,0 +1,155 @@
+// import { v4 as uuidv4 } from 'uuid'
+import { uuid10 } from '@/utils'
+
+// 月报标签页基础数据过滤设置
+export function setReportData(obj, line = 6) {
+  const domKeys = []
+  const newObj = { ...obj }
+  const setDomInfo = (arr) => {
+    arr &&
+      arr.length &&
+      arr.forEach((elm) => {
+        elm.domKey = uuid10(4)
+        domKeys.indexOf(elm.domKey) < 0 && domKeys.push(elm.domKey)
+        if (elm.hasOwnProperty('content') && elm.content.length) {
+          elm.content.forEach((item) => {
+            item.domKey = uuid10(4)
+            domKeys.indexOf(item.domKey) < 0 && domKeys.push(elm.domKey)
+            if (item.type.search(/Table|TableAndRichText/) > -1) {
+              setTableHeader(item.tableHeaders)
+              item.tableRows = arrToObj(item.tableRows, item.tableHeaders)
+            }
+          })
+        }
+        if (elm.hasOwnProperty('children') && elm.children.length) {
+          setDomInfo(elm.children)
+        }
+      })
+  }
+  if (newObj && newObj.children && newObj.children.length) {
+    setDomInfo(newObj.children)
+    // newObj.children.forEach((elm) => {
+    //
+    // })
+    return { newObj, domKeys }
+  }
+  return {}
+}
+
+// 递归处理单页数据
+export function reportDataBack(obj) {
+  const newObj = { ...obj }
+  const setOldData = (arr) => {
+    arr &&
+      arr.length &&
+      arr.forEach((elm) => {
+        const { content, children } = elm
+        if (content && content.length) {
+          content.forEach((item) => {
+            if (item.type.search(/Table|TableAndRichText/) > -1) {
+              item.tableRows = objToArr(item.tableRows, item.tableHeaders)
+            }
+          })
+        }
+        if (children && children.length) {
+          setOldData(children)
+        }
+      })
+  }
+  if (newObj && newObj.children && newObj.children.length) {
+    setOldData(newObj.children)
+    // newObj.children.forEach((elm) => {
+    //   elm.content.forEach((item) => {
+    //     if (item.type === 'table') {
+    //       item.tableRows = objToArr(item.tableRows, item.tableHeaders)
+    //     }
+    //   })
+    // })
+    return newObj
+  }
+  return []
+}
+
+export function setTableHeader(tableHeaders) {
+  tableHeaders.map((elm) => {
+    elm.headerKey = uuid10(5)
+  })
+}
+
+// 月报:表格数据转elm组件数据
+export function arrToObj(arr, headerList) {
+  const newObj = []
+  const newArr = [...arr]
+  newArr.forEach((elm) => {
+    const obj = {}
+    elm && elm.length && elm.forEach((item, index) => {
+      const { headerKey } = headerList[index]
+      // let value = ''
+      // if (headerList[index].displayType === 'Select') {
+      //   const label = headerList[index].selectEnum.filter(
+      //     (selectEnumItem) => selectEnumItem.value === item.value
+      //   )
+      //   if (label.length) value = label[0].label
+      // }
+      // obj[headerKey] = value || item.value || ''
+      obj[headerKey] = item.value || ''
+    })
+    obj.rowKey = uuid10()
+    newObj.push(obj)
+  })
+  return newObj
+}
+
+// 月报:elm组件数据转表格数据
+export function objToArr(obj, tableHeaders) {
+  const newObj = [...obj]
+  const newArr = []
+  newObj.forEach((elm) => {
+    const elms = []
+    Object.keys(elm).forEach((key, index) => {
+      if (key !== 'rowKey') {
+        // let value = ''
+        // if (tableHeaders[index].displayType === 'Select') {
+        //   const values = tableHeaders[index].selectEnum.filter(
+        //     (selectEnumItem) => selectEnumItem.label === elm[key]
+        //   )
+        //   if (values.length) value = values[0].value
+        // }
+        elms.push({
+          // value: value || elm[key] || '',
+          value: elm[key] || '',
+          buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+          operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+        })
+      }
+    })
+    newArr.push(elms)
+  })
+  return newArr
+}
+
+// 对字符串进行处理,支持正则
+export function setTabActive(reg = '', value, newValue = '') {
+  const newreg = new RegExp(`${reg}`)
+  return value.replace(newreg, newValue)
+}
+
+export function ret(arr) {
+  const res = [arr[0]]
+  for (let j = 1; j < arr.length; j++) {
+    let repeat = false
+    for (let i = 0; i < res.length; i++) {
+      if (arr[j] === res[i]) {
+        repeat = true
+        break
+      }
+    }
+    if (!repeat) {
+      res.push(arr[j])
+    }
+  }
+  return res
+}
+
+// 根据操作对象唯一标识,查询该对象数据
+export function findDomKey(obj, domKey) {}

+ 36 - 0
src/utils/index.js

@@ -117,3 +117,39 @@ export function isEmpty(obj) {
     return false
   }
 }
+export function randomNumber(min, max) {
+  return Math.floor((max - min) * Math.random() + min)
+}
+
+// 创建唯一标识
+export function uuid10(len = 3) {
+  const letters = 'abcdefghijklmopqrstuvwxyz'
+  const number = '0123456789'
+  let id = ''
+  for (let i = 0; i < len; i++) {
+    id += letters[randomNumber(0, letters.length - 1)]
+  }
+  for (let i = 0; i < len - 1; i++) {
+    id += number[randomNumber(0, number.length - 1)]
+  }
+  return id
+}
+
+// 完成将 toChineseNum, 可以将数字转换成中文大写的表示,处理到万级别,例如 toChineseNum(12345),返回 一万二千三百四十五。
+export function toChinesNum(num) {
+  const changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'] // changeNum[0] = "零"
+  const unit = ['', '十', '百', '千', '万']
+  num = parseInt(num)
+  const getWan = (temp) => {
+    const strArr = temp.toString().split('').reverse()
+    let newNum = ''
+    for (var i = 0; i < strArr.length; i++) {
+      newNum = (i === 0 && strArr[i] === 0 ? '' : (i > 0 && strArr[i] === 0 && strArr[i - 1] === 0 ? '' : changeNum[strArr[i]] + (strArr[i] === 0 ? unit[0] : unit[i]))) + newNum
+    }
+    return newNum
+  }
+  const overWan = Math.floor(num / 10000)
+  let noWan = num % 10000
+  if (noWan.toString().length < 4) noWan = '0' + noWan
+  return overWan ? getWan(overWan) + '万' + getWan(noWan) : getWan(num)
+}

+ 81 - 0
src/views/monthlyReport/childrenPage/editReport/components/CascaderInfo.vue

@@ -0,0 +1,81 @@
+<template>
+<div v-if="teamData && teamData.length">
+  <span
+    v-for="(item, index) in itemName"
+    :key="index"
+    style="margin-right: 10px">{{ item }}<span>{{ !(index >= itemName.length - 1) ? ',' : '' }}</span></span>
+</div>
+</template>
+
+<script>
+import _ from 'lodash'
+
+export default {
+  name: 'CascaderInfo',
+  props: {
+    teamData: {
+      type: [Array, String],
+      required: false,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      itemName: []
+    }
+  },
+  computed: {
+    selectEnum() {
+      return this.$store.state.monthlyReportEdit.selectEnum
+    }
+  },
+  watch: {
+    teamData() {
+      this.init()
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      if (this.teamData && this.teamData.length) {
+        const [first, second] = this.teamData
+        // console.log(first, second)
+        const arr = [...first]
+        if (arr.length < 2 && second) {
+          arr.concat(second[0])
+        }
+        const itemName = []
+        this.teamData.forEach((elm) => {
+          if (_.isArray(elm)) {
+            const last = elm[elm.length - 1]
+            itemName.push(this.find(last))
+          }
+        })
+        // 数组去重
+        this.itemName = [...new Set(itemName)]
+      }
+    },
+    find(id) {
+      let name = ''
+      const run = (arr) => {
+        for (let i = 0; i < arr.length; i++) {
+          const elm = arr[i]
+          if (elm.value === id) {
+            name = elm.label
+            return
+          }
+          if (elm.children) {
+            run(elm.children)
+          }
+        }
+      }
+      run(this.selectEnum)
+      return name
+    }
+  }
+}
+</script>
+
+<style scoped lang="less"></style>

+ 281 - 0
src/views/monthlyReport/childrenPage/editReport/components/MrTable.vue

@@ -0,0 +1,281 @@
+<template>
+  <div>
+    <el-table
+      :data="tableData"
+      border
+      style="width: 100%;"
+      highlight-current-row
+      :header-cell-style="{
+        background: '#F7F7F7',
+        color: '#4a4a4a',
+        'font-size': '14px',
+        'font-weight': '500'
+      }"
+      :cell-style="{ 'font-size': '14px', color: 'rgba(102,102,102,1)' }"
+      size="small"
+      show-overflow-tooltip="true"
+    >
+      <el-table-column
+        v-for="(item, index) in columns"
+        :key="item.headerKey"
+        :data-index="index"
+        :prop="item.headerKey"
+        :align="index === 0 ? 'left' : 'center'"
+        :label="item.name"
+        :min-width="setMinWidth(item)"
+        :fixed="isFixed(item, index, columns)"
+      >
+        <template slot-scope="scope">
+          <!--    操作列    -->
+          <div v-if="item.name === '操作'">
+            <el-button
+              v-for="(btnItem, btnIndex) in item.defaultValue"
+              :key="btnIndex"
+              size="mini"
+              type="text"
+              @click="btnFun(btnItem, scope)"
+              >{{ btnItem.value }}</el-button
+            >
+          </div>
+          <div v-else class="edit-wrapper">
+            <!--            <div v-if="editKeys.indexOf(`${scope.row.rowKey}_${index}`) > -1">-->
+            <div v-if="editKeys.indexOf(domKey) > -1">
+              <div v-if="item.displayType === 'Select'">
+                <div v-if="item.selectType && item.selectType === 'time'">
+                  <el-date-picker
+                    :ref="`${scope.row.rowKey}_${index}`"
+                    v-model="scope.row[item.headerKey]"
+                    type="date"
+                    style="width: 90%"
+                    value-format="yyyy-MM-dd"
+                    size="mini"
+                    placeholder="选择日期"
+                  />
+                </div>
+                <div v-else-if="item.selectType && item.selectType === 'SinglePeople'">
+                  <searchPeople :value.sync="scope.row[item.headerKey]" />
+                </div>
+                <div v-else-if="item.selectType && item.selectType === 'MultiplePeople'">
+                  <searchPeople :value.sync="scope.row[item.headerKey]" :multiple="true" />
+                </div>
+                <div v-else-if="item.selectType && item.selectType === 'people'">
+                  <searchPeople :value.sync="scope.row[item.headerKey]" :multiple="true" />
+                </div>
+                <el-select
+                  v-else
+                  :ref="`${scope.row.rowKey}_${index}`"
+                  v-model="scope.row[item.headerKey]"
+                  size="mini"
+                  placeholder="请选择"
+                  style="width: 80%"
+                >
+                  <el-option
+                    v-for="optionItem in item.selectEnum"
+                    :key="optionItem"
+                    :label="optionItem"
+                    :value="optionItem"
+                  >{{ optionItem }}</el-option
+                  >
+                </el-select>
+              </div>
+
+              <el-input
+                v-else-if="item.displayType === 'Text'"
+                :ref="`${scope.row.rowKey}_${index}`"
+                v-model="scope.row[item.headerKey]"
+                type="textarea"
+                placeholder="请输入"
+                maxlength="100"
+                :autosize="{ minRows: 1, maxRows: 4 }"
+                show-word-limit
+              />
+              <div v-else-if="item.displayType === 'Cascader'">
+                <el-cascader
+                  :ref="`${scope.row.rowKey}_${index}`"
+                  v-model="scope.row[item.headerKey]"
+                  :options="selectEnum"
+                  size="mini"
+                  collapse-tags
+                  :props="{ multiple: true }"
+                  clearable
+                  @change="(value)=>cascaderChange(value, item.headerKey,scope.row)" />
+              </div>
+              <el-input
+                v-else
+                :ref="`${scope.row.rowKey}_${index}`"
+                v-model="scope.row[item.headerKey]"
+                size="mini"
+                maxlength="100"
+                show-word-limit
+                placeholder="请输入"
+              />
+            </div>
+            <!--            <div v-else class="edit-cell" @click="editLine(scope.row, index)">-->
+            <div v-else class="edit-cell" @click="editLine(scope.row, index)">
+              <div v-if="item.displayType === 'Cascader'">
+                <CascaderInfo :team-data="scope.row[item.headerKey]" />
+              </div>
+              <div v-else-if="item.displayType === 'Select'">
+              <!-- 单个人员选择 -->
+                <div v-if="item.selectType && item.selectType === 'SinglePeople'">
+                  <MultiplePeopleInfo :team-data="scope.row[item.headerKey]" />
+                </div>
+                <!-- 多个人员选择 -->
+                <div v-else-if="item.selectType && item.selectType === 'MultiplePeople'">
+                  <!-- <searchPeople :value.sync="scope.row[item.headerKey]" :multiple="true" disabled />-->
+                  <MultiplePeopleInfo :team-data="scope.row[item.headerKey]" />
+                </div>
+                <!-- 多个人员选择 -->
+                <div v-else-if="item.selectType && item.selectType === 'people'">
+                  <MultiplePeopleInfo :team-data="scope.row[item.headerKey]" />
+                </div>
+                <div v-else>
+                  {{ scope.row[item.headerKey] }}
+                </div>
+              </div>
+            <div v-else>
+              {{ scope.row[item.headerKey] }}
+            </div>
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="plus-table-data" :style="{marginBottom: plusTableDataBottom}">
+      <el-button
+type="text"
+@click="addTableData"
+        ><svg-icon icon-class="data-plus" class="icon" />&nbsp;新增</el-button
+      >
+    </div>
+    <slot name="fixedText" />
+  </div>
+</template>
+
+<script>
+import { uuid10 } from '@/utils'
+import CascaderInfo from './CascaderInfo'
+import MultiplePeopleInfo from './MultiplePeopleInfo'
+import searchPeople from '@/components/select/searchPeople' // 人员select
+
+export default {
+  name: 'MrTable',
+  components: { CascaderInfo, searchPeople, MultiplePeopleInfo },
+  props: {
+    plusTableDataBottom: {
+      type: String,
+      required: false,
+      default: () => '18px'
+    },
+    domKey: {
+      type: String,
+      required: false,
+      default: () => ''
+    },
+    columns: {
+      type: Array,
+      required: false,
+      default: () => []
+    },
+    tableData: {
+      type: Array,
+      required: false,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+    }
+  },
+  computed: {
+    selectEnum() {
+      return this.$store.state.monthlyReportEdit.selectEnum
+    },
+    editKeys() {
+      return this.$store.state.monthlyReportEdit.editKeys
+    }
+  },
+  methods: {
+    isEdit() {},
+    setMinWidth(item) {
+      let width = 200
+      if (item.name === '操作') {
+        if (item.defaultValue.length) {
+          width = item.defaultValue.length * 50
+        }
+      }
+      return `${width}px`
+    },
+    isFixed(item, index, columns) {
+      // || index === columns.length - 1
+      if (item.name === '操作') return 'right'
+      // if (index === 0) return 'left'
+      return false
+    },
+    editLine(row, index) {
+      // console.log(row)
+      this.$store.commit(
+        'monthlyReportEdit/ADD_EDIT_KEYS',
+        // `${row.rowKey}_${index}`
+        `${this.domKey}`
+      )
+      // this.$nextTick(() => {
+      //   const [dom] = this.$refs[`${row.rowKey}_${index}`]
+      //   setTimeout(() => {
+      //     // 下拉选择器 利用点击事件展开选项
+      //     if (dom && dom.options && dom.options.length) {
+      //       dom && dom.$el.click()
+      //     } else {
+      //       dom && dom.focus()
+      //     }
+      //   }, 100)
+      // })
+    },
+    btnFun(btnItem, scope) {
+      this.$store.commit('monthlyReportEdit/INIT_EDIT_KEYS')
+      if (btnItem.value === '删除') {
+        // console.log(this.tableData, btnItem, scope)
+        this.tableData.splice(scope.$index, 1)
+        // this.$store.commit('monthlyReportEdit/DELETE_TABLE_LINE', { btnItem, scope, domKey: this.domKey })
+      }
+    },
+    addTableData() {
+      const item = {
+        rowKey: uuid10()
+      }
+      this.columns.forEach(elm => {
+        item[elm.headerKey] = ''
+      })
+      this.tableData.push(item)
+      this.$nextTick(() => {
+        this.$store.commit('monthlyReportEdit/GET_ALL_OFFSETTOP')
+      })
+      this.editLine()
+      // const item = {}
+      // console.log(this.columns)
+      // this.columns.forEach(elm => {
+      //   if (elm.name !== '操作') {
+      //
+      //   }
+      // })
+    },
+    cascaderChange(value, headerKey, row) {
+      console.log(value, headerKey, row)
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.edit-wrapper {
+  cursor: pointer;
+
+  .edit-cell {
+    min-height: 23px;
+    width: 100%;
+  }
+}
+.plus-table-data {
+  margin-top: 2px;
+}
+</style>

+ 77 - 0
src/views/monthlyReport/childrenPage/editReport/components/MultiplePeopleInfo.vue

@@ -0,0 +1,77 @@
+<template>
+  <div v-if="userName && userName.length">
+    <span
+      v-for="(item, index) in userName"
+      :key="index"
+      style="margin-right: 10px"
+    >{{ item
+      }}<span>{{ !(index >= userName.length - 1) ? ',' : '' }}</span></span
+    >
+  </div>
+</template>
+
+<script>
+import { memberQueryMemberInfoByIDAPorName } from '@/api/projectIndex'
+/*
+ * 用户详情解析
+ * */
+export default {
+  name: 'MultiplePeopleInfo',
+  props: {
+    teamData: {
+      type: [Array, String],
+      required: false,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      timeOut: false,
+      userName: []
+    }
+  },
+  watch: {
+    teamData() {
+      if (this.teamData && this.teamData.length) {
+        this.init()
+      }
+    }
+  },
+  mounted() {
+    if (this.teamData && this.teamData.length) {
+      this.init()
+    }
+  },
+  methods: {
+    // 根据传入类型判断数据
+    init() {
+      let index = typeof this.teamData === 'string' ? 'a9527' : 0
+      const getInfo = () => {
+        this.getMember(
+          index !== 'a9527' ? this.teamData[index] : this.teamData,
+          () => {
+            if (index !== 'a9527' && !this.timeOut) {
+              index++
+              getInfo()
+            }
+          }
+        )
+      }
+      getInfo()
+    },
+    async getMember(query, cb) {
+      const res = await memberQueryMemberInfoByIDAPorName({ memberIDAP: query })
+      if (res.data && res.data.length) {
+        for (let i = 0; i < res.data.length; i++) {
+          const elm = res.data[i]
+          if (elm.idap === query) {
+            this.userName.push(elm.name)
+            cb()
+            return
+          }
+        }
+      }
+    }
+  }
+}
+</script>

+ 49 - 0
src/views/monthlyReport/childrenPage/editReport/components/RichText.vue

@@ -0,0 +1,49 @@
+<template>
+  <div>
+    <normal-area
+      v-if="editKeys.indexOf(item.domKey) > -1"
+      :id="item.domKey"
+      :value.sync="item.value"
+      :height="200"
+      :full-position-style="{ top:'20px',left:'15%', right: '15%' }"
+    />
+    <div v-else style="cursor: pointer" @click="editDom" v-html="item.value" />
+  </div>
+</template>
+
+<script>
+import normalArea from '@/components/input/normalArea' // 富文本
+import 'tinymce/plugins/table'
+// 插入表格插件
+export default {
+  name: 'RichText',
+  components: {
+    normalArea
+  },
+  props: {
+    item: {
+      type: Object,
+      requried: false,
+      default: () => {}
+    }
+  },
+  computed: {
+    editKeys() {
+      return this.$store.state.monthlyReportEdit.editKeys
+    }
+  },
+  methods: {
+    editDom() {
+      this.$store.commit(
+        'monthlyReportEdit/ADD_EDIT_KEYS',
+        // `${row.rowKey}_${index}`
+        `${this.item.domKey}`
+      )
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 103 - 0
src/views/monthlyReport/childrenPage/editReport/components/VarText.vue

@@ -0,0 +1,103 @@
+<template>
+  <div class="fixedText">
+    <!--    <div class="top-title">-->
+    <!--      <div class="top-title-content">top-title-content</div>-->
+    <!--      <div class="handle-box"><el-button type="text">标记</el-button></div>-->
+    <!--    </div>-->
+    <div class="content">
+      <div class="title">{{ name }}</div>
+      <div class="value">
+        <el-input
+          v-model="textValue"
+          type="textarea"
+          placeholder="请输入"
+          maxlength="300"
+          show-word-limit
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash'
+
+export default {
+  name: 'VarText',
+  props: {
+    title: {
+      type: String,
+      required: false,
+      default: () => ''
+    },
+    name: {
+      type: String,
+      required: false,
+      default: () => ''
+    },
+    value: {
+      type: String,
+      required: false,
+      default: () => ''
+    }
+  },
+  data() {
+    this.upData = _.debounce(this.upData, 800)
+    return {
+      textValue: ''
+    }
+  },
+  watch: {
+    value(val) {
+      this.textValue = val
+    },
+    textValue(val) {
+      this.upData()
+    }
+  },
+  mounted() {
+    this.textValue = this.value
+  },
+  methods: {
+    upData() {
+      this.$emit('input', this.textValue)
+    }
+  }
+}
+</script>
+
+<style scoped lang='less'>
+.fixedText {
+  .top-title {
+    width: 100%;
+    display: flex;
+
+    &-content {
+      flex: 1;
+      padding: 10px 0;
+    }
+
+    .handle-box {
+      flex: none;
+      width: 50px;
+      text-align: right;
+    }
+  }
+
+  .content {
+    width: 100%;
+    display: flex;
+
+    .title {
+      padding: 9px 0;
+      flex: none;
+      width: 50px;
+    }
+
+    .value {
+      flex: 1;
+    }
+  }
+}
+</style>
+

+ 86 - 0
src/views/monthlyReport/childrenPage/editReport/components/content.vue

@@ -0,0 +1,86 @@
+<template>
+  <div class="content-wrapper">
+    <div v-for="item in baseData" :key="item.domKey">
+      <!--   表格:Table   -->
+      <div v-if="item.type === 'Table'">
+        <mrTable
+          :columns="item.tableHeaders"
+          :table-data="item.tableRows"
+          :dom-key="item.domKey"
+        />
+      </div>
+      <!--   表格和富文本:TableAndRichText   -->
+      <div v-else-if="item.type === 'TableAndRichText'">
+        <mrTable
+          :columns="item.tableHeaders"
+          :table-data="item.tableRows"
+          :dom-key="item.domKey"
+          plus-table-data-bottom="0px"
+          style="margin-bottom: 18px"
+        >
+          <template slot="fixedText">
+            <fixedText
+              v-model="item.value"
+              :title="item.title"
+              :name="item.name"
+            />
+          </template>
+        </mrTable>
+      </div>
+      <!--   固定文本--由后端生成:FixedText   -->
+      <div v-else-if="item.type === 'FixedText'">{{ item.value }}</div>
+      <!--   可变文本:VarText   -->
+      <div v-else-if="item.type === 'VarText'">
+        <VarText
+          v-model="item.value"
+          :title="item.title"
+          :name="item.name"
+          :dom-key="item.domKey"
+        />
+      </div>
+      <!--   富文本--用户可编辑:RichText   -->
+      <div v-else-if="item.type === 'RichText'">
+        <RichText :dom-key="item.domKey" :item="item" />
+      </div>
+      <div v-else>
+<!--        <fixedText-->
+<!--          v-model="item.value"-->
+<!--          :title="item.title"-->
+<!--          :name="item.name"-->
+<!--          :dom-key="item.domKey"-->
+<!--        />-->
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import mrTable from './MrTable'
+import fixedText from './fixedText'
+import RichText from './RichText'
+import VarText from './VarText'
+
+export default {
+  name: 'Content',
+  components: {
+    mrTable,
+    fixedText,
+    RichText,
+    VarText
+  },
+  props: {
+    baseData: {
+      type: Array,
+      required: false,
+      default: () => null
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.content-wrapper {
+  //margin-top: 10px;
+  margin-bottom: 30px;
+}
+</style>

+ 159 - 0
src/views/monthlyReport/childrenPage/editReport/components/core.vue

@@ -0,0 +1,159 @@
+<template>
+  <div v-show="baseData.isVisible">
+    <div v-if="baseData.type === 'Head1'" :id="baseData.domKey">
+      <headTitle
+        :title="baseData.title"
+      />
+    </div>
+    <div
+      v-if="baseData.type.search(/Head2|Head3/) > -1"
+      :id="baseData.domKey"
+      style="margin-top: 10px;"
+    >
+      {{ headerIndex }}{{ headerTitle }}
+    </div>
+    <div v-if="baseData.content && baseData.content.length" style="margin-bottom: 10px">
+      <contentDom :base-data="baseData.content" />
+    </div>
+    <div v-if="baseData.children && baseData.children.length">
+      <div v-if="baseData.children[0].type === 'Tag'">
+        <el-tabs v-model="activeName" @tab-click="handleClick">
+          <el-tab-pane
+            v-for="(item, index) in baseData.children"
+            :key="item.domKey"
+            :label="item.title"
+            :name="item.domKey"
+            :dom-index="index"
+            ><Core
+:key="item.domKey"
+:base-data="item"
+          /></el-tab-pane>
+        </el-tabs>
+      </div>
+      <div v-else>
+        <Core
+          v-for="(item, index) in baseData.children"
+          :key="item.domKey"
+          :dom-index="index"
+          :base-data="item"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import headTitle from '@/components/headTitle'
+import contentDom from './content'
+import { toChinesNum } from '@/utils'
+
+export default {
+  name: 'Core',
+  components: {
+    headTitle,
+    contentDom
+  },
+  props: {
+    baseData: {
+      type: Object,
+      required: false,
+      default: () => null
+    },
+    domIndex: {
+      type: Number,
+      required: false,
+      default: () => null
+    }
+  },
+  data() {
+    return {
+      activeName: '',
+      headerTitle: ''
+    }
+  },
+  computed: {
+    headerIndex() {
+      if (this.baseData.depth === 3) {
+        return this.domIndex ? `${toChinesNum(this.domIndex)}、` : ''
+      }
+      return this.domIndex ? `${this.domIndex}、` : ''
+    }
+  },
+  watch: {
+    activeName(val, old) {
+      this.$store.commit('monthlyReportEdit/SUB_TABS_ACTIVE', {
+        key: val,
+        oldKey: old
+      })
+    },
+    'baseData.content': {
+      handler() {
+        this.setHeader()
+      },
+      deep: true
+    }
+  },
+  mounted() {
+    if (
+      this.baseData &&
+      this.baseData.children &&
+      this.baseData.children.length &&
+      this.baseData.children[0].type === 'Tag'
+    ) {
+      // this.$store.commit('monthlyReportEdit/SUB_TABS_ACTIVE', this.baseData.children[0].domKey, this.activeName)
+      this.activeName = this.baseData.children[0].domKey
+    }
+    this.setHeader()
+  },
+  methods: {
+    handleClick(tab, event) {
+      // console.log(tab, event)
+      this.$nextTick(() => {
+        this.$store.commit('monthlyReportEdit/GET_ALL_OFFSETTOP')
+        this.$store.commit('monthlyReportEdit/INIT_EDIT_KEYS')
+      })
+
+      // const { name } = tab
+      // this.$store.commit('monthlyReportEdit/SUB_TABS_ACTIVE', this.baseData.children[0].domKey, this.activeName)
+    },
+    setHeader() {
+      const title = `${this.baseData.title}`
+      if (title.search(/\{param\}/) > -1) {
+        this.headerTitle = this.generalDelayTitle(title)
+        return
+      }
+      this.headerTitle = title
+    },
+    // 延期 - 项目延期提测{test}次,延期发布{release}次
+    generalDelayTitle(title) {
+      let newTitle = title + ''
+      const { tableRows, tableHeaders } = this.baseData.content[0]
+      const { headerKey, selectEnum } = tableHeaders[0]
+      let test1 = 0
+      let test2 = 0
+      tableRows && tableRows.length && tableRows.forEach(elm => {
+        if (elm[headerKey] && elm[headerKey] === selectEnum[0]) {
+          test1++
+        }
+        if (elm[headerKey] && elm[headerKey] === selectEnum[1]) {
+          test2++
+        }
+      })
+      newTitle = newTitle.replace('{param}', test1)
+      newTitle = newTitle.replace('{param}', test2)
+      return newTitle
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+/*elm-tabs 默认样式处理*/
+/deep/.el-tabs__active-bar,
+/deep/.el-tabs__nav-wrap::after {
+  display: none;
+}
+/deep/.el-tabs__header {
+  margin-bottom: 0;
+}
+</style>

+ 108 - 0
src/views/monthlyReport/childrenPage/editReport/components/createdItem.vue

@@ -0,0 +1,108 @@
+<template>
+  <div v-clickoutside="()=> modalShow = false">
+    <modal
+      :visible="modalShow"
+      :bg="false"
+      :title="titleName"
+      :box-styles="{
+      height:'calc(60vh - 118px)'
+    }"
+      @close="modalClose">
+      <el-form label-width="50px">
+        <el-form-item label="标题">
+          <el-input v-model="normalAreaName" autocomplete="off" placeholder="请输入项目名称" />
+        </el-form-item>
+        <el-form-item label="内容">
+          <normal-area
+            :id="uuid10(10)"
+            :value.sync="normalAreaValue"
+            :height="200"
+            :full-position-style="{ top:'20px',left:'15%', right: '15%' }"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="modalShow = false">取 消</el-button>
+        <el-button type="primary" @click="addItem">确 定</el-button>
+      </div>
+    </modal>
+  </div>
+</template>
+<script>
+import modal from '@/components/modal'
+import normalArea from '@/components/input/normalArea'
+import { uuid10 } from '@/utils'
+import Clickoutside from '_element-ui@2.15.1@element-ui/src/utils/clickoutside'
+export default {
+  name: 'CreatedItem',
+  components: {
+    normalArea,
+    modal
+  },
+  directives: { Clickoutside },
+  data() {
+    return {
+      modalShow: false,
+      titleName: '添加',
+      normalAreaName: '',
+      menuData: '',
+      normalAreaValue: ''
+    }
+  },
+  methods: {
+    uuid10,
+    openModal(title, menuData) {
+      this.titleName = title
+      this.menuData = menuData
+      this.modalShow = true
+    },
+    addItem() {
+      const params = {
+        'children': [],
+        'content': [
+          {
+            'name': null,
+            'tableHeaders': [],
+            'tableRows': [],
+            'type': 'RichText',
+            domKey: uuid10(4),
+            'value': `${this.normalAreaValue}`
+          }
+        ],
+        'depth': this.menuData.depth + 1,
+        'fromUser': true,
+        'hiddenAncestor': null,
+        'isVisible': true,
+        domKey: uuid10(4),
+        'title': `${this.normalAreaName}`,
+        'type': 'Head2'
+      }
+
+      // 添加同级子项
+      // 添加子项
+      if (this.titleName === '添加同级子项') {
+        params.depth = this.menuData.depth
+        if (this.menuData.depth === 0) {
+          params.type = 'Head1'
+        }
+        this.$store.commit('monthlyReportEdit/ADD_ITEM', {
+          domKey: this.menuData.domKey, params: { ...params }
+        })
+      }
+      if (this.titleName === '添加子项') {
+        this.$store.commit('monthlyReportEdit/ADD_ITEM', {
+          domKey: this.menuData.domKey, params: { ...params }, isSub: true
+        })
+      }
+      this.modalClose()
+    },
+    modalClose() {
+      this.normalAreaName = ''
+      this.menuData = ''
+      this.normalAreaValue = ''
+      this.modalShow = false
+    }
+  }
+
+}
+</script>

+ 99 - 0
src/views/monthlyReport/childrenPage/editReport/components/fixedText.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="fixedText">
+<!--    <div class="top-title">-->
+<!--      <div class="top-title-content">top-title-content</div>-->
+<!--      <div class="handle-box"><el-button type="text">标记</el-button></div>-->
+<!--    </div>-->
+    <div class="content">
+      <div class="title">{{ name }}</div>
+      <div class="value">
+        <el-input
+          v-model="textValue"
+          type="textarea"
+          placeholder="请输入"
+          maxlength="300"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash'
+
+export default {
+  name: 'FixedText',
+  props: {
+    title: {
+      type: String,
+      required: false,
+      default: () => ''
+    },
+    name: {
+      type: String,
+      required: false,
+      default: () => ''
+    },
+    value: {
+      type: String,
+      required: false,
+      default: () => ''
+    }
+  },
+  data() {
+    this.upData = _.debounce(this.upData, 800)
+    return {
+      textValue: ''
+    }
+  },
+  watch: {
+    value(val) {
+      this.textValue = val
+    },
+    textValue(val) {
+      this.upData()
+    }
+  },
+  mounted() {
+    this.textValue = this.value
+  },
+  methods: {
+    upData() {
+      this.$emit('input', this.textValue)
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.fixedText {
+  .top-title{
+    width: 100%;
+    display: flex;
+    &-content {
+      flex: 1;
+      padding: 10px 0;
+    }
+    .handle-box{
+      flex: none;
+      width: 50px;
+      text-align: right;
+    }
+  }
+  .content {
+    width: 100%;
+    display: flex;
+
+    .title {
+      padding: 9px 0;
+      flex: none;
+      width: 50px;
+    }
+
+    .value {
+      flex: 1;
+    }
+  }
+}
+</style>
+

+ 108 - 0
src/views/monthlyReport/childrenPage/editReport/components/markingIssues.vue

@@ -0,0 +1,108 @@
+<template>
+  <div v-clickoutside="()=> modalShow = false">
+    <modal
+:visible="modalShow"
+:bg="false"
+:title="titleName"
+:box-styles="{
+      height:'calc(60vh - 118px)'
+    }"
+@close="modalClose">
+      <el-form label-width="50px">
+        <el-form-item label="标题">
+          <el-input v-model="normalAreaName" autocomplete="off" placeholder="请输入项目名称" />
+        </el-form-item>
+        <el-form-item label="内容">
+          <normal-area
+            :id="uuid10(10)"
+            :value.sync="normalAreaValue"
+            :height="200"
+            :full-position-style="{ top:'20px',left:'15%', right: '15%' }"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="modalShow = false">取 消</el-button>
+        <el-button type="primary" @click="addItem">确 定</el-button>
+      </div>
+    </modal>
+  </div>
+</template>
+<script>
+import modal from '@/components/modal'
+import normalArea from '@/components/input/normalArea'
+import { uuid10 } from '@/utils'
+import Clickoutside from '_element-ui@2.15.1@element-ui/src/utils/clickoutside'
+export default {
+  name: 'CreatedItem',
+  components: {
+    normalArea,
+    modal
+  },
+  directives: { Clickoutside },
+  data() {
+    return {
+      modalShow: false,
+      titleName: '添加',
+      normalAreaName: '',
+      menuData: '',
+      normalAreaValue: ''
+    }
+  },
+  methods: {
+    uuid10,
+    openModal(title, menuData) {
+      this.titleName = title
+      this.menuData = menuData
+      this.modalShow = true
+    },
+    addItem() {
+      const params = {
+        'children': [],
+        'content': [
+          {
+            'name': null,
+            'tableHeaders': [],
+            'tableRows': [],
+            'type': 'RichText',
+            domKey: uuid10(4),
+            'value': `${this.normalAreaValue}`
+          }
+        ],
+        'depth': this.menuData.depth + 1,
+        'fromUser': true,
+        'hiddenAncestor': null,
+        'isVisible': true,
+        domKey: uuid10(4),
+        'title': `${this.normalAreaName}`,
+        'type': 'Head2'
+      }
+
+      // 添加同级子项
+      // 添加子项
+      if (this.titleName === '添加同级子项') {
+        params.depth = this.menuData.depth
+        if (this.menuData.depth === 0) {
+          params.type = 'Head1'
+        }
+        this.$store.commit('monthlyReportEdit/ADD_ITEM', {
+          domKey: this.menuData.domKey, params: { ...params }
+        })
+      }
+      if (this.titleName === '添加子项') {
+        this.$store.commit('monthlyReportEdit/ADD_ITEM', {
+          domKey: this.menuData.domKey, params: { ...params }, isSub: true
+        })
+      }
+      this.modalClose()
+    },
+    modalClose() {
+      this.normalAreaName = ''
+      this.menuData = ''
+      this.normalAreaValue = ''
+      this.modalShow = false
+    }
+  }
+
+}
+</script>

+ 146 - 0
src/views/monthlyReport/childrenPage/editReport/components/menu.vue

@@ -0,0 +1,146 @@
+<template>
+  <!--  左侧菜单 :class="{ hide: show }"  -->
+  <div>
+    <div
+      v-if="menuData && menuData.item"
+      class="left-menu-wrapper"
+      :style="menuStyle"
+      :class="{ hide: show }"
+    >
+      <el-dropdown-item
+      ><div @click.stop="hideDom">
+        <!--
+        menuData.item.isVisible === true
+           判断 当前点击元素 是否为用户自定义dom
+           menuData.item.fromUser === true  '删除'
+           menuData.item.fromUser === false '隐藏'
+
+         menuData.item.isVisible === false'显示'
+           -->
+        {{
+          menuData.item.isVisible
+            ? menuData.item.fromUser
+            ? '删除'
+            : '隐藏'
+            : '显示'
+        }}
+      </div></el-dropdown-item
+      >
+      <el-dropdown-item><div @click="addItem('添加同级子项')">添加同级子项</div></el-dropdown-item>
+      <el-dropdown-item v-if="menuData.item.depth<4"><div @click="addItem('添加子项')">添加下级子项</div></el-dropdown-item>
+    </div>
+    <createdItem ref="createdItem" />
+  </div>
+</template>
+
+<script>
+import createdItem from './createdItem'
+export default {
+  name: 'Menu',
+  // watch: {
+  //   menuData: {
+  //     handler() {
+  //       this.init()
+  //     },
+  //     deep: true
+  //   }
+  // },
+  components: { createdItem },
+  // props: {
+  //   menuData: {
+  //     type: Object,
+  //     require: false,
+  //     default: () => {}
+  //   }
+  // },
+  data() {
+    return {
+      show: false,
+      timeout: null,
+      menuData: {},
+      menuStyle: {}
+    }
+  },
+  methods: {
+    init(menuData) {
+      this.menuData = { ...menuData }
+      const { clientWidth, clientHeight } = document.documentElement
+      let clientX = this.menuData.event.clientX + 10
+      let clientY = this.menuData.event.clientY + 10
+      if (clientWidth - clientX < 200) {
+        clientX = clientX - 70
+      }
+      if (clientHeight - clientY < 200) {
+        clientY = clientY - 100
+      }
+      this.menuStyle = {
+        left: `${clientX + 10}px`,
+        top: `${clientY + 15}px`
+      }
+      setTimeout(() => {
+        this.show = false
+      }, 200)
+    },
+    closeMenu() {
+      clearTimeout(this.timeout)
+      this.timeout = setTimeout(() => {
+        this.show = true
+      }, 100)
+    },
+    // 控制左侧dom的显示隐藏
+    hideDom() {
+      setTimeout(() => {
+        this.show = true
+      }, 300)
+      const { item } = this.menuData
+      // 如果是自定义的话
+      // 不能设置
+      if (item.fromUser && item.hiddenAncestor !== 'stop') {
+        this.$store.commit('monthlyReportEdit/DELETE_ITEM', item.domKey)
+        return
+      }
+      if (
+        item.hasOwnProperty('hiddenAncestor') &&
+        item.hiddenAncestor === 'stop'
+      ) {
+        return this.$message.warning('当前元素无法操作!')
+      }
+      item.isVisible = !item.isVisible
+      // 设置子集:添加 hiddenAncestor 字段
+      const setHiddenAncestor = (arr) => {
+        arr.forEach((elm) => {
+          elm.hiddenAncestor = item.isVisible ? 'none' : 'stop'
+          elm.isVisible = item.isVisible
+          if (elm.children && elm.children.length) {
+            setHiddenAncestor(elm.children)
+          }
+        })
+      }
+      if (item.children && item.children.length) {
+        setHiddenAncestor(item.children)
+      }
+    },
+    // 添加同级子项
+    addItem(title) {
+      this.$refs.createdItem.openModal(title, this.menuData.item)
+    },
+    // 添加下级子项
+    addSubItem() {
+
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.left-menu-wrapper {
+  position: fixed;
+  z-index: 90;
+  background: #ffffff;
+  box-shadow: 0 0 33px rgba(74, 81, 100, 0.12);
+
+  &.hide {
+    display: none;
+  }
+}
+</style>

+ 64 - 0
src/views/monthlyReport/childrenPage/editReport/deepSearch.js

@@ -0,0 +1,64 @@
+import _ from 'lodash'
+
+// 类别页面全局查询
+export function searchLabelChange(value, tableList, datacopy, columns) {
+  const searchData = _.cloneDeep(datacopy)
+  // const self = this;
+  if (value.item === 'clear' || !value.value) {
+    tableList = searchData
+    return
+  }
+  // 模糊查询
+  const allSearch = () => {
+    const columnsShadows = []
+    if (value.item === 'all') {
+      // 处理 columns 中的多余属性
+      columns.forEach((elm) => {
+        const columnItem = _.cloneDeep(elm)
+        if (columnItem.key !== 'dataSource' || columnItem.key !== 'operation') {
+          columnsShadows.push(columnItem.key)
+        }
+      })
+    } else {
+      columnsShadows.push(value.item.key)
+    }
+    // 递归便利数据,设置是否展示
+    function tree(treeData) {
+      treeData.forEach((elm) => {
+        elm.isShow = false
+        columnsShadows.forEach((columnsElm) => {
+          if (elm[columnsElm] && elm[columnsElm].search(value.value) > -1) {
+            elm.isShow = true
+          }
+        })
+        if (elm.children) {
+          tree(elm.children)
+        }
+      })
+    }
+    tree(searchData)
+    function treeFilter(treeData) {
+      const elm = []
+      for (let i = 0; i < treeData.length; i++) {
+        const item = JSON.parse(JSON.stringify(treeData[i]))
+        if (treeData[i].isShow) {
+          elm.push(item)
+          if (treeData[i].children && treeData[i].children.length) {
+            item.children = treeFilter(treeData[i].children)
+            if (!item.children.length) {
+              delete item.children
+            }
+          }
+        } else if (treeData[i].children && treeData[i].children.length) {
+          elm.push.apply(elm, treeFilter(treeData[i].children)) // eslint-disable-line
+        }
+      }
+      return elm
+    }
+    // console.log('searchData', JSON.stringify(searchData));
+    const a = treeFilter(searchData)
+    // self.deleteChildren(a);
+    return a
+  }
+  return allSearch()
+}

+ 208 - 131
src/views/monthlyReport/childrenPage/editReport/index.vue

@@ -1,52 +1,60 @@
 <template>
   <div ref="pageWrapper" class="page-wrapper" @click="setInit">
-    <!--    :target="() => $refs.pageWrapper"-->
-    <!--    <Affix :offset-top="30" :target="() => $refs.pageWrapper.parentNode">-->
-    <!--      <el-button type="danger" size="small">测试</el-button>-->
-    <!--    </Affix>-->
-    <!--  header  -->
-    <headerCom title="月报" sub-title="新建月报" />
-
+    <headerCom title="月报" sub-title="新建月报">
+      <template slot="content">
+        <el-button
+type="primary"
+size="small"
+@click="upDateReport"
+        >保存
+        </el-button>
+        <el-button plain size="small">发送确认</el-button>
+        <el-button plain size="small">取消</el-button>
+        <el-button plain size="small">删除</el-button>
+      </template>
+    </headerCom>
+    <div style="position: fixed;z-index: 99; top: 20px">
+      <el-button type="primary" @click="test">test</el-button>
+    </div>
     <!--  content  -->
     <div class="content-wrapper">
-      <div class="left-wrapper">
-        <el-button size="small">默认按钮</el-button>
-        <el-button type="primary" size="small">主要按钮</el-button>
-        <el-button type="success" size="small">成功按钮</el-button>
-        <el-button type="info" size="small">信息按钮</el-button>
-        <el-button type="warning" size="small">警告按钮</el-button>
-        <el-button type="danger" size="small"> 危险按钮</el-button>
-        <div id="user_0">user_0</div>
-        <div v-for="i in 70" :key="i">
-          <el-button type="danger" size="small">测试</el-button>
+      <el-tabs :value="tabsActive" @tab-click="tabClick">
+        <el-tab-pane
+          v-for="item in tabsList"
+          :key="item.name"
+          :label="item.label"
+          :name="item.name"
+        />
+      </el-tabs>
+      <div class="body-wrapper">
+        <div class="left-wrapper">
+          <div v-if="tabPageShow">
+            <Croe
+              v-for="item in tabPageData.children"
+              :key="item.domKey"
+              :base-data="item"
+            />
+          </div>
         </div>
-        <div id="user_2_2_0">user_2_2_0</div>
-        <div v-for="i in 70" :key="`${i}btn`">
-          <el-button size="small">默认按钮</el-button>
-          <el-button type="primary" size="small">主要按钮</el-button>
-          <el-button type="success" size="small">成功按钮</el-button>
-          <el-button type="info" size="small">信息按钮</el-button>
-          <el-button type="warning" size="small">警告按钮</el-button>
+        <div class="right-wrapper">
+          <Affix
+            ref="affix"
+            v-clickoutside="$refs.menu && $refs.menu.closeMenu"
+            :listen-time="100"
+            :offset-top="178"
+            :target="() => $refs.pageWrapper.parentNode"
+            @change="userFun"
+          >
+            <Anchor
+              :list="tabPageData && tabPageData.children"
+              :active="anchorActive"
+              @change="anchorChange"
+              @openMenu="openMenu"
+            />
+            <Menu ref="menu" />
+          </Affix>
         </div>
       </div>
-      <div class="right-wrapper">
-        <Affix :listen-time="100" :user-fun="userFun" :offset-top="103" :target="() => $refs.pageWrapper.parentNode">
-          <Anchor
-            :list="list"
-            :active="anchorActive"
-            @change="anchorChange"
-            @openMenu="openMenu"
-          />
-          <Menu ref="menu" :menu-data="menuData">
-            <el-dropdown-item>黄金糕</el-dropdown-item>
-            <el-dropdown-item>狮子头</el-dropdown-item>
-            <el-dropdown-item>螺蛳粉</el-dropdown-item>
-            <el-dropdown-item>双皮奶</el-dropdown-item>
-            <el-dropdown-item>蚵仔煎</el-dropdown-item>
-          </Menu>
-        </Affix>
-      </div>
-
     </div>
   </div>
 </template>
@@ -55,7 +63,17 @@
 import headerCom from '../../components/header'
 import Affix from '@/components/affix/affix'
 import Anchor from '../../components/anchor'
-import Menu from '../../components/menu'
+import Menu from './components/menu'
+import reportData from './reportData'
+import Croe from './components/core'
+import Clickoutside from '_element-ui@2.15.1@element-ui/src/utils/clickoutside'
+
+Object.freeze(reportData)
+// import {
+//   getMonthlyReport,
+//   updateMonthlyReport
+// } from '@/api/qualityMonthlyReport/edit'
+// import { reportDataBack } from '@/store/modules/monthlyReport/edit/utils'
 
 export default {
   name: '',
@@ -63,123 +81,182 @@ export default {
     headerCom,
     Affix,
     Anchor,
-    Menu
+    Menu,
+    Croe
   },
+  directives: { Clickoutside },
   data() {
+    // this.userFun = _.debounce(this.userFun, 300)
     return {
-      list: [
-        {
-          name: '上月问题跟进',
-          key: 'user_0'
-        },
-        { name: '本月重点问题', key: 'user_1' },
-        {
-          name: '本月详情',
-          key: 'user_2',
-          children: [
-            {
-              name: '一、线上问题',
-              key: 'user_2_0'
-            },
-            {
-              name: '二、质量流程&研发效率',
-              key: 'user_2_1',
-              children: [
-                {
-                  name: '1、延期',
-                  key: 'user_2_1_0'
-                },
-                {
-                  name: '2、线下问题',
-                  key: 'user_2_1_1'
-                }
-              ]
-            },
-            {
-              name: '三、发布质量',
-              key: 'user_2_2',
-              children: [
-                {
-                  name: '1、发布&回滚',
-                  key: 'user_2_2_0'
-                }
-              ]
-            }
-          ]
-        },
-        { name: '本月优秀', key: 'user_3' }
-      ],
+      /* 右侧列表页数据 */
       anchorActive: '',
       scrollTop: 0,
-      menuData: null
+      reportData
     }
   },
-  methods: {
-    anchorChange(item) {
-      this.anchorActive = item.key
-      const anchor = document.getElementById(`${item.key}`) // 参数为要跳转到的元素id
-      if (!anchor) {
-        return (this.$el.parentNode.scrollTop = 0)
-      }
-      this.$el.parentNode.scrollTop = anchor.offsetTop + 83 // chrome
-      // this.$el.scrollTop = anchor.offsetTop // firefox
+  computed: {
+    tabPageShow() {
+      return (
+        this.tabPageData &&
+        this.tabPageData.children &&
+        this.tabPageData.children.length
+      )
     },
-    openMenu({ event, item }) {
-      this.menuData = { event, item }
-      // console.log(event, item)
+    tabPageData() {
+      return this.$store.state.monthlyReportEdit.tabPageData
+    },
+    tabsList() {
+      return this.$store.state.monthlyReportEdit.tabsList
+    },
+    tabsActive() {
+      return this.$store.state.monthlyReportEdit.tabsActive
+    },
+    treeData() {
+      return this.$store.state.monthlyReportEdit.treeData
+    },
+    subTabsActive() {
+      return this.$store.state.monthlyReportEdit.subTabsActive
+    },
+    domKeys() {
+      return this.$store.state.monthlyReportEdit.domKeys
     },
+    offsetList() {
+      return this.$store.state.monthlyReportEdit.offsetList
+    }
+  },
+  watch: {
+    subTabsActive() {
+      this.$refs.affix.init()
+    }
+  },
+  mounted() {
+    if (this.$route.query.reportId) {
+      this.$store.dispatch(
+        'monthlyReportEdit/initPageData',
+        this.$route.query.reportId
+      )
+      // this.getPageData(this.$route.query.reportId)
+    }
+  },
+  methods: {
     setInit() {
       // window.addEventListener('click', () => {
       //   this.$refs.menu.show = true
       //   console.log(127)
       // })
     },
-    userFun() {
-      const getOffsetTop = (id) => {
-        return document.getElementById(id).offsetTop
+    anchorChange(item) {
+      // 获取元素到文档区域的坐标
+      const getPosition = (element) => {
+        var actualLeft = element.offsetLeft
+        var actualTop = element.offsetTop
+        var current = element.offsetParent // 取得元素的offsetParent
+        // 一直循环直到根元素
+        while (current !== null) {
+          actualLeft += current.offsetLeft
+          actualTop += current.offsetTop
+          current = current.offsetParent
+        }
+        // 返回包含left、top坐标的对象
+        return {
+          left: actualLeft,
+          top: actualTop
+        }
       }
-      console.log(136)
-      const list = [
-        {
-          key: 'user_0',
-          offsetTop: getOffsetTop('user_0')
-        }, {
-          key: 'user_2_2_0',
-          offsetTop: getOffsetTop('user_2_2_0')
+      this.anchorActive = item.domKey
+      const anchor = document.getElementById(`${item.domKey}`) // 参数为要跳转到的元素id
 
-        }]
-      // console.log(this.$refs.pageWrapper.parentElement.scrollTop)
-      this.scrollTop = this.$refs.pageWrapper.parentElement.scrollTop
-      this.anchorActive = ''
-      list.forEach(elm => {
-        console.log(Math.abs(this.scrollTop - elm.offsetTop), 145)
-        if (Math.abs(this.scrollTop - elm.offsetTop) < 100) {
-          this.anchorActive = elm.key
+      if (!anchor) {
+        return (this.$el.parentNode.scrollTop = 0)
+      }
+      const { top } = getPosition(anchor)
+      this.$el.parentNode.scrollTop = top // chrome
+    },
+    openMenu({ event, item }) {
+      this.$refs.menu.init({ event, item })
+      // console.log(event, item)
+    },
+    userFun({ scrollTop }) {
+      this.$nextTick(() => {
+        if (!this.tabPageData || !this.tabPageData.children) return false
+        this.$refs.menu && this.$refs.menu.closeMenu()
+        // this.anchorActive = ''
+        const getOffsetTop = (id) => {
+          const dom = document.getElementById(id)
+          if (!dom) return 0.9527
+          return dom.getBoundingClientRect().top
+        }
+        const setActive = (key) => {
+          const offsetTop = getOffsetTop(key)
+          if (offsetTop && offsetTop !== 0.9527 && Math.abs(offsetTop) < 50) {
+            this.anchorActive = key
+          }
+        }
+        const setList = (arr) => {
+          arr.forEach((elm) => {
+            if (elm.domKey) {
+              setActive(elm.domKey)
+            }
+            if (elm.content && elm.content.length) {
+              elm.content.forEach((item) => {
+                if (item.domKey) {
+                  setActive(item.domKey)
+                }
+              })
+            }
+            if (elm.children && elm.children.length) {
+              setList(elm.children)
+            }
+          })
         }
+        // 每次 scroll 事件结束之后,递归计算各个标签距离窗口顶部的位置
+        setList(this.tabPageData.children)
       })
+    },
+    // 月报更新
+    upDateReport() {
+      this.$store.dispatch('monthlyReportEdit/upDateReport')
+    },
+    test() {
+      console.log(this.tabPageData)
+      // console.log(this.$store.state.monthlyReportEdit.reportData[0].children[0].content[0].tableRows[0])
+      // console.log(this.subTabsActive)
+      // console.log(JSON.stringify(this.offsetList, null, 2))
+      // console.log(JSON.stringify(this.$store.state.monthlyReportEdit.reportData[0].children[0].content[0].tableRows[0], null, 2))
+    },
+    tabClick(tab, event) {
+      // console.log(tab.name, event)
+      this.$store.commit('monthlyReportEdit/TAB_ACTIVE_CHANGE', tab.name)
+      // this.$nextTick(() => {
+      //   this.$store.commit('monthlyReportEdit/GET_ALL_OFFSETTOP')
+      // })
     }
   }
-  // destroyed() {
-  //   window.removeEventListener('click', () => {
-  //     this.$refs.menu.show = true
-  //   })
-  // }
 }
 </script>
 <style scoped lang='less'>
 @import '../../style';
 
 .content-wrapper {
-  display: flex;
-
-  .left-wrapper {
-    flex: 1;
-    width: 100%;
+  /deep/ .el-tabs__nav-wrap::after {
+    height: 1px;
   }
 
-  .right-wrapper {
-    flex: 1 1 0;
-    display: contents;
+  .body-wrapper {
+    display: grid;
+    grid-template-columns: calc(100% - 190px) 190px;
+    //grid-template-rows: 100px 100px 100px;
+
+    .left-wrapper {
+      //flex: 1;
+      //width: 100%;
+      padding-right: 20px;
+    }
+
+    .right-wrapper {
+      //flex: 1 1 0;
+      //display: contents;
+    }
   }
 }
 </style>

+ 1233 - 0
src/views/monthlyReport/childrenPage/editReport/newData.js

@@ -0,0 +1,1233 @@
+export const pageData = {
+  id: 1,
+  reportName: '月报名称',
+  status: '', // 0新建、1待确认、2已确认、3已发布
+  startTime: '', // 起始时间
+  endTime: '', // 结束时间
+  deadline: '', // 截止时间
+  createTime: '', // 创建时间
+  modifyTime: '', // 更新时间
+  createBy: '', // 创建人
+  subReports: [
+    {
+      id: 2,
+      parentId: 'parentId',
+      reportName: '两轮车',
+      isServerAndClient: 0, // 是否双端 0否 1是
+      confirmer: '', // 确认人 ,分割
+      createTime: '', // 创建时间
+      modifyTime: '', // 更新时间
+      modifyBy: '', // 最近修改人
+      reportCatalog: {
+        children: [
+          {
+            type: 'Head1', // 类型:TAG1|Head1|TAG2|Head2
+            title: '上个月问题跟进', // 标题
+            depth: '1', // 深度
+            isVisible: true, // 是否展示
+            content: [
+              {
+                type: 'table', // 分为表格、固定文本、富文本、文本加表格四种内容类型
+                name: '', // 文本头
+                value: '', // 文本内容
+                tableHeaders: [
+                  {
+                    name: '团队', //
+                    type: 'team', // 自定义数据类型
+                    dataType: 'Single', // Single单个数据,Multiple多个数据
+                    displayType: 'Select', // Select|Cascader|Text|Input|Button组件类型
+                    defaultValue: {
+                      value: '', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    selectEnum: [
+                      {
+                        value: '选项1',
+                        label: '黄金糕'
+                      },
+                      {
+                        value: '选项2',
+                        label: '双皮奶'
+                      },
+                      {
+                        value: '选项3',
+                        label: '蚵仔煎'
+                      },
+                      {
+                        value: '选项4',
+                        label: '龙须面'
+                      },
+                      {
+                        value: '选项5',
+                        label: '北京烤鸭'
+                      }
+                    ]
+                  },
+                  {
+                    name: '问题', //
+                    type: 'issues', // 自定义数据类型
+                    dataType: 'Single', // Single单个数据,Multiple多个数据
+                    displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                    defaultValue: {
+                      value: '', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    selectEnum: []
+                  },
+                  {
+                    name: '改进项', //
+                    type: 'improvements', // 自定义数据类型
+                    dataType: 'Single', // Single单个数据,Multiple多个数据
+                    displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                    defaultValue: {
+                      value: '', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    selectEnum: []
+                  },
+                  {
+                    name: '达成情况', //
+                    type: 'achievement', // 自定义数据类型
+                    dataType: 'Single', // Single单个数据,Multiple多个数据
+                    displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                    defaultValue: {
+                      value: '', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    selectEnum: []
+                  },
+                  {
+                    name: '操作', //
+                    dataType: 'Single', // Single单个数据,Multiple多个数据
+                    displayType: 'Button', // Select|Cascader|Text|Input|Button组件类型
+                    defaultValue: [
+                      {
+                        value: '删除', // 表格展示数据
+                        buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                        operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                      },
+                      {
+                        value: '标记', // 表格展示数据
+                        buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                        operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                      }
+                    ],
+                    selectEnum: []
+                  }
+                ],
+                tableRows: [
+                  [
+                    {
+                      value: '资产管理组', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '问题', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '改进项', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '达成情况', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  [
+                    {
+                      value: '资产管理组', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '问题', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '改进项', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '达成情况', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  [
+                    {
+                      value: '资产管理组', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '问题', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '改进项', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '达成情况', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  [
+                    {
+                      value: '资产管理组', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '问题', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '改进项', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '达成情况', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  [
+                    {
+                      value: '资产管理组', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '问题', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+
+                    {
+                      value: '改进项', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '达成情况', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ]
+                ]
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      id: 3,
+      parentId: 'parentId',
+      reportName: '代驾',
+      isServerAndClient: 0, // 是否双端 0否 1是
+      confirmer: '', // 确认人 ,分割
+      createTime: '', // 创建时间
+      modifyTime: '', // 更新时间
+      modifyBy: '', // 最近修改人
+      reportCatalog: [
+        {
+          type: 'Head1', // 类型:TAG1|Head1|TAG2|Head2
+          title: '上个月问题跟进', // 标题
+          depth: '1', // 深度
+          isVisible: true, // 是否展示
+          content: [
+            {
+              type: 'table', // 分为表格、固定文本、富文本、文本加表格四种内容类型
+              name: '', // 文本头
+              value: '', // 文本内容
+              tableHeaders: [
+                {
+                  name: '团队', //
+                  type: 'team', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Select', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: [
+                    {
+                      value: '选项1',
+                      label: '黄金糕'
+                    },
+                    {
+                      value: '选项2',
+                      label: '双皮奶'
+                    },
+                    {
+                      value: '选项3',
+                      label: '蚵仔煎'
+                    },
+                    {
+                      value: '选项4',
+                      label: '龙须面'
+                    },
+                    {
+                      value: '选项5',
+                      label: '北京烤鸭'
+                    }
+                  ]
+                },
+                {
+                  name: '问题', //
+                  type: 'issues', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '改进项', //
+                  type: 'improvements', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '达成情况', //
+                  type: 'achievement', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '操作', //
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Button', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: [
+                    {
+                      value: '删除', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '标记', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  selectEnum: []
+                }
+              ],
+              tableRows: [
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ]
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      id: 4,
+      parentId: 'parentId',
+      reportName: '货运',
+      isServerAndClient: 0, // 是否双端 0否 1是
+      confirmer: '', // 确认人 ,分割
+      createTime: '', // 创建时间
+      modifyTime: '', // 更新时间
+      modifyBy: '', // 最近修改人
+      reportCatalog: [
+        {
+          type: 'Head1', // 类型:TAG1|Head1|TAG2|Head2
+          title: '上个月问题跟进', // 标题
+          depth: '1', // 深度
+          isVisible: true, // 是否展示
+          content: [
+            {
+              type: 'table', // 分为表格、固定文本、富文本、文本加表格四种内容类型
+              name: '', // 文本头
+              value: '', // 文本内容
+              tableHeaders: [
+                {
+                  name: '团队', //
+                  type: 'team', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Select', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: [
+                    {
+                      value: '选项1',
+                      label: '黄金糕'
+                    },
+                    {
+                      value: '选项2',
+                      label: '双皮奶'
+                    },
+                    {
+                      value: '选项3',
+                      label: '蚵仔煎'
+                    },
+                    {
+                      value: '选项4',
+                      label: '龙须面'
+                    },
+                    {
+                      value: '选项5',
+                      label: '北京烤鸭'
+                    }
+                  ]
+                },
+                {
+                  name: '问题', //
+                  type: 'issues', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '改进项', //
+                  type: 'improvements', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '达成情况', //
+                  type: 'achievement', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '操作', //
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Button', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: [
+                    {
+                      value: '删除', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '标记', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  selectEnum: []
+                }
+              ],
+              tableRows: [
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ]
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      id: 5,
+      parentId: 'parentId',
+      reportName: '中台',
+      isServerAndClient: 0, // 是否双端 0否 1是
+      confirmer: '', // 确认人 ,分割
+      createTime: '', // 创建时间
+      modifyTime: '', // 更新时间
+      modifyBy: '', // 最近修改人
+      reportCatalog: [
+        {
+          type: 'Head1', // 类型:TAG1|Head1|TAG2|Head2
+          title: '上个月问题跟进', // 标题
+          depth: '1', // 深度
+          isVisible: true, // 是否展示
+          content: [
+            {
+              type: 'table', // 分为表格、固定文本、富文本、文本加表格四种内容类型
+              name: '', // 文本头
+              value: '', // 文本内容
+              tableHeaders: [
+                {
+                  name: '团队', //
+                  type: 'team', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Select', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: [
+                    {
+                      value: '选项1',
+                      label: '黄金糕'
+                    },
+                    {
+                      value: '选项2',
+                      label: '双皮奶'
+                    },
+                    {
+                      value: '选项3',
+                      label: '蚵仔煎'
+                    },
+                    {
+                      value: '选项4',
+                      label: '龙须面'
+                    },
+                    {
+                      value: '选项5',
+                      label: '北京烤鸭'
+                    }
+                  ]
+                },
+                {
+                  name: '问题', //
+                  type: 'issues', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '改进项', //
+                  type: 'improvements', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '达成情况', //
+                  type: 'achievement', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '操作', //
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Button', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: [
+                    {
+                      value: '删除', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '标记', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  selectEnum: []
+                }
+              ],
+              tableRows: [
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '中台,达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ]
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      id: 6,
+      parentId: 'parentId',
+      reportName: '硬件',
+      isServerAndClient: 0, // 是否双端 0否 1是
+      confirmer: '', // 确认人 ,分割
+      createTime: '', // 创建时间
+      modifyTime: '', // 更新时间
+      modifyBy: '', // 最近修改人
+      reportCatalog: [
+        {
+          type: 'Head1', // 类型:TAG1|Head1|TAG2|Head2
+          title: '上个月问题跟进', // 标题
+          depth: '1', // 深度
+          isVisible: true, // 是否展示
+          content: [
+            {
+              type: 'table', // 分为表格、固定文本、富文本、文本加表格四种内容类型
+              name: '', // 文本头
+              value: '', // 文本内容
+              tableHeaders: [
+                {
+                  name: '团队', //
+                  type: 'team', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Select', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: [
+                    {
+                      value: '选项1',
+                      label: '黄金糕'
+                    },
+                    {
+                      value: '选项2',
+                      label: '双皮奶'
+                    },
+                    {
+                      value: '选项3',
+                      label: '蚵仔煎'
+                    },
+                    {
+                      value: '选项4',
+                      label: '龙须面'
+                    },
+                    {
+                      value: '选项5',
+                      label: '北京烤鸭'
+                    }
+                  ]
+                },
+                {
+                  name: '问题', //
+                  type: 'issues', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '改进项', //
+                  type: 'improvements', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '达成情况', //
+                  type: 'achievement', // 自定义数据类型
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Input', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: {
+                    value: '', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  selectEnum: []
+                },
+                {
+                  name: '操作', //
+                  dataType: 'Single', // Single单个数据,Multiple多个数据
+                  displayType: 'Button', // Select|Cascader|Text|Input|Button组件类型
+                  defaultValue: [
+                    {
+                      value: '删除', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    },
+                    {
+                      value: '标记', // 表格展示数据
+                      buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                      operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                    }
+                  ],
+                  selectEnum: []
+                }
+              ],
+              tableRows: [
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ],
+                [
+                  {
+                    value: '资产管理组', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '问题', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+
+                  {
+                    value: '改进项', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  },
+                  {
+                    value: '达成情况', // 表格展示数据
+                    buttonType: '', // 按钮类型,当该列TableHeader的displayType=Button才有
+                    operationTarget: '' // 按钮操作目标,当buttonType=SIGN才有
+                  }
+                ]
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+
+export const treeData = [
+  {
+    name: '上月问题跟进',
+    key: 'user_0'
+  },
+  { name: '本月重点问题', key: 'user_1' },
+  {
+    name: '本月详情',
+    key: 'user_2',
+    children: [
+      {
+        name: '一、线上问题',
+        key: 'user_2_0'
+      },
+      {
+        name: '二、质量流程&研发效率',
+        key: 'user_2_1',
+        children: [
+          {
+            name: '1、延期',
+            key: 'user_2_1_0'
+          },
+          {
+            name: '2、线下问题',
+            key: 'user_2_1_1'
+          }
+        ]
+      },
+      {
+        name: '三、发布质量',
+        key: 'user_2_2',
+        children: [
+          {
+            name: '1、发布&回滚',
+            key: 'user_2_2_0'
+          }
+        ]
+      }
+    ]
+  },
+  { name: '本月优秀', key: 'user_3' }
+]

文件差異過大導致無法顯示
+ 2570 - 0
src/views/monthlyReport/childrenPage/editReport/reportData.js


+ 146 - 27
src/views/monthlyReport/components/anchor.vue

@@ -1,36 +1,77 @@
 <template>
-  <div v-if="list.length" class="anchor-wrapper">
-    <div v-if="list.length > 1" class="line" />
-    <div v-for="(item, index) in list" :key="item.key" class="title-wrapper">
+  <div v-if="list && list.length" class="anchor-wrapper">
+    <!--
+如果是TAG的话
+  循环
+    判断当前tabs焦点,符合的话,调用当前组件
+  不符合条件
+    正常渲染-->
+    <div v-if="list[0].type === 'Tag'">
+      <div v-for="item in list" :key="item.domKey" class="title-wrapper">
+        <div v-if="item.children && item.children.length">
+          <Anchor
+            v-if="isShow(item)"
+            :active="active"
+            :parent-dome-key="item.domKey"
+            :list="item.children"
+            @change="(item) => change(item)"
+            @mouseMoveItem="mouseMoveItem"
+            @openMenu="(val) => openMenu(val.event, val.item)"
+          />
+        </div>
+      </div>
+    </div>
+    <div v-else>
+      <div v-if="list.length > 1" class="line" />
       <div
-        v-if="index === 0 || index === list.length - 1"
-        class="radius"
-        :class="{
-          down: list.length > 1 && index === list.length - 1,
-          center: list.length === 1
-        }"
-      />
-      <el-tooltip
-        class="item"
-        effect="dark"
-        :enterable="true"
-        :content="item.name"
-        placement="top-start"
+        v-for="(item, index) in list"
+        :key="item.domKey"
+        class="title-wrapper"
       >
         <div
-          class="mi"
-          @contextmenu.prevent="openMenu($event, item)"
-          @click="change(item)"
-          @mousemove="mouseMoveItem({ event: $event, item })"
+          v-if="index === 0 || index === list.length - 1"
+          class="radius"
+          :class="{
+            down: list.length > 1 && index === list.length - 1,
+            center: list.length === 1
+          }"
+        />
+        <el-tooltip
+          class="item"
+          effect="dark"
+          :enterable="true"
+          :content="item.title"
+          placement="top-start"
         >
-          <span class="title" :class="{ active: active === item.key }">
-            {{ item.name }}</span
+          <div
+            class="mi"
+            :class="{hide: !item.isVisible}"
+            @contextmenu.prevent="openMenu($event, item)"
+            @click="change(item)"
+            @mousemove="mouseMoveItem({ event: $event, item })"
           >
-        </div>
-      </el-tooltip>
+            <span class="title" :class="{ active: active === item.domKey, hide: !item.isVisible}">
+              {{ item.title }}</span
+            >
+          </div>
+        </el-tooltip>
 
+        <span v-if="item.children && item.children.length">
+          <Anchor
+            :active="active"
+            :parent-dome-key="item.domKey"
+            :list="item.children"
+            @change="(item) => change(item)"
+            @mouseMoveItem="mouseMoveItem"
+            @openMenu="(val) => openMenu(val.event, val.item)"
+          />
+        </span>
+      </div>
+    </div>
+    <!--    <div v-if="list[0].type === 'TAG1'">
       <span v-if="item.children && item.children.length">
         <Anchor
+          v-if="isShow(item)"
           :active="active"
           :list="item.children"
           @change="(item) => change(item)"
@@ -38,7 +79,54 @@
           @openMenu="(val) => openMenu(val.event, val.item)"
         />
       </span>
-    </div>
+    </div>-->
+    <!--    <div>
+      <div v-if="list.length > 1 && list[0].type !== 'TAG1'" class="line" />
+      <div
+        v-for="(item, index) in list"
+        :key="item.domKey"
+        class="title-wrapper"
+      >
+        <div v-if="isShow(item)">
+          <div
+            v-if="index === 0 || index === list.length - 1"
+            class="radius"
+            :class="{
+              down: list.length > 1 && index === list.length - 1,
+              center: list.length === 1
+            }"
+          />
+          <el-tooltip
+            class="item"
+            effect="dark"
+            :enterable="true"
+            :content="item.title"
+            placement="top-start"
+          >
+            <div
+              class="mi"
+              @contextmenu.prevent="openMenu($event, item)"
+              @click="change(item)"
+              @mousemove="mouseMoveItem({ event: $event, item })"
+            >
+              <span class="title" :class="{ active: active === item.domKey }">
+                {{ item.domKey }}</span
+              >
+            </div>
+          </el-tooltip>
+
+          <span v-if="item.children && item.children.length">
+            <Anchor
+              :active="active"
+              :list="item.children"
+              @change="(item) => change(item)"
+              @mouseMoveItem="mouseMoveItem"
+              @openMenu="(val) => openMenu(val.event, val.item)"
+            />
+          </span>
+        </div>
+      </div>
+    </div>-->
   </div>
 </template>
 
@@ -57,6 +145,11 @@ export default {
       type: String,
       require: false,
       default: () => ''
+    },
+    parentDomeKey: {
+      type: String,
+      require: false,
+      default: () => 'top'
     }
   },
   data() {
@@ -64,6 +157,11 @@ export default {
       tooltipValue: false
     }
   },
+  computed: {
+    subTabsActive() {
+      return this.$store.state.monthlyReportEdit.subTabsActive
+    }
+  },
   methods: {
     mouseMoveItem(event, item) {
       // console.log(event, item, 66)
@@ -72,6 +170,23 @@ export default {
     change(item) {
       this.$emit('change', item)
     },
+    isShow(item) {
+      if (item.type === 'Tag') {
+        // console.log(this.subTabsActive.indexOf(item.domKey))
+        return this.subTabsActive.indexOf(item.domKey) > -1
+      }
+      return true
+      //
+      // let show = ''
+      // if (this.subTabsActive && this.list) {
+      //   this.list.forEach(elm => {
+      //     if (this.subTabsActive.indexOf(elm.domKey) > -1) {
+      //       show = elm.domKey
+      //     }
+      //   })
+      // }
+      // return show !== ''
+    },
     openMenu(event, item) {
       this.tooltipValue = false
       this.hide = false
@@ -81,7 +196,7 @@ export default {
 }
 </script>
 
-<style scoped lang='less'>
+<style scoped lang="less">
 .anchor-wrapper {
   background-color: #ffffff;
   position: relative;
@@ -91,7 +206,7 @@ export default {
   .title-wrapper {
     margin-top: 5px;
     margin-left: 10px;
-    padding-left: 10px;
+    padding-left: 5px;
     position: relative;
 
     .title {
@@ -106,6 +221,10 @@ export default {
       &.hide:hover {
         color: #999999;
       }
+
+      &.visible{
+        color: #999999;
+      }
     }
 
     .title.hide,

+ 14 - 5
src/views/monthlyReport/components/menu.vue

@@ -40,9 +40,19 @@ export default {
   },
   methods: {
     init() {
+      const { clientWidth, clientHeight } = document.documentElement
+      let clientX = this.menuData.event.clientX + 10
+      let clientY = this.menuData.event.clientY + 10
+      console.log(clientX, clientY)
+      if (clientWidth - clientX < 200) {
+        clientX = clientX - 200
+      }
+      if (clientHeight - clientY < 200) {
+        clientY = clientY - 200
+      }
       this.menuStyle = {
-        left: `${this.menuData.event.clientX + 10}px`,
-        top: `${this.menuData.event.clientY + 15}px`
+        left: `${clientX + 10}px`,
+        top: `${clientY + 15}px`
       }
       setTimeout(() => {
         this.show = false
@@ -57,7 +67,6 @@ export default {
   }
 }
 </script>
-
 <style scoped lang="less">
 .left-menu-wrapper {
   position: fixed;
@@ -65,8 +74,8 @@ export default {
   background: #ffffff;
   box-shadow: 0px 0px 33px rgba(74, 81, 100, 0.12);
 
-  width: 100px;
-  height: 100px;
+  min-width: 100px;
+  min-height: 100px;
 
   &.hide {
     display: none;

+ 0 - 0
test.js


部分文件因文件數量過多而無法顯示