Эх сурвалжийг харах

完整月报查看和编辑,子月报查看和编辑

洪海涛 4 жил өмнө
parent
commit
ff33a43e70

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

@@ -13,6 +13,17 @@ export function getMonthlyReport(reportId) {
   })
 }
 
+// 删除月报
+export function delMonthlyReport(reportId) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/delete',
+    method: 'get',
+    params: {
+      reportId
+    }
+  })
+}
+
 // 更新整个月报
 export function updateMonthlyReport(data) {
   return request({
@@ -30,3 +41,44 @@ export function updatSettingMonthlyReport(data) {
     data
   })
 }
+
+// 获取完整报告
+
+/**
+ *
+ * @param data[reportId]      月报ID(93|94)
+ * @param data[catalogTitle]  (上月问题跟进|本月重点问题|服务端详情|客户端详情|硬件详情|本月优秀&持续改进)
+ * @returns {*}
+ */
+export function getAllSubReportCatalog(data) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/getAllSubReportCatalog',
+    method: 'post',
+    data
+  })
+}
+
+export function updateAnalyticFeedback(data) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/updateAnalyticFeedback',
+    method: 'post',
+    data
+  })
+}
+
+export function getSubReport(params) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/subReport/get',
+    method: 'get',
+    params
+  })
+}
+
+// 获取部门数据
+export function getReportDependence(params) {
+  return request({
+    url: projectManagementUrl + '/monthlyReport/getReportDependence',
+    method: 'get',
+    params
+  })
+}

+ 189 - 13
src/store/modules/monthlyReport/edit/index.js

@@ -1,9 +1,20 @@
 import { uuid10 } from '@/utils'
 import {
   getMonthlyReport,
-  updateMonthlyReport
+  updateMonthlyReport,
+  delMonthlyReport,
+  getAllSubReportCatalog,
+  getSubReport,
+  getReportDependence
 } from '@/api/qualityMonthlyReport/edit'
-import { reportDataBack, setReportData, setTabActive, setDeptArch } from './utils'
+import {
+  reportDataBack,
+  setReportData,
+  setTabActive,
+  setDeptArch
+} from './utils'
+import { message } from '@/utils/mesDebounce'
+
 import _ from 'lodash'
 
 export default {
@@ -11,7 +22,14 @@ export default {
   namespaced: true,
   state: {
     pageDate: null,
-    tabsList: [],
+    tabsList: [
+      '上月问题跟进',
+      '本月重点问题',
+      '服务端详情',
+      '客户端详情',
+      '硬件详情',
+      '本月优秀&持续改进'
+    ],
     tabsActive: '',
     tabPageData: null, // 单个标签页数据
     treeActive: '',
@@ -22,11 +40,24 @@ export default {
     domKeys: [], // 记录所有元素区域的唯一标识
     offsetList: [],
     selectEnum: [], // 部门数据
-    pageType: 'edit'
+    userNames: [], // 人员数据
+    subTitle: '新建月报',
+    pageType: 'edit' // edit:(月报编辑和新建); readAll:(查看月报详情)
   },
   mutations: {
     // 页面基础数据赋值
     INIT_PAGE_DATA(state, params) {
+      const { pageType } = state
+      if (pageType === 'read') return
+      if (pageType === 'readAll') {
+        // 设置tabs数据
+        state.tabsList = state.tabsList.map((elm) => ({
+          label: elm,
+          name: `tab_${elm}`
+        }))
+        state.tabsActive = 'tab_上月问题跟进'
+        return
+      }
       state.pageDate = { ...params }
       delete state.pageDate.subReports
       const subReports = [...params.subReports]
@@ -55,6 +86,9 @@ export default {
     },
     // 单个tab页面数据初始化设置
     INIT_TAB_PAGE_DATA(state, tabsActive = '') {
+      console.log()
+      const { pageType } = state
+
       const setKey = (arr, depth) => {
         if (arr && arr.length) {
           arr.forEach((elm) => {
@@ -69,7 +103,11 @@ export default {
           })
         }
       }
-      // console.log(54)
+
+      if (pageType === 'readAll') {
+        state.tabsActive = tabsActive || state.tabsActive
+        return
+      }
       state.reportData.forEach((elm) => {
         setKey(elm.reportCatalog.children, 0)
       })
@@ -79,11 +117,16 @@ export default {
           `${elm.id}` === setTabActive('tab_', tabsActive || state.tabsActive)
         )
       })
+      console.log(tabPageData)
       if (tabsActive) {
         state.tabsActive = `tab_${tabsActive}`
       }
       // state.tabPageData = setReportData(tabPageData)
-      const { newObj, domKeys } = setReportData(tabPageData.reportCatalog)
+      const { newObj, domKeys } = setReportData(
+        tabPageData
+          ? tabPageData.reportCatalog
+          : state.reportData[0].reportCatalog
+      )
       state.tabPageData = newObj
       state.domKeys = domKeys
     },
@@ -114,6 +157,7 @@ export default {
         newTabPageData.reportCatalog,
         108
       )
+      state.tabsActive = `tab_${newTabsActive}`
       state.tabPageData = newObj
       state.domKeys = domKeys
       // 页面恢复待编辑状态
@@ -170,9 +214,11 @@ export default {
       //       })
     },
     // 切换tabs之后,重新生成左侧树
-    CREATE_TREE_DATA(state) {},
+    CREATE_TREE_DATA(state) {
+    },
     // 菜单添加子项setInit
-    ADD_MENU_CHILDREN(state, params) {},
+    ADD_MENU_CHILDREN(state, params) {
+    },
     // 获取子页面所有距离顶部的集合基础信息
     GET_ALL_OFFSETTOP(state) {
       const getOffsetTop = (id) => {
@@ -252,15 +298,129 @@ export default {
         addItem(tabPageData, domKey)
         state.tabPageData.children = [...tabPageData]
       }
+    },
+    // 数据初始化
+    INIT_STATE_DATA(state) {
+      state.pageDate = null
+      state.tabsList = [
+        '上月问题跟进',
+        '本月重点问题',
+        '服务端详情',
+        '客户端详情',
+        '硬件详情',
+        '本月优秀&持续改进'
+      ]
+      state.tabsActive = ''
+      state.tabPageData = null // 单个标签页数据
+      state.treeActive = ''
+      state.treeData = []
+      state.reportData = [] // 所有标签页数据
+      state.editKeys = []
+      state.subTabsActive = [] // 当前页签中所有已切换的数据
+      state.domKeys = [] // 记录所有元素区域的唯一标识
+      state.offsetList = []
+      state.selectEnum = [] // 部门数据
+      state.userNames = {} // 人员数据
+      state.pageType = 'edit'
+    },
+    // tabPageData
+    SET_TAB_PAGE_DATA(state, { data, id, tabsActive }) {
+      // 对新数据进行转换
+      const { newObj, domKeys } = setReportData(
+        {
+          children: _.cloneDeep(data)
+        },
+        108
+      )
+      // state.tabPageData = {
+      //   children: _.cloneDeep(data)
+      // }
+      state.tabPageData = newObj
+      state.domKeys = domKeys
+      // 页面恢复待编辑状态
+      state.editKeys = []
+      // 子页面页签切换,清空原来的tabs选中状态
+      state.subTabsActive = []
+      state.tabsActive = '' + tabsActive
+    },
+    // 设置人员数据,避免重复请求 userNames
+    SET_USER_NAME(state, { key, value }) {
+      if (!state.userNames.hasOwnProperty(key) && !state.userNames[key]) {
+        state.userNames[key] = value
+      }
+    },
+    // 设置月报标题
+    SET_SUB_TITLE(state, name) {
+      state.subTitle = name
+    },
+    // 获取部门数据
+    SET_SELECT_ENUM(state, params) {
+      state.selectEnum = params
+      setDeptArch(state.selectEnum)
     }
   },
   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 initPageData(
+      { commit, state, dispatch },
+      { id, subReportId, subActive }
+    ) {
+      console.log()
+      const { pageType } = state
+      if (pageType === 'readAll' || pageType === 'read') {
+        commit('INIT_PAGE_DATA')
+        dispatch('getSubReportData', {
+          id,
+          subReportId,
+          tabsActive: `tab_${subActive}`
+        })
+      } else {
+        const res = await getMonthlyReport(id)
+        if (res.code === 200 && res.data) {
+          commit('INIT_PAGE_DATA', { ...res.data })
+          commit('INIT_TAB_PAGE_DATA', subActive && `tab_${subActive}`)
+        }
+      }
+    },
+    // 页面切换 TAB_ACTIVE_CHANGE
+    tabActiveChange({ commit, state, dispatch }, { id, tabsActive }) {
+      const { pageType } = state
+      if (pageType === 'edit') {
+        return commit('TAB_ACTIVE_CHANGE', tabsActive)
+      }
+      if (pageType === 'readAll') {
+        dispatch('getSubReportData', { id, tabsActive })
+      }
+    },
+    // 获取查看月报数据
+    async getSubReportData({ commit, state }, { id, subReportId, tabsActive }) {
+      const { pageType } = state
+      let params = {}
+      const method =
+        pageType === 'readAll' ? getAllSubReportCatalog : getSubReport
+      if (pageType === 'read') {
+        params = {
+          subReportId
+        }
+      }
+      if (pageType === 'readAll') {
+        params = {
+          reportId: id,
+          catalogTitle: setTabActive('tab_', tabsActive)
+        }
+      }
+      const res = await method(params)
+      if (res.code === 200) {
+        // 单个月报与完整月报数据梳理
+        if (pageType === 'read') {
+          commit('SET_SUB_TITLE', res.data.reportName)
+        }
+        commit('SET_TAB_PAGE_DATA', {
+          data:
+            pageType === 'readAll' ? res.data : res.data.reportCatalog.children,
+          id,
+          tabsActive
+        })
       }
     },
     // 月报提交
@@ -284,6 +444,22 @@ export default {
       if (res.code === 200) {
         this.$router.push({ path: '/monthlyReport/index' })
       }
+    },
+    // 获取部门数据
+    async setSelectEnum({ commit }, reportId) {
+      const res = await getReportDependence({
+        reportId
+      })
+      if (res.code === 200) {
+        commit('SET_SELECT_ENUM', res.data.deptArch.children)
+      }
+    },
+    async deleteReport({ commit, state, context }, { key, cb }) {
+      const res = await delMonthlyReport(state.pageDate.id)
+      if (res.code === 200) {
+        message.success(`${key === 'cancel' ? '取消' : '删除'}成功!`)
+        cb()
+      }
     }
   }
 }

+ 61 - 26
src/store/modules/monthlyReport/edit/utils.js

@@ -1,5 +1,5 @@
 // import { v4 as uuidv4 } from 'uuid'
-import { uuid10 } from '@/utils'
+import { uuid10, strToArr, arrToStr } from '@/utils'
 import _ from 'lodash'
 
 // 月报标签页基础数据过滤设置
@@ -81,29 +81,48 @@ export function setTableHeader(tableHeaders) {
 export function arrToObj(arr, headerList) {
   const newObj = []
   const newArr = [...arr]
-  newArr.forEach(elm => {
+  newArr.forEach((elm) => {
     const obj = {}
-    elm.tableItems && elm.tableItems.length && elm.tableItems.forEach((item, index) => {
-      const { headerKey } = headerList[index]
-      obj[headerKey] = item.value
-      if (headerList[index].displayType && obj[headerKey]) {
-        if (headerList[index].displayType === 'Cascader') {
-          obj[headerKey] = JSON.parse(obj[headerKey])
+    // elm.tableItems && elm.tableItems.length && elm.tableItems.forEach((item, index) => {
+    headerList.forEach((helm, index) => {
+      const { headerKey, displayType, itemInfo, selectType } = helm
+      const item = elm.tableItems[index]
+      if (item) {
+        obj[headerKey] = item.value
+        if (displayType && obj[headerKey]) {
+          if (displayType === 'Cascader') {
+            obj[headerKey] = strToArr(obj[headerKey])
+          }
+          if (selectType && selectType === 'MultiplePeople') {
+            obj[headerKey] = obj[headerKey].replace(/\[|\]|'/g, '').split(',')
+          }
         }
-        if (headerList[index].selectType && headerList[index].selectType === 'MultiplePeople') {
-          obj[headerKey] = JSON.parse(obj[headerKey])
+        if (!itemInfo) {
+          headerList[index].itemInfo = _.clone(item)
         }
       }
-      if (!headerList[index].itemInfo) {
-        headerList[index].itemInfo = _.clone(item)
-      }
     })
     obj.rowKey = uuid10()
-    obj.analyticContents = elm.analyticContents
+    obj.analyticFeedback = analyticFeedbackToObj(elm.analyticFeedback)
     newObj.push(obj)
   })
   return newObj
 }
+export function analyticFeedbackToObj(obj) {
+  const newObj = _.cloneDeep(obj)
+  newObj &&
+    newObj.analyticContents &&
+    _.isArray(newObj.analyticContents) &&
+    newObj.analyticContents.forEach((elm) => {
+      _.isArray(elm.improvementItems) &&
+        elm.improvementItems.forEach((item) => {
+          item.personInCharge = item.personInCharge
+            .replace(/\[|\]|'/g, '')
+            .split(',')
+        })
+    })
+  return newObj
+}
 
 // 月报:elm组件数据转表格数据
 export function objToArr(obj, tableHeaders) {
@@ -123,10 +142,12 @@ export function objToArr(obj, tableHeaders) {
         }
         if (param.value) {
           if (item.displayType && item.displayType === 'Cascader') {
-            param.value = JSON.stringify(param.value)
+            param.value = arrToStr(param.value)
           }
           if (item.selectType && item.selectType === 'MultiplePeople') {
-            param.value = JSON.stringify(param.value)
+            // param.value = JSON.stringify(param.value)
+            // param.value = arrToStr(param.value)
+            param.value = `[${param.value.toString()}]`
           }
         }
         if (!elms.tableItems) {
@@ -135,12 +156,24 @@ export function objToArr(obj, tableHeaders) {
         elms.tableItems.push(param)
       }
     })
-    elms.analyticContents = _.clone(elm.analyticContents)
+    elms.analyticFeedback = analyticFeedbackToArr(elm.analyticFeedback)
     newArr.push(elms)
   })
   return newArr
 }
-
+export function analyticFeedbackToArr(obj) {
+  const newObj = _.cloneDeep(obj)
+  newObj &&
+    newObj.analyticContents &&
+    _.isArray(newObj.analyticContents) &&
+    newObj.analyticContents.forEach((elm) => {
+      _.isArray(elm.improvementItems) &&
+        elm.improvementItems.forEach((item) => {
+          item.personInCharge = `[${item.personInCharge.toString()}]`
+        })
+    })
+  return newObj
+}
 // 对字符串进行处理,支持正则
 export function setTabActive(reg = '', value, newValue = '') {
   const newreg = new RegExp(`${reg}`)
@@ -170,14 +203,16 @@ export function findDomKey(obj, domKey) {}
 // 设置部门数据
 export function setDeptArch(data) {
   const run = (arr) => {
-    arr && arr.length && arr.forEach(elm => {
-      if (elm.children.length) {
-        run(elm.children)
-      }
-      if (!elm.children.length) {
-        elm.children = null
-      }
-    })
+    arr &&
+      arr.length &&
+      arr.forEach((elm) => {
+        if (elm.children.length) {
+          run(elm.children)
+        }
+        if (!elm.children.length) {
+          elm.children = null
+        }
+      })
   }
   run(data)
 }

+ 26 - 0
src/utils/index.js

@@ -153,3 +153,29 @@ export function toChinesNum(num) {
   if (noWan.toString().length < 4) noWan = '0' + noWan
   return overWan ? getWan(overWan) + '万' + getWan(noWan) : getWan(num)
 }
+
+// 二维数组 转 String
+export function arrToStr(objarr) {
+  const arrLen = objarr.length
+  let row = '['
+  for (let i = 0; i < arrLen; i++) {
+    row += '['
+    for (var j = 0; j < objarr[i].length; j++) {
+      row += objarr[i][j]
+      if (j < objarr[i].length - 1) {
+        row += ','
+      }
+    }
+    row += ']'
+    if (i < arrLen - 1) {
+      row += ','
+    }
+  }
+  row += ']'
+  return row
+}
+// 字符串转二维数组
+export function strToArr(str) {
+  // eslint-disable-next-line no-eval
+  return window.eval(str)
+}

+ 261 - 0
src/views/monthlyReport/childrenPage/editReport/components/Analysis.vue

@@ -0,0 +1,261 @@
+<template>
+  <normal-dialog
+    ref="normalDialog"
+    :show-dialog="false"
+    is-succes
+    title="分析反馈"
+    width="80%"
+    @succes="updateModule"
+  >
+    <div class="box-wrapper">
+      <span v-if="analyticFeedback && analyticFeedback.analyticContents">
+        <el-form
+          v-for="(item, index) in analyticFeedback.analyticContents"
+          :key="index"
+          class="analysis-wrapper"
+        >
+          <span class="del-item">
+            <el-button
+icon="el-icon-delete"
+type="text"
+@click="delItem(index)"
+              >删除</el-button
+            >
+          </span>
+          <el-form-item label="问题" :label-width="formLabelWidth">
+            <el-input
+              v-model="item.problem"
+              size="small"
+              placeholder="请输入内容"
+            />
+          </el-form-item>
+          <el-form-item label="原因" :label-width="formLabelWidth">
+            <el-input
+              v-model="item.reason"
+              size="small"
+              placeholder="请输入内容"
+            />
+          </el-form-item>
+          <el-form-item label="改进项" :label-width="formLabelWidth">
+            <div v-if="item.improvementItems && item.improvementItems.length">
+              <div
+                v-for="(subItem, subindex) in item.improvementItems"
+                :key="subindex"
+                class="improvementItems-wrapper"
+              >
+                <div class="description-wrapper">
+                  <el-input
+                    v-model="subItem.description"
+                    class="description"
+                    type="textarea"
+                    :rows="2"
+                    placeholder="请填写改进事项"
+                  />
+                  <el-input
+                    v-model="subItem.detail"
+                    class="detail"
+                    type="textarea"
+                    :rows="2"
+                    placeholder="请填写具体描述"
+                  />
+                </div>
+                <div class="timer-wrapper">
+                  <el-form-item label="责任人">
+                    <searchPeople
+                      style="width: 70%"
+                      :value.sync="subItem.personInCharge"
+                      :multiple="true"
+                    />
+                  </el-form-item>
+                  <el-form-item class="deadline" label="计划完成时间">
+                    <el-date-picker
+                      v-model="subItem.deadline"
+                      type="date"
+                      style="width: 90%"
+                      value-format="yyyy-MM-dd"
+                      size="mini"
+                      placeholder="选择日期"
+                    />
+                  </el-form-item>
+                </div>
+                <el-form-item class="deadline-wrapper" label="进度">
+                  <el-input-number
+                    v-model="subItem.progress"
+                    controls-position="right"
+                    size="small"
+                    :min="0"
+                    :max="100"
+                  />
+                  &nbsp;&nbsp;%
+                </el-form-item>
+                <span class="del-sub-item">
+                  <el-button
+                    type="text"
+                    icon="el-icon-minus"
+                    @click="delSubItem(index, subindex)"
+                  />
+                </span>
+              </div>
+            </div>
+            <el-button
+              type="text"
+              icon="el-icon-plus"
+              @click="addSubItem(index)"
+              >新增改进项</el-button
+            >
+          </el-form-item>
+        </el-form>
+      </span>
+    </div>
+    <el-button
+type="text"
+icon="el-icon-plus"
+@click="addItem"
+      >新增问题</el-button
+    >
+  </normal-dialog>
+</template>
+
+<script>
+import _ from 'lodash'
+import normalDialog from '@/components/dialog/normalDialog'
+import searchPeople from '@/components/select/searchPeople' // 人员select
+
+export default {
+  name: 'Analysis',
+  components: { normalDialog, searchPeople },
+  data() {
+    return {
+      rowIndex: '',
+      analyticFeedback: '',
+      formLabelWidth: '80px'
+    }
+  },
+  methods: {
+    open(analyticFeedback, index) {
+      this.analyticFeedback = _.cloneDeep(analyticFeedback)
+      this.rowIndex = _.cloneDeep(index)
+      this.$refs.normalDialog.visible = true
+    },
+    addItem() {
+      if (!this.analyticFeedback.analyticContents) {
+        this.analyticFeedback.analyticContents = []
+      }
+      this.analyticFeedback.analyticContents.push({})
+    },
+    delItem(index) {
+      console.log('删除')
+      this.analyticFeedback.analyticContents.splice(index, 1)
+    },
+    addSubItem(index) {
+      if (!this.analyticFeedback.analyticContents[index].improvementItems) {
+        this.analyticFeedback.analyticContents[index].improvementItems = []
+      }
+      this.analyticFeedback.analyticContents[index].improvementItems.push({})
+      this.$forceUpdate()
+    },
+    delSubItem(index, subindex) {
+      console.log(index, subindex)
+      this.analyticFeedback.analyticContents[index].improvementItems.splice(
+        subindex,
+        1
+      )
+    },
+    updateModule() {
+      const { analyticFeedback, rowIndex } = this
+      this.$emit('upData', {
+        analyticFeedback,
+        rowIndex
+      })
+      this.oldBaseData = _.cloneDeep(this.baseData)
+      this.$refs.normalDialog.visible = false
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.box-wrapper {
+  .analysis-wrapper {
+    border: 1px solid #d1d0d0;
+    padding: 20px 45px 20px 0;
+    position: relative;
+    border-bottom: 0;
+    &:last-child {
+      border-bottom: 1px solid #d1d0d0;
+    }
+    .del-item {
+      padding: 0 5px;
+      position: absolute;
+      font-size: 14px;
+      right: 20px;
+      top: -20px;
+      background: #fff;
+    }
+    /deep/.el-form-item__label {
+      font-weight: 400;
+      text-align: left;
+      padding-left: 20px;
+      color: #606266;
+    }
+  }
+  .improvementItems-wrapper {
+    position: relative;
+    padding-bottom: 30px;
+    .description-wrapper {
+      display: flex;
+      > * {
+        box-sizing: border-box;
+      }
+      .description {
+        width: 320px;
+        flex: none;
+      }
+      .detail {
+        flex: 1;
+        margin-left: 30px;
+      }
+    }
+    .timer-wrapper {
+      display: flex;
+      margin-top: 15px;
+      .el-form-item {
+        flex: 1;
+        /deep/.el-form-item__label {
+          padding-left: 0;
+        }
+        .el-form-item__content {
+          text-align: right;
+        }
+      }
+      .deadline {
+        flex: 1;
+        display: flex;
+        /deep/ .el-form-item__content {
+          text-align: right;
+          flex: 1;
+        }
+      }
+    }
+    .deadline-wrapper {
+      margin-top: 5px;
+      /deep/.el-form-item__label {
+        padding-left: 0;
+        padding-right: 26px;
+      }
+    }
+    .del-sub-item {
+      position: absolute;
+      right: -30px;
+      top: 0;
+    }
+  }
+}
+/deep/.el-icon-plus:before,
+/deep/.el-icon-minus:before {
+  border: 1px solid;
+}
+.el-button {
+  font-weight: 400;
+}
+</style>

+ 11 - 8
src/views/monthlyReport/childrenPage/editReport/components/CascaderInfo.vue

@@ -25,12 +25,15 @@ export default {
     }
   },
   computed: {
+    tabsActive() {
+      return this.$store.state.monthlyReportEdit.tabsActive
+    },
     selectEnum() {
       return this.$store.state.monthlyReportEdit.selectEnum
     }
   },
   watch: {
-    teamData() {
+    tabsActive() {
       this.init()
     }
   },
@@ -40,12 +43,12 @@ export default {
   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 [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)) {
@@ -62,7 +65,7 @@ export default {
       const run = (arr) => {
         for (let i = 0; i < arr.length; i++) {
           const elm = arr[i]
-          if (elm.value === id) {
+          if (`${elm.value}` === `${id}`) {
             name = elm.label
             return
           }

+ 249 - 42
src/views/monthlyReport/childrenPage/editReport/components/MrTable.vue

@@ -1,5 +1,6 @@
 <template>
   <div>
+    <div v-if="pageType !== 'edit'" v-html="analyticFeedback" />
     <el-table
       :data="tableData"
       border
@@ -11,33 +12,51 @@
         'font-size': '14px',
         'font-weight': '500'
       }"
-      :cell-style="{ 'font-size': '14px', color: 'rgba(102,102,102,1)' }"
+      :cell-style="{ 'font-size': '14px', color: 'rgb(102,102,102)' }"
       size="small"
       show-overflow-tooltip="true"
     >
+      <!-- <el-table-column v-if="index === 0 && tabsActive.indexOf('本月重点问题') > -1
+        && pageType !== 'edit' ? 'expand' : ''" label="展开" type="expand"> -->
       <el-table-column
-        v-for="(item, index) in columns"
+        v-for="(item, index) in setColumns(columns)"
         :key="item.headerKey"
         :data-index="index"
         :prop="item.headerKey"
-        :align="index === 0 ? 'left' : 'center'"
+        :align="item.align"
         :label="item.name"
+        :type="item.type"
         :min-width="setMinWidth(item)"
         :fixed="isFixed(item, index, columns)"
       >
         <template slot-scope="scope">
+          <!--    展开    -->
+          <div v-if="item.type === 'expand'">
+            <TableExpandRow :analytic-feedback="scope.row.analyticFeedback" @upAnalyticFeedback="setAnalyticFeedback" />
+          </div>
           <!--    操作列    -->
-          <div v-if="item.name === '操作'">
-            <el-button
+          <div v-else-if="item.name === '操作'">
+            <span
               v-for="(btnItem, btnIndex) in item.defaultValue"
               :key="btnIndex"
-              size="mini"
-              type="text"
-              @click="btnFun(btnItem, scope)"
-              >{{ btnItem.value }}</el-button
             >
+              <el-button
+                v-if="
+                  scope.row.analyticFeedback &&
+                    !scope.row.analyticFeedback.isCommitted
+                "
+                size="mini"
+                type="text"
+                @click="btnFun(btnItem, scope)"
+                >{{ btnItem.value }}</el-button
+              >
+            </span>
           </div>
-          <div v-else class="edit-wrapper">
+          <div
+            v-else
+            class="edit-wrapper"
+            :style="{ cursor: pageType === 'edit' ? 'pointer' : 'auto' }"
+          >
             <!--  <div v-if="editKeys.indexOf(`${scope.row.rowKey}_${index}`) > -1">  -->
             <div v-if="editKeys.indexOf(domKey) > -1 && !item.defaultValue">
               <div v-if="item.displayType === 'Select'">
@@ -52,14 +71,30 @@
                     placeholder="选择日期"
                   />
                 </div>
-                <div v-else-if="item.selectType && item.selectType === 'SinglePeople'">
+                <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
+                  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
+                  v-else-if="item.selectType && item.selectType === 'people'"
+                >
+                  <searchPeople
+                    :value.sync="scope.row[item.headerKey]"
+                    :multiple="true"
+                  />
                 </div>
                 <el-select
                   v-else
@@ -74,7 +109,7 @@
                     :key="optionItem"
                     :label="optionItem"
                     :value="optionItem"
-                  >{{ optionItem }}</el-option
+                    >{{ optionItem }}</el-option
                   >
                 </el-select>
               </div>
@@ -97,7 +132,10 @@
                   collapse-tags
                   :props="{ multiple: true }"
                   clearable
-                  @change="(value)=>cascaderChange(value, item.headerKey,scope.row)" />
+                  @change="
+                    (value) => cascaderChange(value, item.headerKey, scope.row)
+                  "
+                />
               </div>
               <div v-else-if="item.defaultValue === 'Select'" />
               <el-input
@@ -110,9 +148,8 @@
                 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-else class="edit-cell" @click="editLine(scope.row, index)">
-
               <div v-if="item.displayType === 'Cascader'">
                 <CascaderInfo :team-data="scope.row[item.headerKey]" />
               </div>
@@ -121,51 +158,71 @@
                 {{ item.defaultValue.value }}
               </div>
               <div v-else-if="item.displayType === 'Select'">
-              <!-- 单个人员选择 -->
-                <div v-if="item.selectType && item.selectType === 'SinglePeople'">
+                <!-- 单个人员选择 -->
+                <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 />-->
+                <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'">
+                <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 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 class="plus-table-data" :style="{ marginBottom: plusTableDataBottom }">
+      <el-button v-if="pageType === 'edit'" type="text" @click="addTableData">
+        <svg-icon icon-class="data-plus" class="icon" />
+        新增
+      </el-button>
     </div>
     <slot name="fixedText" />
+    <Analysis ref="Analysis" @upData="upDataAnalysis" />
   </div>
 </template>
 
 <script>
+import _ from 'lodash'
 import { uuid10 } from '@/utils'
+import Analysis from './Analysis'
 import CascaderInfo from './CascaderInfo'
 import MultiplePeopleInfo from './MultiplePeopleInfo'
+import TableExpandRow from './TableExpandRow'
 import searchPeople from '@/components/select/searchPeople' // 人员select
+import { updateAnalyticFeedback } from '@/api/qualityMonthlyReport/edit'
+import { reportDataBack } from '@/store/modules/monthlyReport/edit/utils.js'
 
 export default {
   name: 'MrTable',
-  components: { CascaderInfo, searchPeople, MultiplePeopleInfo },
+  components: {
+    Analysis,
+    CascaderInfo,
+    searchPeople,
+    MultiplePeopleInfo,
+    TableExpandRow
+  },
   props: {
     plusTableDataBottom: {
       type: String,
@@ -182,6 +239,12 @@ export default {
       required: false,
       default: () => []
     },
+    // 分析反馈时使用的数据
+    title: {
+      type: String,
+      required: false,
+      default: () => ''
+    },
     tableData: {
       type: Array,
       required: false,
@@ -189,25 +252,49 @@ export default {
     }
   },
   data() {
+    this.setAnalyticFeedback = _.debounce(this.setAnalyticFeedback, 3000)
     return {
+      analyticFeedback: ''
     }
   },
   computed: {
     selectEnum() {
       return this.$store.state.monthlyReportEdit.selectEnum
     },
+    tabPageData() {
+      return this.$store.state.monthlyReportEdit.tabPageData
+    },
+    pageType() {
+      return this.$store.state.monthlyReportEdit.pageType
+    },
+    tabsActive() {
+      return this.$store.state.monthlyReportEdit.tabsActive
+    },
     editKeys() {
       return this.$store.state.monthlyReportEdit.editKeys
     }
   },
+  mounted() {
+    setTimeout(() => {
+      if (!this.analyticFeedback) {
+        this.setAnalyticFeedback()
+      }
+    }, 3000)
+  },
   methods: {
     isEdit() {},
     setMinWidth(item) {
-      let width = 200
+      let width = 100
       if (item.name === '操作') {
         if (item.defaultValue.length) {
           width = item.defaultValue.length * 50
         }
+        if (
+          this.pageType !== 'edit' &&
+          this.tabsActive.indexOf('本月重点问题') > -1
+        ) {
+          width = 90
+        }
       }
       return `${width}px`
     },
@@ -216,10 +303,9 @@ export default {
       return false
     },
     editLine(row, index) {
-      this.$store.commit(
-        'monthlyReportEdit/ADD_EDIT_KEYS',
-        `${this.domKey}`
-      )
+      if (this.pageType === 'edit') {
+        this.$store.commit('monthlyReportEdit/ADD_EDIT_KEYS', `${this.domKey}`)
+      }
     },
     btnFun(btnItem, scope) {
       this.$store.commit('monthlyReportEdit/INIT_EDIT_KEYS')
@@ -229,12 +315,22 @@ export default {
       if (btnItem.value === '标记') {
         this.tableData.splice(scope.$index, 1)
       }
+      if (btnItem.value === '分析反馈') {
+        console.log(293, btnItem, scope)
+        this.$refs.Analysis.open(scope.row.analyticFeedback, scope.$index)
+      }
+    },
+    // 分析反馈问题更新
+    upDataAnalysis({ rowIndex, analyticFeedback }) {
+      console.log(rowIndex, analyticFeedback)
+      this.tableData[rowIndex].analyticFeedback = _.cloneDeep(analyticFeedback)
+      this.setAnalyticFeedback()
     },
     addTableData() {
       const item = {
         rowKey: uuid10()
       }
-      this.columns.forEach(elm => {
+      this.columns.forEach((elm) => {
         item[elm.headerKey] = ''
       })
       this.tableData.push(item)
@@ -245,6 +341,86 @@ export default {
     },
     cascaderChange(value, headerKey, row) {
       console.log(value, headerKey, row)
+    },
+    // 添加插入
+    setColumns(columns) {
+      let newColumns = _.cloneDeep(columns)
+      if (
+        this.pageType !== 'edit' &&
+        this.tabsActive.indexOf('本月重点问题') > -1
+      ) {
+        newColumns = [
+          {
+            dataType: 'Single',
+            defaultValue: null,
+            displayType: 'Cascader',
+            name: '',
+            align: 'left',
+            type: 'expand',
+            selectEnum: null,
+            selectType: null,
+            headerKey: uuid10(6)
+          },
+          ...newColumns
+        ]
+        newColumns[1].align = 'left'
+      }
+      newColumns.forEach((elm) => {
+        if (!elm.align) {
+          elm.align = 'center'
+        }
+      })
+      if (
+        this.pageType !== 'edit' &&
+        this.tabsActive.indexOf('本月重点问题') < 0
+      ) {
+        newColumns.splice(newColumns.length - 1, 1)
+      }
+      return newColumns
+    },
+    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (
+        columnIndex === 0 &&
+        this.tabsActive.indexOf('本月重点问题') > -1 &&
+        this.pageType !== 'edit'
+      ) {
+        return [1, 2]
+      } else if (columnIndex === 1) {
+        return [0, 0]
+      }
+    },
+    // 查看页面数据分析
+    setAnalyticFeedback() {
+      // this.$refs.Analysis.open()
+      console.log(this.domKey)
+      const tabPageData = reportDataBack(_.cloneDeep(this.tabPageData))
+      let obj = null
+      const run = (arr) => {
+        arr.forEach((elm) => {
+          if (elm.content.length) {
+            elm.content.forEach((item) => {
+              if (item.domKey === this.domKey) {
+                console.log(elm)
+                obj = _.cloneDeep(elm)
+              }
+            })
+          }
+        })
+      }
+      run(tabPageData.children)
+      console.log(obj)
+      // 提交数据
+      updateAnalyticFeedback({
+        reportId: this.$route.query.reportId,
+        reportCatalog: obj
+
+      }).then((res) => {
+        if (res.code === 200) {
+          console.log(res.data)
+        }
+      })
+      // console.log(this.domKey)
+      // console.log(this.title)
     }
   }
 }
@@ -252,14 +428,45 @@ export default {
 
 <style scoped lang="less">
 .edit-wrapper {
-  cursor: pointer;
-
   .edit-cell {
     min-height: 23px;
     width: 100%;
   }
 }
+
 .plus-table-data {
   margin-top: 2px;
 }
+/deep/.el-table__expand-column {
+  border-right: 0;
+  .el-icon-arrow-right:before {
+    // 这是展开图标
+    border: 1px solid rgba(0, 0, 0, 0.14901960784313725);
+  }
+}
+/deep/.el-table__expand-column .cell {
+  .el-table__expand-icon {
+    .el-icon-arrow-right:before {
+      // 这是展开图标
+      content: '\e6d9';
+      //content: "\e6d8";
+    }
+  }
+  .el-table__expand-icon--expanded {
+    // 这是点击后的旋转角度
+    //transform: rotate(180deg);
+    transform: rotate(0deg);
+    .el-icon-arrow-right:before {
+      // 这是展开图标
+      //content: "\e6d9";
+      content: '\e6d8' !important;
+    }
+  }
+}
+.red {
+  color: red;
+}
+.yellow {
+  color: yellow;
+}
 </style>

+ 27 - 11
src/views/monthlyReport/childrenPage/editReport/components/MultiplePeopleInfo.vue

@@ -4,7 +4,7 @@
       v-for="(item, index) in userName"
       :key="index"
       style="margin-right: 10px"
-    >{{ item
+      >{{ item
       }}<span>{{ !(index >= userName.length - 1) ? ',' : '' }}</span></span
     >
   </div>
@@ -30,6 +30,11 @@ export default {
       userName: []
     }
   },
+  computed: {
+    userNames() {
+      return this.$store.state.monthlyReportEdit.userNames
+    }
+  },
   watch: {
     teamData() {
       if (this.teamData && this.teamData.length) {
@@ -59,17 +64,28 @@ export default {
       }
       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
+    getMember(query, cb) {
+      if (!query) return
+      if (this.userNames[query]) {
+        this.userName.push(this.userNames[query])
+        cb()
+      } else {
+        memberQueryMemberInfoByIDAPorName({ memberIDAP: query }).then((res) => {
+          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.$store.commit('monthlyReportEdit/SET_USER_NAME', {
+                  key: elm.idap,
+                  value: elm.name
+                })
+                this.userName.push(elm.name)
+                cb()
+                return
+              }
+            }
           }
-        }
+        })
       }
     }
   }

+ 12 - 6
src/views/monthlyReport/childrenPage/editReport/components/RichText.vue

@@ -1,7 +1,8 @@
 <template>
   <div>
+    <div v-if="pageType !== 'edit'" v-html="item.value || '暂无数据!'" />
     <normal-area
-      v-if="editKeys.indexOf(item.domKey) > -1"
+      v-else-if="editKeys.indexOf(item.domKey) > -1"
       :id="item.domKey"
       :value.sync="item.value"
       :height="200"
@@ -28,17 +29,22 @@ export default {
     }
   },
   computed: {
+    pageType() {
+      return this.$store.state.monthlyReportEdit.pageType
+    },
     editKeys() {
       return this.$store.state.monthlyReportEdit.editKeys
     }
   },
   methods: {
     editDom() {
-      this.$store.commit(
-        'monthlyReportEdit/ADD_EDIT_KEYS',
-        // `${row.rowKey}_${index}`
-        `${this.item.domKey}`
-      )
+      if (this.pageType === 'edit') {
+        this.$store.commit(
+          'monthlyReportEdit/ADD_EDIT_KEYS',
+          // `${row.rowKey}_${index}`
+          `${this.item.domKey}`
+        )
+      }
     }
   }
 }

+ 222 - 0
src/views/monthlyReport/childrenPage/editReport/components/TableExpandRow.vue

@@ -0,0 +1,222 @@
+<template>
+  <div v-if="analyticFeedback && analyticFeedback.analyticContents">
+    <div
+      v-for="(item, index) in analyticFeedback.analyticContents"
+      :key="index"
+      class="analyticContents-wrapper"
+    >
+      <!--序号-->
+      <div>
+        <span class="item-index">{{ index + 1 }}</span>
+      </div>
+      <!--问题-->
+      <div class="item-title">问题</div>
+      <div class="item-content">{{ item.problem }}</div>
+      <!--原因-->
+      <div class="item-title">原因</div>
+      <div class="item-content">{{ item.reason }}</div>
+      <!--改进项-->
+      <div class="item-title">改进项</div>
+      <div v-if="item.improvementItems && item.improvementItems.length">
+        <div
+          v-for="(subItem, subIndex) in item.improvementItems"
+          :key="subIndex"
+          class="improvementItems-wrapper"
+        >
+          <!--改进项: 描述-->
+          <div>{{ subIndex + 1 }}、{{ subItem.description }}</div>
+          <!--改进项: 其他-->
+          <div class="description-wrapper">
+            <!--改进项: 责任人-->
+            <span
+style="min-width: 50px;display: inline-block;"
+              >责任人:
+              <span v-if="!subItem.personInCharge">暂无负责人</span>
+              <MultiplePeopleInfo
+                v-else
+                style="display:inline-block "
+                :team-data="subItem.personInCharge"
+            /></span>
+            <!--改进项: 计划完成时间-->
+            <span
+              style="min-width: 200px;display: inline-block;margin-right: 10px;"
+              >计划完成时间:{{ subItem.deadline }}</span
+            >
+            <!--改进项: 进度-->
+            <span
+              class="progress-wrapper"
+              :style="{ width: !subItem.isProgressEdit ? '80px' : '150px' }"
+              >进度:<span v-if="!subItem.isProgressEdit">{{
+                subItem.progress || '0'
+              }}</span
+              ><span v-else>
+                <el-input-number
+                  v-model="subItem.progress"
+                  controls-position="right"
+                  size="small"
+                  style="width:100px"
+                  :min="0"
+                  :max="100" /></span
+              >%
+              <span v-if="subItem.isHold" class="isHold">Hole</span>
+            </span>
+            <!--改进项: 进度更新-->
+            <span
+              class="up-progress"
+              :style="{ width: !subItem.isHold ? '80px' : '80px' }"
+              ><span
+v-if="!subItem.isHold"
+@click="progressEdit(subItem)"
+                >进度更新</span
+              ></span
+            >
+            <!--改进项: Hold-->
+            <span class="Hold" @click="setHold(index, subIndex, subItem)">{{
+              subItem.isHold ? '解除Hold' : 'Hold'
+            }}</span>
+          </div>
+        </div>
+      </div>
+      <!--责任人: 计划完成时间:进度-->
+    </div>
+    <Hold ref="Hold" @upData="upHold" />
+  </div>
+</template>
+
+<script>
+import MultiplePeopleInfo from './MultiplePeopleInfo'
+import _ from 'lodash'
+import Hold from './Hold'
+
+export default {
+  name: 'TableExpandRow',
+  components: { MultiplePeopleInfo, Hold },
+  props: {
+    analyticFeedback: {
+      type: Object,
+      required: false,
+      default: null
+    }
+  },
+  methods: {
+    setHold(index, subIndex, subItem) {
+      subItem.isProgressEdit = false
+      if (subItem.isHold) {
+        subItem.isHold = false
+        this.$forceUpdate()
+        return
+      }
+      this.$refs.Hold.open(index, subIndex, subItem.holdReason)
+    },
+    upHold({ index, subIndex, holdReason }) {
+      this.analyticFeedback.analyticContents[index].improvementItems[
+        subIndex
+      ].isHold = true
+      if (holdReason) {
+        this.analyticFeedback.analyticContents[index].improvementItems[
+          subIndex
+        ].holdReason = holdReason
+      }
+      this.$emit('upAnalyticFeedback')
+    },
+    progressEdit(item) {
+      if (!_.isBoolean(item.isProgressEdit)) {
+        item.isProgressEdit = false
+      }
+      if (_.isNaN(Number.parseInt(item.progress))) {
+        item.progress = 0
+      }
+      item.isProgressEdit = !item.isProgressEdit
+      this.$forceUpdate()
+      this.$emit('upAnalyticFeedback')
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.analyticContents-wrapper {
+  .text-hide {
+    overflow: hidden; //超出的文本隐藏
+    text-overflow: ellipsis; //溢出用省略号显示
+    white-space: nowrap; //溢出不换行
+  }
+  color: #333333;
+  position: relative;
+  // border-bottom: 1px solid #EBEEF5;
+  padding-bottom: 10px;
+  margin-bottom: 10px;
+  &::after {
+    content: '';
+    position: absolute;
+    bottom: 0;
+    left: -50px;
+    right: -50px;
+    height: 1px;
+    border-bottom: 1px solid #ebeef5;
+  }
+  &:last-child {
+    border-bottom: 0;
+    padding-bottom: 0;
+    margin-bottom: 0;
+    &::after {
+      border-bottom: 0;
+    }
+  }
+  .item-index {
+    position: absolute;
+    left: -26px;
+    text-align: center;
+    color: #fff;
+    width: 16px;
+    height: 16px;
+    background: #1890ff;
+    border-radius: 50%;
+    opacity: 1;
+    display: inline-block;
+  }
+  .item-title {
+    color: #666666;
+    margin-bottom: 5px;
+  }
+  .item-content {
+    margin-bottom: 5px;
+  }
+  .progress-wrapper {
+    width: 75px;
+    display: inline-block;
+    margin-right: 10px;
+    position: relative;
+    .isHold {
+      position: absolute;
+      background: #e8e8e8;
+      border-radius: 2px;
+      font-size: 0.25em;
+      line-height: 15px;
+      color: #666666;
+      top: -10px;
+      padding: 0 3px;
+    }
+  }
+  .up-progress {
+    color: #1890ff;
+    display: inline-block;
+    // width: 50px;
+    margin-right: 10px;
+    cursor: pointer;
+  }
+  .Hold {
+    color: #1890ff;
+    display: inline-block;
+    cursor: pointer;
+  }
+  // .description-wrapper {
+  // }
+  // .item-problem {
+  // }
+  // .item-reason {
+  // }
+  // .improvementItems-wrapper {
+  // }
+}
+</style>

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

@@ -8,12 +8,14 @@
       <div class="title">{{ name }}</div>
       <div class="value">
         <el-input
+          v-if="pageType === 'edit'"
           v-model="textValue"
           type="textarea"
           placeholder="请输入"
           maxlength="300"
           show-word-limit
         />
+        <span v-else style="padding: 10px 0;display: inline-block;">{{ textValue }}</span>
       </div>
     </div>
   </div>
@@ -47,6 +49,11 @@ export default {
       textValue: ''
     }
   },
+  computed: {
+    pageType() {
+      return this.$store.state.monthlyReportEdit.pageType
+    }
+  },
   watch: {
     value(val) {
       this.textValue = val

+ 276 - 0
src/views/monthlyReport/childrenPage/editReport/components/anchor.vue

@@ -0,0 +1,276 @@
+<template>
+  <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-for="(item, index) in list"
+        :key="item.domKey"
+        class="title-wrapper"
+      >
+        <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"
+            :class="{hide: !item.isVisible}"
+            @contextmenu.prevent="openMenu($event, item)"
+            @click="change(item)"
+            @mousemove="mouseMoveItem({ event: $event, item })"
+          >
+            <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)"
+          @mouseMoveItem="mouseMoveItem"
+          @openMenu="(val) => openMenu(val.event, val.item)"
+        />
+      </span>
+    </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>
+
+<script>
+// import _ from 'lodash'
+
+export default {
+  name: 'Anchor',
+  props: {
+    list: {
+      type: Array,
+      require: false,
+      default: () => []
+    },
+    active: {
+      type: String,
+      require: false,
+      default: () => ''
+    },
+    parentDomeKey: {
+      type: String,
+      require: false,
+      default: () => 'top'
+    }
+  },
+  data() {
+    return {
+      tooltipValue: false
+    }
+  },
+  computed: {
+    subTabsActive() {
+      return this.$store.state.monthlyReportEdit.subTabsActive
+    }
+  },
+  methods: {
+    mouseMoveItem(event, item) {
+      // console.log(event, item, 66)
+      this.$emit('mouseMoveItem', { event, item })
+    },
+    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
+      this.$emit('openMenu', { event, item })
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+.anchor-wrapper {
+  background-color: #ffffff;
+  position: relative;
+  padding: 5px 0;
+  overflow: hidden;
+
+  .title-wrapper {
+    margin-top: 5px;
+    margin-left: 10px;
+    padding-left: 5px;
+    position: relative;
+
+    .title {
+      cursor: pointer;
+      //display: inline-block;
+      &:hover,
+      &.active {
+        color: #409eff;
+      }
+
+      &.hide,
+      &.hide:hover {
+        color: #999999;
+      }
+
+      &.visible{
+        color: #999999;
+      }
+    }
+
+    .title.hide,
+    .title.hide:hover {
+      color: #999999;
+    }
+  }
+
+  .radius {
+    position: absolute;
+    left: -5px;
+    top: -5px;
+    width: 7px;
+    height: 7px;
+    background: #ffffff;
+    border: 1px solid #409eff;
+    border-radius: 50%;
+    opacity: 1;
+
+    &.center {
+      top: 7px;
+    }
+
+    &.down {
+      bottom: -5px;
+      top: auto;
+    }
+  }
+
+  .line {
+    position: absolute;
+    width: 0px;
+    top: 14px;
+    left: 8px;
+    //height: -webkit-fill-available;
+    height: calc(100% - 23px);
+    //border: 1px solid #e9e9e9;
+    border-left: 0.5px solid #e9e9e9;
+    opacity: 1;
+  }
+
+  .mi {
+    width: 100%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+</style>

+ 14 - 3
src/views/monthlyReport/childrenPage/editReport/components/content.vue

@@ -4,6 +4,7 @@
       <!--   表格:Table   -->
       <div v-if="item.type === 'Table'">
         <mrTable
+          :title='title'
           :columns="item.tableHeaders"
           :table-data="item.tableRows"
           :dom-key="item.domKey"
@@ -19,7 +20,7 @@
           style="margin-bottom: 18px"
         >
           <template slot="fixedText">
-            <fixedText
+            <VarText
               v-model="item.value"
               :title="item.title"
               :name="item.name"
@@ -56,24 +57,34 @@
 
 <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: {
+    title: {
+      type: String,
+      required: false,
+      default: () => ''
+    },
     baseData: {
       type: Array,
       required: false,
       default: () => null
     }
+  },
+  computed: {
+    pageType() {
+      return this.$store.state.monthlyReportEdit.pageType
+    }
   }
 }
 </script>

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

@@ -1,7 +1,7 @@
 <template>
   <div v-show="baseData.isVisible">
-    <div v-if="baseData.type === 'Head1'" :id="baseData.domKey">
-      <headTitle
+
+    <div v-if="baseData.type === 'Head1'" :id="baseData.domKey"><headTitle
         :title="baseData.title"
       />
     </div>
@@ -10,10 +10,10 @@
       :id="baseData.domKey"
       style="margin-top: 10px;"
     >
-      {{ headerIndex }}{{ headerTitle }}
+       {{ headerIndex }}{{ headerTitle }}
     </div>
     <div v-if="baseData.content && baseData.content.length" style="margin-bottom: 10px">
-      <contentDom :base-data="baseData.content" />
+      <contentDom :base-data="baseData.content" :title='baseData.title' />
     </div>
     <div v-if="baseData.children && baseData.children.length">
       <div v-if="baseData.children[0].type === 'Tag'">

+ 66 - 21
src/views/monthlyReport/childrenPage/editReport/index.vue

@@ -1,24 +1,40 @@
 <template>
   <div ref="pageWrapper" class="page-wrapper" @click="setInit">
-    <headerCom title="月报" sub-title="新建月报">
-      <template slot="content">
+    <headerCom title="月报" :sub-title="subTitle">
+      <template v-if="pageType === 'edit'" slot="content">
+        {{ tabsActive }}
         <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>
+        <el-button
+          slot="reference"
+          plain
+          size="small"
+          @click="$router.push({ path: '/monthlyReport/index' })"
+          >取消
+        </el-button>
+        <el-popconfirm
+          title="确认删除当前月报吗?"
+          @confirm="delectReport('delete')"
+        >
+          <el-button slot="reference" plain size="small">删除</el-button>
+        </el-popconfirm>
       </template>
     </headerCom>
-    <div style="position: fixed;z-index: 99; top: 20px">
+<!--     <div style="position: fixed;z-index: 99; top: 20px">
       <el-button type="primary" @click="test">test</el-button>
-    </div>
+    </div> -->
     <!--  content  -->
     <div class="content-wrapper">
-      <el-tabs :value="tabsActive" @tab-click="tabClick">
+      <el-tabs
+        v-if="pageType !== 'read'"
+        :value="tabsActive"
+        @tab-click="tabClick"
+      >
         <el-tab-pane
           v-for="item in tabsList"
           :key="item.name"
@@ -59,10 +75,10 @@ size="small"
   </div>
 </template>
 
-<script type='text/javascript'>
+<script type="text/javascript">
 import headerCom from '../../components/header'
 import Affix from '@/components/affix/affix'
-import Anchor from '../../components/anchor'
+import Anchor from './components/anchor'
 import Menu from './components/menu'
 import Croe from './components/core'
 import Clickoutside from 'element-ui/src/utils/clickoutside'
@@ -102,6 +118,9 @@ export default {
     tabPageData() {
       return this.$store.state.monthlyReportEdit.tabPageData
     },
+    subTitle() {
+      return this.$store.state.monthlyReportEdit.subTitle
+    },
     tabsList() {
       return this.$store.state.monthlyReportEdit.tabsList
     },
@@ -119,6 +138,9 @@ export default {
     },
     offsetList() {
       return this.$store.state.monthlyReportEdit.offsetList
+    },
+    pageType() {
+      return this.$store.state.monthlyReportEdit.pageType
     }
   },
   watch: {
@@ -127,19 +149,30 @@ export default {
     }
   },
   mounted() {
-    console.log(this.$route.query)
+    if (this.$route.query.pageType === 'read' && this.$route.query.reportId) {
+      this.$store.dispatch('monthlyReportEdit/setSelectEnum', this.$route.query.reportId)
+    }
+    if (this.$route.query.pageType === 'readAll') {
+      this.$store.commit('monthlyReportEdit/SET_SUB_TITLE', '查看完整月报')
+    }
     if (this.$route.query.pageType) {
       this.$store.commit(
-        'monthlyReportEdit/SET_PAGE_TYPE', this.$route.query.pageType)
-    }
-    if (this.$route.query.reportId) {
-      this.$store.dispatch(
-        'monthlyReportEdit/initPageData',
-        this.$route.query.reportId
+        'monthlyReportEdit/SET_PAGE_TYPE',
+        this.$route.query.pageType
       )
+    }
+    if (this.$route.query.reportId || this.$route.query.subReportId) {
+      this.$store.dispatch('monthlyReportEdit/initPageData', {
+        id: this.$route.query.reportId,
+        subActive: this.$route.query.subActive,
+        subReportId: this.$route.query.subReportId
+      })
       // this.getPageData(this.$route.query.reportId)
     }
   },
+  destroyed() {
+    this.$store.commit('monthlyReportEdit/INIT_STATE_DATA')
+  },
   methods: {
     setInit() {
       // window.addEventListener('click', () => {
@@ -219,16 +252,28 @@ export default {
     upDateReport() {
       this.$store.dispatch('monthlyReportEdit/upDateReport')
     },
+    delectReport(key) {
+      this.$store.dispatch('monthlyReportEdit/deleteReport', {
+        key,
+        cb: () => {
+          this.$router.push({ path: '/monthlyReport/index' })
+        }
+      })
+    },
     test() {
-      console.log(this.tabPageData)
+      console.log(this.$store.state.monthlyReportEdit)
       // 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.$store.dispatch('monthlyReportEdit/tabActiveChange', {
+        ...this.$route.query,
+        id: this.$route.query.reportId,
+        tabsActive: tab.name
+      })
+      // this.$store.commit('monthlyReportEdit/TAB_ACTIVE_CHANGE', tab.name)
       // this.$nextTick(() => {
       //   this.$store.commit('monthlyReportEdit/GET_ALL_OFFSETTOP')
       // })
@@ -236,7 +281,7 @@ export default {
   }
 }
 </script>
-<style scoped lang='less'>
+<style scoped lang="less">
 @import '../../style';
 
 .content-wrapper {