소스 검색

提交经营目标系统,文件预览组件

manywhy 1 개월 전
부모
커밋
ea5a773790
100개의 변경된 파일2464개의 추가작업 그리고 15271개의 파일을 삭제
  1. 23 1
      package.json
  2. 1 1
      src/api/login.js
  3. BIN
      src/assets/123.pdf
  4. BIN
      src/assets/header_bg.png
  5. BIN
      src/assets/posx.jpg
  6. BIN
      src/assets/step/templateDetail/cc.png
  7. BIN
      src/assets/step/templateDetail/flowSetting.png
  8. BIN
      src/assets/step/templateDetail/resultInput.png
  9. BIN
      src/assets/step/templateDetail/review.png
  10. BIN
      src/assets/step/templateDetail/score.png
  11. BIN
      src/assets/step/templateDetail/scoreEachOther.png
  12. BIN
      src/assets/step/templateDetail/selfScore.png
  13. BIN
      src/assets/step/templateDetail/targetConfirm.png
  14. BIN
      src/assets/step/workbench/Snipaste_2025-10-09_10-22-29.png
  15. BIN
      src/assets/step/workbench/result-input.png
  16. BIN
      src/assets/step/workbench/review.png
  17. BIN
      src/assets/step/workbench/score.png
  18. BIN
      src/assets/step/workbench/self-score.png
  19. BIN
      src/assets/targetStep/add-target-dialog.png
  20. BIN
      src/assets/targetStep/cycle-list.png
  21. BIN
      src/assets/targetStep/dismantling-target.png
  22. BIN
      src/assets/targetStep/drawer-box.png
  23. BIN
      src/assets/targetStep/message-list.png
  24. BIN
      src/assets/targetStep/month-data.png
  25. BIN
      src/assets/targetStep/publish-step.png
  26. BIN
      src/assets/targetStep/target-step.png
  27. BIN
      src/assets/targetStep/task-list.png
  28. 2 0
      src/components/AppealCreate.vue
  29. 190 0
      src/components/ExcelPreview.vue
  30. 2 2
      src/components/PageHead.vue
  31. 99 0
      src/components/PdfPreview.vue
  32. 11 0
      src/components/Steps.vue
  33. 10 6
      src/components/UserImage.vue
  34. 4 4
      src/components/organization/EmploeAdd.vue
  35. 1 1
      src/components/organization/EmployeeTable.vue
  36. 7 2
      src/components/system/Interface.vue
  37. 1 1
      src/components/system/Jurisdiction.vue
  38. 14 2
      src/home.vue
  39. 23 4
      src/index.vue
  40. 19 1
      src/main.js
  41. 8 5
      src/newPerformance/components/AnnualStatement.vue
  42. 0 127
      src/newPerformance/components/CombinationTemplates/BatchTemplatePublish.vue
  43. 0 171
      src/newPerformance/components/CombinationTemplates/EmployeeChooseOkrs.vue
  44. 0 572
      src/newPerformance/components/ExamineContrast.vue
  45. 0 11
      src/newPerformance/components/ExamineRecord.vue
  46. 0 381
      src/newPerformance/components/ExamineRecord/LeftExamineRecord.vue
  47. 0 142
      src/newPerformance/components/ExamineRecord/PieChart1.vue
  48. 0 131
      src/newPerformance/components/ExamineRecord/RightEamineComp/EditCateType.vue
  49. 0 259
      src/newPerformance/components/ExamineRecord/RightEamineComp/EditCircle.vue
  50. 0 78
      src/newPerformance/components/ExamineRecord/RightEamineComp/EditTitle.vue
  51. 0 685
      src/newPerformance/components/ExamineRecord/RightExamineRecord copy.vue
  52. 0 789
      src/newPerformance/components/ExamineRecord/RightExamineRecord.vue
  53. 34 251
      src/newPerformance/components/IndicatorSetting.vue
  54. 0 347
      src/newPerformance/components/IndicatorSetting/PerCcSelector.vue
  55. 0 362
      src/newPerformance/components/IndicatorSetting/PerCcSelectorOnly.vue
  56. 2 1
      src/newPerformance/components/IndicatorSetting/PerEmployeeSelector.vue
  57. 0 316
      src/newPerformance/components/IndicatorSetting/PerResultInputSelector.vue
  58. 0 324
      src/newPerformance/components/IndicatorSetting/PerResultInputSelectorOnly.vue
  59. 0 364
      src/newPerformance/components/IndicatorSetting/PerReviewsSelector.vue
  60. 0 380
      src/newPerformance/components/IndicatorSetting/PerReviewsSelectorOnly.vue
  61. 0 97
      src/newPerformance/components/IndicatorSetting/PerScoreEachOther.vue
  62. 0 87
      src/newPerformance/components/IndicatorSetting/PerScoreEachOtherOnly.vue
  63. 0 102
      src/newPerformance/components/IndicatorSetting/PerScoreSelf.vue
  64. 0 89
      src/newPerformance/components/IndicatorSetting/PerScoreSelfOnly.vue
  65. 0 505
      src/newPerformance/components/IndicatorSetting/PerScoresSelector.vue
  66. 0 521
      src/newPerformance/components/IndicatorSetting/PerScoresSelectorOnly.vue
  67. 0 364
      src/newPerformance/components/IndicatorSetting/PerTargetConfirmSelector.vue
  68. 0 394
      src/newPerformance/components/IndicatorSetting/PerTargetConfirmSelectorOnly.vue
  69. 1 16
      src/newPerformance/components/IndicatorSetting/PublishComp.vue
  70. 220 486
      src/newPerformance/components/IndicatorSetting/QuickCreate.vue
  71. 0 928
      src/newPerformance/components/IndicatorSetting/TemplateDetails.vue
  72. 0 11
      src/newPerformance/components/IndicatorSetting/TemplateMixedPublish.vue
  73. 197 426
      src/newPerformance/components/IndicatorSetting/UploadPublish.vue
  74. 100 52
      src/newPerformance/components/IndicatorStore.vue
  75. 1 4
      src/newPerformance/components/LevelSetting.vue
  76. 309 107
      src/newPerformance/components/MyPerformance.vue
  77. 0 822
      src/newPerformance/components/MyPerformance/AddIndicator copy.vue
  78. 432 244
      src/newPerformance/components/MyPerformance/AddIndicator.vue
  79. 1 11
      src/newPerformance/components/MyPerformance/ExamineLog.vue
  80. 32 27
      src/newPerformance/components/MyPerformance/IndicatorList.vue
  81. 10 8
      src/newPerformance/components/MyPerformance/SelectExamine.vue
  82. 4 3
      src/newPerformance/components/OrganizationExamine.vue
  83. 0 759
      src/newPerformance/components/PerInterview.vue
  84. 0 596
      src/newPerformance/components/PerReviewDetail.vue
  85. 0 272
      src/newPerformance/components/PerformanceCoaching.vue
  86. 0 785
      src/newPerformance/components/PerformanceInterview.vue
  87. 0 449
      src/newPerformance/components/PersonalExamine.vue
  88. 0 328
      src/newPerformance/components/PersonalExamine/ExamineDetails copy.vue
  89. 0 446
      src/newPerformance/components/PersonalExamine/ExamineDetails.vue
  90. 0 108
      src/newPerformance/components/PersonalExamine/PieChart1.vue
  91. 0 109
      src/newPerformance/components/PersonalExamine/PieChart2.vue
  92. 0 111
      src/newPerformance/components/PersonalExamine/PieChart3.vue
  93. 0 111
      src/newPerformance/components/PersonalExamine/PieChart4.vue
  94. 0 138
      src/newPerformance/components/PersonalExamine/TableHeaderRender.vue
  95. 69 25
      src/newPerformance/components/ProcessTracking.vue
  96. 13 8
      src/newPerformance/components/PublicComp/AIAssistant.vue
  97. 0 0
      src/newPerformance/components/PublicComp/BindingOKR/ChooseKR.vue
  98. 0 0
      src/newPerformance/components/PublicComp/PerformanceWorkflow.vue
  99. 2 1
      src/newPerformance/components/PublicComp/ShowHanderDialog2.vue
  100. 622 0
      src/newPerformance/components/PublicComp/TargetPlanComp.vue

+ 23 - 1
package.json

@@ -39,11 +39,22 @@
     "@tiptap/pm": "^2.11.5",
     "@tiptap/starter-kit": "^2.11.5",
     "@tiptap/vue-2": "^2.11.5",
+    "@vue-flow/background": "^1.3.2",
+    "@vue-flow/controls": "^1.1.2",
+    "@vue-flow/core": "^1.19.3",
+    "@vue-flow/minimap": "^1.5.3",
+    "@vue-flow/node-resizer": "^1.5.0",
+    "@vue-flow/node-toolbar": "^1.1.1",
+    "@vue-office/docx": "^1.6.3",
+    "@vue-office/excel": "^1.3.0",
+    "@vue-office/pdf": "^2.0.10",
+    "@vue/composition-api": "^1.7.2",
     "@wangeditor/editor": "^5.1.23",
     "@wangeditor/editor-for-vue": "^1.0.2",
     "axios": "^1.6.2",
     "babel-runtime": "^6.26.0",
     "clipboard": "^2.0.11",
+    "colresizable": "^1.6.0",
     "connect": "^3.7.0",
     "date-fns": "^4.1.0",
     "dhtmlx-gantt": "^8.0.6",
@@ -56,12 +67,15 @@
     "intro.js": "^7.2.0",
     "js-cookie": "^3.0.5",
     "jsencrypt": "^3.2.2",
+    "luckyexcel": "^1.0.1",
+    "mammoth": "^1.11.0",
     "marked": "^0.8.0",
     "moment": "^2.29.4",
     "node-sass": "^4.14.1",
     "normalize.css": "^8.0.1",
     "npm": "^7.20.1",
     "nprogress": "0.2.0",
+    "pdfjs-dist": "^2.16.105",
     "photoswipe": "^4.1.3",
     "pikaz-excel-js": "^0.2.16",
     "qrcodejs2": "0.0.2",
@@ -79,7 +93,9 @@
     "vue-clickaway": "^2.2.2",
     "vue-count-to": "^1.0.13",
     "vue-json-excel": "^0.3.0",
+    "vue-pdf": "^4.3.0",
     "vue-photo-preview": "^1.0.9",
+    "vue-puzzle-vcode": "^1.1.10",
     "vue-router": "^3.6.5",
     "vue-router-storage": "^1.0.9",
     "vue-seamless-scroll": "^1.1.23",
@@ -87,9 +103,13 @@
     "vue-tree-chart": "^1.2.9",
     "vue-tree-color": "^2.3.3",
     "vue2-org-tree": "^1.3.6",
+    "vue2-verify": "^1.1.5",
     "vuedraggable": "^2.24.3",
     "vuex": "^3.6.2",
+    "vxe-pc-ui": "^4.3.37",
+    "vxe-table": "^3.16.11",
     "ws": "^8.18.1",
+    "xe-utils": "^3.7.9",
     "xlsx": "^0.17.5",
     "xlsx-style": "^0.8.13"
   },
@@ -111,6 +131,7 @@
     "compression-webpack-plugin": "^1.1.11",
     "copy-webpack-plugin": "4.5.2",
     "cross-env": "5.2.0",
+    "crypto-js": "^4.2.0",
     "css-loader": "1.0.0",
     "eslint": "4.19.1",
     "eslint-friendly-formatter": "4.0.1",
@@ -150,7 +171,8 @@
     "webpack-bundle-analyzer": "2.13.1",
     "webpack-cli": "3.1.0",
     "webpack-dev-server": "3.1.5",
-    "webpack-merge": "4.1.4"
+    "webpack-merge": "4.1.4",
+    "worker-loader": "^3.0.8"
   },
   "engines": {
     "node": ">= 6.0.0",

+ 1 - 1
src/api/login.js

@@ -1,7 +1,7 @@
 
 import axiosUser from '@/utils/axiosUser'
 import axios from '@/utils/axios'
-import {returnJSEncrypt} from '@/utils/auth'
+import { returnJSEncrypt } from '@/utils/auth'
 
 export function loginByUsername(username, password) {
   const data = {

BIN
src/assets/123.pdf


BIN
src/assets/header_bg.png


BIN
src/assets/posx.jpg


BIN
src/assets/step/templateDetail/cc.png


BIN
src/assets/step/templateDetail/flowSetting.png


BIN
src/assets/step/templateDetail/resultInput.png


BIN
src/assets/step/templateDetail/review.png


BIN
src/assets/step/templateDetail/score.png


BIN
src/assets/step/templateDetail/scoreEachOther.png


BIN
src/assets/step/templateDetail/selfScore.png


BIN
src/assets/step/templateDetail/targetConfirm.png


BIN
src/assets/step/workbench/Snipaste_2025-10-09_10-22-29.png


BIN
src/assets/step/workbench/result-input.png


BIN
src/assets/step/workbench/review.png


BIN
src/assets/step/workbench/score.png


BIN
src/assets/step/workbench/self-score.png


BIN
src/assets/targetStep/add-target-dialog.png


BIN
src/assets/targetStep/cycle-list.png


BIN
src/assets/targetStep/dismantling-target.png


BIN
src/assets/targetStep/drawer-box.png


BIN
src/assets/targetStep/message-list.png


BIN
src/assets/targetStep/month-data.png


BIN
src/assets/targetStep/publish-step.png


BIN
src/assets/targetStep/target-step.png


BIN
src/assets/targetStep/task-list.png


+ 2 - 0
src/components/AppealCreate.vue

@@ -15,6 +15,8 @@
     top="1%"
   >
 
+  
+
     <template>
       <el-form v-model="rewriteData" v-loading="loading">
         <el-form-item label="审批人" required>

+ 190 - 0
src/components/ExcelPreview.vue

@@ -0,0 +1,190 @@
+<template>
+    <div>
+        <div class="sheet-tooltip">{{ content }}</div>
+        <div :id="idName" class="sheet-table" style="height: 600px;"></div>
+    </div>
+</template>
+
+<script>
+import LuckyExcel from 'luckyexcel'
+
+export default {
+    name: "ExcelPreview",
+    components: { LuckyExcel },
+    props: {
+        idName: {
+            type: String,
+        },
+        objectURL: {
+            type: String,
+        },
+        headerNum: {
+            type: Number,
+            default() {
+                return 1
+            }
+        },
+        showCommentColumns: {
+            type: Array,
+            default() {
+                return []
+            }
+        }
+    },
+    data() {
+        return {
+            content: ''
+        };
+    },
+    watch: {
+        objectURL(val) {
+            this.handleExcel(val)
+        }
+    },
+    methods: {
+        handleExcel(objectURL) {
+            let me = this
+            LuckyExcel.transformExcelToLuckyByUrl(
+                objectURL,
+                "test3.xlsx",
+                (exportJson, luckysheetfile) => {
+                    console.log('exportJson:', exportJson)
+                    if (exportJson.sheets == null || exportJson.sheets.length == 0) {
+                        alert("文件读取失败!");
+                        return;
+                    }
+                    // 销毁原来的表格
+                    // window.luckysheet.setWorkBookEditMode()
+                    // 重新创建新表格
+                    luckysheet.create({
+                        lang: "zh", // 设定表格语言
+                        defaultColWidth: 150,
+                        container: this.idName, // 设定DOM容器的id
+                        allowHotkey: false, // 禁止快捷键
+                        showtoolbar: false, // 是否显示工具栏
+                        showinfobar: false, // 是否显示顶部信息栏
+                        showstatisticBar: false, // 是否显示底部计数栏
+                        sheetBottomConfig: false, // sheet页下方的添加行按钮和回到顶部按钮配置
+                        allowEdit: false, // 是否允许前台编辑
+                        allowCopy: false, //允许复制
+                        enableAddRow: false, // 是否允许增加行
+                        enableAddCol: false, // 是否允许增加列
+                        sheetFormulaBar: false, // 是否显示公式栏
+                        enableAddBackTop: false, //返回头部按钮
+                        showsheetbar: true, // 是否显示底部sheet页按钮
+                        showsheetbarConfig: { //自定义配置底部sheet页按钮,可以与showsheetbar配合使用,showsheetbarConfig拥有更高的优先级。
+                            add: false, //新增sheet  
+                            menu: false, //sheet管理菜单
+                            sheet: true, //sheet页显示
+                        },
+                        sheetRightClickConfig: { //自定义配置sheet页右击菜单
+                            delete: false, // 删除
+                            copy: true, // 复制
+                            rename: false, //重命名
+                            color: false, //更改颜色
+                            hide: false, //隐藏,取消隐藏
+                            move: false, //向左移,向右移
+                        },
+                        loading: {
+                            image: () => {
+                                return `<svg viewBox="25 25 50 50" class="circular">
+                <circle cx="50" cy="50" r="20" fill="none"></circle>
+                </svg>`
+                            },
+                            imageClass: "loadingAnimation"
+                        },
+                        showConfigWindowResize: false,
+                        data: exportJson.sheets, //表格内容
+                        title: exportJson.info.name, //表格标题
+                        cellRightClickConfig: {
+                            copy: true, // 复制
+                            copyAs: false, // 复制为
+                            paste: false, // 粘贴
+                            insertRow: false, // 插入行
+                            insertColumn: false, // 插入列
+                            deleteRow: false, // 删除选中行
+                            deleteColumn: false, // 删除选中列
+                            deleteCell: false, // 删除单元格
+                            hideRow: false, // 隐藏选中行和显示选中行
+                            hideColumn: false, // 隐藏选中列和显示选中列
+                            rowHeight: false, // 行高
+                            columnWidth: false, // 列宽
+                            clear: false, // 清除内容
+                            matrix: false, // 矩阵操作选区
+                            sort: false, // 排序选区
+                            filter: false, // 筛选选区
+                            chart: false, // 图表生成
+                            image: false, // 插入图片
+                            link: false, // 插入链接
+                            data: false, // 数据验证
+                            cellFormat: false, // 设置单元格格式
+                        },
+                        hook: {
+                            cellRenderBefore: function (cell, postion, sheetFile, ctx) {
+                                if (cell && cell.m) {
+                                    if (!cell.ps && postion.r > me.headerNum - 1 && me.showCommentColumns.includes(postion.c + 1)) {
+                                        cell.tb = 0
+                                        cell.ps = {
+                                            value: cell.m.replace('&#xa;', '')
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    });
+                }
+            );
+        },
+    },
+};
+</script>
+
+<style>
+/* 自定义loading演示样式 */
+@keyframes loading-rotate {
+    0% {
+        transform: rotate(0deg);
+    }
+
+    100% {
+        transform: rotate(360deg);
+    }
+}
+
+@keyframes loading-dash {
+    0% {
+        stroke-dasharray: 1, 200;
+        stroke-dashoffset: 0;
+    }
+
+    50% {
+        stroke-dasharray: 90, 150;
+        stroke-dashoffset: -40px;
+    }
+
+    100% {
+        stroke-dasharray: 90, 150;
+        stroke-dashoffset: -120px;
+    }
+}
+
+.loadingAnimation {
+    width: 3em;
+    height: 3em;
+    animation: loading-rotate 2s linear infinite;
+}
+
+.loadingAnimation circle {
+    animation: loading-dash 1.5s ease-in-out infinite;
+    stroke-dasharray: 90, 150;
+    stroke-dashoffset: 0;
+    stroke-width: 2;
+    stroke: currentColor;
+    stroke-linecap: round;
+}
+
+.sheet-tooltip {
+    position: absolute;
+    z-index: 1000;
+}
+</style>

+ 2 - 2
src/components/PageHead.vue

@@ -19,8 +19,8 @@ export default {
         default:''
       },
       routePush:{
-        type:String,
-        default:null
+        type: String,
+        default: null
       }
     },
   data() {

+ 99 - 0
src/components/PdfPreview.vue

@@ -0,0 +1,99 @@
+<template>
+    <div class="pdf-viewer">
+        <!-- 画布用于显示PDF页面 -->
+        <canvas ref="pdfCanvas"></canvas>
+    </div>
+</template>
+
+
+
+
+<script>
+// 导入PDF.js核心库和Web Worker
+// import * as pdfjsLib from 'pdfjs-dist'
+// import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf';
+// import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'
+
+// import { GlobalWorkerOptions, getDocument } from 'pdfjs-dist/webpack'
+// import pdfWorker from 'pdfjs-dist/build/pdf.worker.entry'
+// GlobalWorkerOptions.workerSrc = pdfWorker
+import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
+// pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;
+// pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.js`;
+pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js';
+
+
+
+
+// 重要:设置Web Worker路径
+pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker
+
+export default {
+    name: 'PdfViewer',
+    props: {
+        pdfUrl: {
+            type: String,
+            required: true // 接收一个PDF文件路径或URL作为参数
+        }
+    },
+    mounted() {
+        // 组件挂载后加载PDF
+        this.loadPdf()
+    },
+    methods: {
+        async loadPdf() {
+            try {
+                // 1. 创建PDF文档加载任务
+                const loadingTask = pdfjsLib.getDocument(this.pdfUrl)
+                // 2. 异步获取PDF文档对象
+                const pdf = await loadingTask.promise
+                console.log(`PDF加载成功,总页数: ${pdf.numPages}`)
+
+                // 3. 获取第一页(页码从1开始)
+                const pageNumber = 1
+                const page = await pdf.getPage(pageNumber)
+
+                // 4. 准备画布上下文
+                const canvas = this.$refs.pdfCanvas
+                const context = canvas.getContext('2d')
+
+                // 5. 获取页面的视口(定义缩放和显示比例)
+                const viewport = page.getViewport({ scale: 1.5 }) // 可以根据需要调整scale
+
+                // 6. 设置画布尺寸与视口一致
+                canvas.height = viewport.height
+                canvas.width = viewport.width
+
+                // 7. 创建渲染上下文,将画布与视口关联
+                const renderContext = {
+                    canvasContext: context,
+                    viewport: viewport
+                }
+
+                // 8. 将PDF页面渲染到画布上
+                await page.render(renderContext).promise
+                console.log('页面渲染完成')
+
+            } catch (error) {
+                // 错误处理(例如:文件不存在、损坏、网络问题等)
+                console.error('加载或渲染PDF时出错:', error)
+            }
+        }
+    }
+}
+</script>
+
+
+<style scoped>
+.pdf-viewer {
+    width: 100%;
+    overflow: auto;
+}
+
+/* 可以根据需要为canvas添加样式,例如边框 */
+canvas {
+    border: 1px solid #eee;
+    margin: 0 auto;
+    display: block;
+}
+</style>

+ 11 - 0
src/components/Steps.vue

@@ -137,4 +137,15 @@ export default {
   white-space: nowrap;
 }
 
+/deep/ .el-step__icon div:nth-child(1) {
+  overflow: visible !important;
+}
+
+/deep/ img {
+  border-radius: 50% !important;
+}
+
+
+
+
 </style>

+ 10 - 6
src/components/UserImage.vue

@@ -26,7 +26,7 @@ export default {
       default:"50%"
     },
     id: {
-      type: Number,
+      type: [Number, String],
       default: 0
     },
     img_url: {
@@ -43,15 +43,18 @@ export default {
     }
   },
   watch: {
-    id: function(val) {
+    id: function (val) {
+      console.log('123');
       // this.set_info();
       this.name_no();
     },
-    img_url: function(val) {
+    img_url: function (val) {
+      console.log('456');
       // this.set_info();
       this.name_no();
     },
-    user_name: function(val) {
+    user_name: function (val) {
+      console.log('789');
       // this.set_info();
       this.name_no();
     }
@@ -76,6 +79,7 @@ export default {
   methods: {
     set_info() {
       if (this.id) {
+        console.log(this.id)
         let info = this.id && this.$getEmployeeMapItem(this.id) || { name: '', img_url: '', id: 0 };
         if (this.img_url != '') {
           info.img_url = this.img_url;
@@ -106,7 +110,7 @@ export default {
         }
       }else if(this.img_url){
         this.imgUrl=this.img_url;
-      }else if(this.user_name&&this.user_name!='未知'){
+      }else if(this.user_name && this.user_name!='未知'){
         let pattern = new RegExp('^[\u4E00-\u9FA5]+');
         if (this.user_name.length > 2) {
           if (pattern.test(this.user_name)) {
@@ -127,7 +131,7 @@ export default {
   }
 };
 </script>
-<style scoped>
+<style scoped lang="scss">
 .img_round {
   position: relative;
   display: inline-block;

+ 4 - 4
src/components/organization/EmploeAdd.vue

@@ -437,10 +437,10 @@ export default {
         type: 'warning'
       }).then(() => {
           this.$axiosUser('post', '' + '/api/pro/employee/delete?id=' + this.managerId).then(res => {
-              this.$refs['detailForm'].resetFields();
-              this.$emit('closeDetai');
-              this.$emit('refresh');
-              this.$message({message: '删除成功',type: 'success'});
+            this.$refs['detailForm'].resetFields();
+            this.$emit('closeDetai');
+            this.$emit('refresh');
+            this.$message({message: '删除成功',type: 'success'});
           });
       }).catch(() => {});
     },

+ 1 - 1
src/components/organization/EmployeeTable.vue

@@ -6,7 +6,7 @@
       <p>备注:(导入员工的数量不能大于购买的员工数量)</p>
     </el-alert>
 
-    <div class="flex-box all-box br-5 boxMinHeight">
+    <div class="flex-box all-box br-5" style="display: flex !important;">
       <div class="RuleLeft box-sizing-w scroll-bar">
         <el-button @click="addTheDepartment" type="primary" style="margin-bottom: 10px;width:164px;height:36px;text-align: center;font-size:14px;">+添加部门</el-button>
         <div v-loading="dept_show">

+ 7 - 2
src/components/system/Interface.vue

@@ -14,7 +14,8 @@
             </el-table-column> -->
             <el-table-column label="操作" align="center">
                 <el-link type="primary" @click="copy()">复制秘钥</el-link>
-                <el-link type="primary" @click="getDoc()">接口文档</el-link>
+                <el-link type="primary" @click="previewDoc()">预览文档</el-link>
+                <el-link type="primary" @click="getDoc()">下载文档</el-link>
             </el-table-column>
         </el-table>
     </div>
@@ -115,7 +116,11 @@ export default {
         },
 
         getDoc() {
-            window.open('https://new.gdy.g107.com/system/doc');
+            window.open('https://oa.g107.com/system/doc');
+        },
+
+        previewDoc() {
+            window.open('https://oa.g107.com/doc/');
         },
 
         // 显示星号

+ 1 - 1
src/components/system/Jurisdiction.vue

@@ -76,7 +76,7 @@
           <el-table-column label="操作">
             <template slot-scope="scope">
               <el-button
-                v-if="$store.getters.site_info.creator_id!=scope.row.id&&scope.row.id!=$userInfo().id&&userInfo.per_permission.main"
+                v-if="$store.getters.site_info.creator_id != scope.row.id && scope.row.id != $userInfo().id&&userInfo.per_permission.main"
                 @click="deleteUser2(scope.row.id)" type="text" class="red">删除</el-button>
             </template>
           </el-table-column>

+ 14 - 2
src/home.vue

@@ -8,7 +8,7 @@
 
             <div class="flex-box-ce" v-if="user_info && user_info.id">
                 <div style="margin-right: 10px;">
-                  <userImage v-if="user_info && user_info.id" :id="user_info.id" :img_url="user_info.img_url" :user_name="user_info.name" width="50px" height="50px"></userImage>
+                  <userImage :id="userId" :img_url="img_url" :user_name="userName" width="50px" height="50px"></userImage>
                 </div>
                 <div class="flex-1">
                   <div class="flex-box-ce" style="margin-bottom: 6px;font-size: 14px;color: #666;font-weight: 700;">
@@ -136,8 +136,20 @@ export default {
     };
   },
   computed: {
-    ...mapGetters(['user_info','site_info'])
+    ...mapGetters(['user_info', 'site_info']),
+    userId() {
+      return this.user_info && this.user_info.id || '' 
+    },
+    userName() {
+      return this.user_info && this.user_info.name || '' 
+    },
+    img_url() {
+      // 组件渲染时 userInfo 可能还是空,用可选链兜底
+      return this.user_info && this.user_info.img_url || ''
+    },
   },
+
+ 
   methods: {
     openCursor(item){
       let urls=['https://www.yuque.com/xbddba/usmcgl?#','https://www.yuque.com/xbddba/qmvgbb?#','https://www.yuque.com/xbddba/pea8fp?#','https://www.yuque.com/xbddba/rtl7hs?#']

+ 23 - 4
src/index.vue

@@ -55,9 +55,9 @@
             </div>
             <!-- 切换公司或退出账号 -->
             <el-dropdown @command="handleCommand2">
-              <span class="el-dropdown-link" style="cursor: pointer;">
-                <userImage class="user_img" width="40px" height="40px" fontSize="14" :user_name="account_info.name"
-                  :img_url="account_info.img_url"></userImage>
+              <span v-if="user_info" class="el-dropdown-link" style="cursor: pointer;">
+                <userImage :id="userId" :img_url="img_url" :user_name="userName" fontSize="14" width="40px"
+                  height="40px"></userImage>
               </span>
               <el-dropdown-menu slot="dropdown">
                 <el-dropdown-item v-for="(group, index) in userConcent" :key="index" :command="group">
@@ -189,11 +189,30 @@ export default {
     };
   },
   computed: {
-    ...mapGetters(['site_info', 'account_info'])
+    ...mapGetters(['site_info', 'account_info', 'user_info']),
+    userId() {
+      return this.user_info && this.user_info.id || ''
+    },
+    userName() {
+      return this.user_info && this.user_info.name || ''
+    },
+    img_url() {
+      // 组件渲染时 userInfo 可能还是空,用可选链兜底
+      return this.user_info && this.user_info.img_url || ''
+    },
   },
 
   watch: {
+    // watch: {
+    //   $route(to, from) {
+    //     if (to.path === '/login') {
+    //       console.log('从登录页跳转过来,重新获取用户信息')
+    //     }
+    //   }
+    // },
     $route(to, from) {
+      // console.log('重新获取用户信息')
+      // this.$store.dispatch('getUserInfo')
       var str = to.path;
       this.menuArr.some((item, index) => {
           if (item.path == str) {

+ 19 - 1
src/main.js

@@ -4,6 +4,9 @@ import Element from 'element-ui'
 import 'element-ui/lib/theme-chalk/index.css';
 import '@/styles/index.scss'
 import moment from 'moment' // 时间库
+/* 引入并注册 composition-api */
+import VueCompositionAPI from '@vue/composition-api'
+Vue.use(VueCompositionAPI)
 import App from './App'
 import router from './router'
 import store from './store'
@@ -57,9 +60,14 @@ Vue.component('NoData', noData)
 Vue.component('BrawerBox', BrawerBox)
 Vue.component('TaskItem', TaskItem)
 Vue.component('VueOkrTree', VueOkrTree)
+
+
+
 Vue.use(Element, {
   size: 'medium',
 })
+
+
 Vue.prototype.$echarts = ECharts
 Vue.prototype.$axios = axios
 Vue.prototype.$axiosUser = axiosUser
@@ -97,7 +105,8 @@ Vue.prototype.$action = 'https://integralsys.oss-cn-shenzhen.aliyuncs.com'
 Vue.prototype.$acceptImg = 'image/jpeg,image/png'
 Vue.prototype.$acceptFile = 'application/pdf,application/vnd.ms-excel,application/msword,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document'
 Vue.prototype.$acceptImgFile ='image/jpeg,image/png,application/pdf,application/vnd.ms-excel,application/msword,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document'
-Vue.prototype.$xtoken={ 'X-Token': getToken() };
+Vue.prototype.$xtoken = { 'X-Token': getToken() };
+
 Vue.directive('dragscroll', function (el) {
   el.onmousedown = function (ev) {
     const disX = ev.clientX
@@ -172,6 +181,15 @@ Vue.use(Viewer, {
 });
 
 
+import VXETable from 'vxe-table'
+import 'vxe-table/lib/style.css'
+
+Vue.use(VXETable)
+
+
+// import FileView from '@/components/FileView'
+// Vue.component('FileView', FileView)
+
 
 new Vue({
   el: '#app',

+ 8 - 5
src/newPerformance/components/AnnualStatement.vue

@@ -239,8 +239,8 @@
         <EmployeeSelector :title="'选择部门'" :isChecKedAll="false" :can_select_employee="false" :can_select_dept="true"
             :dept_children="false" :selected="dept_selected" :visible.sync="show_dept_selector"
             @confirm="dept_confirm" />
-
-        <EmployeeSelector :multi="true" :is_filtration_creator="false" :selected="employeeSelectedObj"
+        <!-- 部门员工 -->
+        <EmployeeSelector :title="'选择员工'" :multi="true" :is_filtration_creator="false" :selected="employeeSelectedObj"
             :isChecKedAll="false" :visible.sync="showEmployeeSearch" @confirm="onEmployeeConfirm" />
     </div>
 </template>
@@ -333,13 +333,16 @@ export default {
             return str
         }
     },
+    
     computed: {
         ...mapGetters(['user_info']),
     },
+
     created() {
         this.getAllSet();
         this.getRecords();
     },
+
     methods: {
 
         exportToExcel(tableId, fileName) {
@@ -425,9 +428,9 @@ export default {
         // 应用筛选条件
         applyFilters() {
             this.filteredData = this.tableData.filter((item) => {
-                const levelMatch = this.filters.level.length === 0 || item.levelNames.some(level => this.filters.level === level);
-                const employeeMatch = this.filters.employee_ids.length === 0 || this.filters.employee_ids.some(employeeId => employeeId == item.employeeId);
-                const departmentMatch = this.filters.dept_ids.length === 0 || item.departments.some(dept => this.filters.dept_ids.includes(dept.id));
+                const levelMatch = this.filters.level && this.filters.level.length === 0 || item.levelNames.some(level => this.filters.level === level);
+                const employeeMatch = this.filters.employee_ids && this.filters.employee_ids.length === 0 || this.filters.employee_ids.some(employeeId => employeeId == item.employeeId);
+                const departmentMatch = this.filters.dept_ids && this.filters.dept_ids.length === 0 || item.departments.some(dept => this.filters.dept_ids.includes(dept.id));
                 return levelMatch && employeeMatch && departmentMatch;
             });
         },

+ 0 - 127
src/newPerformance/components/CombinationTemplates/BatchTemplatePublish.vue

@@ -1,127 +0,0 @@
-<template>
-    <div>
-        <el-dialog title="请选择考核模板" center :visible.sync="chooseExamineDialog" width="500px"
-            :before-close="dialogBeforeClose">
-            <div class="dialog-content" v-loading="loading">
-                <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange"
-                    style="margin-bottom: 10px;">全选</el-checkbox>
-                <div class="examine-list scroll-bar">
-                    <div class="examine-item" v-for="item in examineList" :key="item.templateId">
-                        <el-checkbox-group v-model="selectExamineIds" @change="changeSelectExamineIds">
-                            <el-checkbox :label="item.templateId"
-                                style="width: 100%; padding: 5px 0; box-sizing: border-box; margin-bottom: 10px; border-bottom: 1px solid #f1f1f1;">
-                                {{ item.title || '默认标题' }}
-                            </el-checkbox>
-                        </el-checkbox-group>
-                    </div>
-                </div>
-
-            </div>
-            <div slot="footer">
-                <el-button @click="dialogBeforeClose()">取 消</el-button>
-                <el-button type="primary" @click="next()" :disable="!(selectExamineIds && selectExamineIds.length > 0)">下一步</el-button>
-            </div>
-        </el-dialog>
-
-    </div>
-
-</template>
-
-
-<script>
-import moment from 'moment';
-import { mapGetters } from 'vuex';
-import InterviewFlow from "../TemplateDetails/InterviewFlow" // 面谈弹框
-
-export default {
-    components: {
-        InterviewFlow
-    },
-    model: {
-        prop: 'chooseExamineDialog',
-        event: 'close-dialog'
-    },
-    props: {
-        chooseExamineDialog: {
-            type: Boolean,
-            default: false
-        },
-        examineList: {
-            type: Array,
-            default: () => []
-        }
-    },
-
-    data() {
-        return {
-            loading: false,
-            selectExamineIds: [],
-            isIndeterminate: false,
-            checkAll: false,
-            interview: false,
-        }
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-    },
-    watch: {
-    },
-
-    mounted() {
-        
-    },
-
-    methods: {
-
-        handleCheckAllChange(v) {
-            if (v) {
-                this.examineList.forEach(examine => {
-                    this.selectExamineIds.push(examine.templateId)
-                })
-
-                this.isIndeterminate = true;
-                this.checkAll = true;
-            } else {
-                this.selectExamineIds = [];
-                this.isIndeterminate = false;
-                this.checkAll = false;
-            }
-        },
-        changeSelectExamineIds(v) { },
-
-        dialogBeforeClose() {
-            this.$emit('close-dialog', false)
-        },
-
-        next() {
-            this.$emit("onConfirm", this.selectExamineIds)
-            this.$emit('close-dialog', false)
-        }
-    }
-}
-
-</script>
-
-
-
-<style scoped="scoped" lang="scss">
-.status-btn-box {
-    width: 120px;
-    height: 40px;
-    z-index: 10;
-    position: absolute;
-    top: 20px;
-    left: 20px;
-}
-
-.dialog-content {
-    width: 100%;
-    height: 450px;
-
-    .examine-list {
-        width: 100%;
-        height: 400px;
-        overflow-y: auto;
-    }
-}
-</style>

+ 0 - 171
src/newPerformance/components/CombinationTemplates/EmployeeChooseOkrs.vue

@@ -1,171 +0,0 @@
-<template>
-    <div>
-        <el-dialog title="考核人员绑定OKR" center :visible.sync="chooseOkrsDialog" width="500px"
-            :before-close="dialogBeforeClose">
-            <div class="flex-box-ce" style="flex-direction: column; justify-content: center; width: 100%;">
-
-                <div class="title">
-                    已绑定的考核人员
-                </div>
-
-                <el-select v-model="employeeIds" placeholder="请选择指定人员" multiple filterable
-                    style="width: 100%; margin: 10px 0;" @change="changeEmployeeIds">
-                    <el-option v-for="item in employeeMap" :key="item.id" :label="item.name"
-                        :value="item.id"></el-option>
-                </el-select>
-
-
-                <div style="width: 100%; margin-bottom: 10px;" v-for="(item, index) in showEmployeeInfos" :key="index"
-                    @click="openSelectedOkrs(item)">
-                    <div class="flex-box-ce" style="width: 100%; justify-content: space-between; margin-bottom: 10px;">
-                        <div class="flex-box-ce">
-                            <userImage :id="item.employeeId" :img_url="item.img_url" :user_name="item.employeeName"
-                                width="30px" height="30px" style="margin-right: 5px;"></userImage>
-                            {{ item.employeeName }}
-                        </div>
-
-                        <el-link type="primary" size="small">请选择关联OKR</el-link>
-                    </div>
-                    <div class="selected-list" v-if="item.okrInfos && item.okrInfos.length > 0">
-                        <div class="selected-item" v-for="info in item.okrInfos">
-                            {{ info.name }}
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </el-dialog>
-
-        <!-- 关联OKR -->
-        <TargetSearch :visible.sync="isShowProject" @confirm="confirmProject" :selectedCheckList="selectedOkrs"
-            :showSelectedData="[]"></TargetSearch>
-    </div>
-</template>
-
-
-<script>
-import _ from "lodash"
-
-import TargetSearch from '@/performance/views/assessManagement/TargetSearch'; // 对齐目标
-
-export default {
-    components: {
-        TargetSearch
-    },
-    model: {
-        prop: 'chooseOkrsDialog',
-        event: 'close-dialog'
-    },
-    props: {
-        chooseOkrsDialog: {
-            type: Boolean,
-            default: false
-        },
-        selectEmployeeIds: {
-            type: Array,
-            default: () => []
-        },
-        employeeInfos: {
-            type: Array,
-            default: () => []
-        }
-    },
-
-    watch: {
-        chooseOkrsDialog(v) {
-            this.employeeIds = _.cloneDeep(this.selectEmployeeIds)
-            this.interviewFlow = _.cloneDeep(this.employeeInfos[0].interviewFlow)
-            this.showEmployeeInfos = _.cloneDeep(this.employeeInfos)
-        }
-    },
-
-    data() {
-        return {
-            employeeIds: [],
-            employeeMap: this.$getEmployeeMap(), // 员工列表
-            showEmployeeInfos: [],
-            interviewFlow: {},
-            isShowProject: false,
-            selectedCheckList: [],
-            selectedOkrs: [],
-            chooseEmployee: null
-        }
-    },
-
-    mounted() {
-        this.employeeIds = this.selectEmployeeIds;
-        this.employeeIds = _.cloneDeep(this.selectEmployeeIds)
-        this.interviewFlow = _.cloneDeep(this.employeeInfos[0].interviewFlow)
-        this.showEmployeeInfos = _.cloneDeep(this.employeeInfos)
-    },
-
-    methods: {
-        dialogBeforeClose() {
-            this.$emit('close-dialog', false)
-        },
-
-        changeEmployeeIds(v) {
-            this.employeeIds = v
-            this.employeeIds = Array.from(new Set(this.employeeIds.map(JSON.stringify))).map(JSON.parse);
-            console.log(this.employeeIds)
-            if (this.employeeIds && this.employeeIds.length > 0) {
-                this.employeeIds.forEach(employee => {
-                    let obj = {
-                        employeeId: employee,
-                        employeeName: this.employeeMap[employee].name,
-                        ids: [],
-                        img_url: this.employeeMap[employee].img_url,
-                        interviewFlow: this.interviewFlow
-                    }
-                    this.showEmployeeInfos.push(obj)
-                })
-            } else {
-                this.employeeIds = []
-                this.showEmployeeInfos = []
-            }
-            this.showEmployeeInfos = Array.from(new Set(this.showEmployeeInfos.map(JSON.stringify))).map(JSON.parse);
-        },
-
-        openSelectedOkrs(item) {
-            console.log(item);
-            this.chooseEmployeeId = item.employeeId;
-            this.selectedOkrs = item.ids;
-            this.isShowProject = true
-        },
-
-        confirmProject(okrs, selectedData) {
-            console.log(okrs)
-            this.showEmployeeInfos.forEach(item => {
-                if (item.employeeId == this.chooseEmployeeId) {
-                    item.ids = okrs
-                    item.okrInfos = selectedData
-                }
-            })
-            console.log(this.showEmployeeInfos)
-
-            // this.selectedData = selectedData;
-        }
-    }
-}
-</script>
-
-
-<style scoped lang="scss">
-.title {
-    width: 100%;
-    text-align: left;
-    line-height: 40px;
-    color: #999;
-}
-
-.selected-item {
-    padding: 5px;
-    box-sizing: border-box;
-    border-radius: 4px;
-    background: #f7f7f7;
-    margin-bottom: 5px;
-
-    &:hover {
-        cursor: pointer;
-    }
-}
-</style>

+ 0 - 572
src/newPerformance/components/ExamineContrast.vue

@@ -1,572 +0,0 @@
-<template>
-    <div class="contrast-container scroll-bar" style="padding-top: 10px;">
-
-        <!-- <div class="flex-box-ce title-box" style="" v-if="selectExamineList && selectExamineList.length > 0">
-            <div class="title">已选择的考核列表:</div>
-            <el-button size="mini" @click="openChooseExamineItem()">查看更多</el-button>
-        </div>
-
-
-        <div v-if="selectExamineList && selectExamineList.length > 0" class="template-list"
-            style="background: #f7f7f7; padding: 10px 10px 0 0; margin: 0 20px; border-radius: 4px;">
-            <template size="small" v-for="(item, index) in selectExamineList">
-                <el-tag :key="item.reviewPackageId" style="margin: 0 0 10px 10px;" closable
-                    @close="handleTagDelete(index)">
-                    {{ item.title }}
-                </el-tag>
-            </template>
-        </div> -->
-
-        <!-- <div class="flex-box-ce" style="padding: 0 20px;">
-            <el-button size="mini" @click="openChooseExamineItem()" style="margin-left: auto;">查看更多</el-button>
-                    :data="userList" style="width: 100%; " border stripe :header-cell-style="{ background: '#f5f7fa' }"
-                    v-loading="loading" :height="500">
-                    <el-table-column prop="employeeName" label="姓名" align="center">
-                    </el-table-column>
-                    <el-table-column :label="item.title" v-for="(item, index) in selectExamineList"
-                        :key="item.reviewPackageId" align="center" :render-header="(h, obj) => renderHeader(h, obj)">
-                        <template slot-scope="scope">
-                            <div v-for="user in item.users">
-                                <span v-if="user.employeeId == scope.row.employeeId">{{ user.score }}</span>
-                            </div>
-                        </template>
-                    </el-table-column>
-                </el-table>
-            </el-tab-pane>
-            <el-tab-pane label="地图" name="1" style="width: 100%;">
-                <div v-if="treeData && JSON.stringify(treeData) !== '{}'" class="flex-box-ce scroll-bar"
-                    style="width: 100%; align-items: center; justify-content: center; overflow-x: auto;">
-                    <vue2-org-tree :data="treeData" style="margin: 0 auto !important;" />
-                </div>
-            </el-tab-pane>
-        </el-tabs> -->
-
-        <el-dialog title="请选择需要对比的考核列表" center :visible.sync="dialogVisible" width="600px"
-            :before-close="dialogBeforeClose">
-            <div>
-                <div class="search-box">
-                    <el-select v-model="cycleType" placeholder="请选择周期类型" @change="changeCircle" style="width: 100px;"
-                        size="mini">
-                        <el-option v-for="item in cycleOptions" :key="item.value" :label="item.label"
-                            :value="item.value">
-                        </el-option>
-                    </el-select>
-
-                    <el-date-picker v-model="date" type="daterange" align="right" unlink-panels range-separator="至"
-                        start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd"
-                        :picker-options="pickerOptions" @change="changeDate" style="width: 300px; margin: 0 10px;"
-                        size="mini">
-                    </el-date-picker>
-
-                    <el-select v-model="status" placeholder="请选择" style="width: 100px;" @change="changeStatus"
-                        size="mini">
-                        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
-                        </el-option>
-                    </el-select>
-
-                    <el-button plain round size="mini" style="margin-left: 10px;" @click="reset">重 置</el-button>
-                </div>
-                <div class="package-list">
-
-                    <div class="template-list-box">
-                        <el-checkbox label="全选" v-model="isAllCheck" style="margin-bottom: 10px;"></el-checkbox>
-                        <div class="template-list scroll-bar">
-                            <div class="template-item" :class="item.isCheck ? 'active' : ''" v-for="item in examineList"
-                                :key="item.reviewPackageId" @click="chooseTemplate(item)">
-                                {{ item.title }}
-                            </div>
-                        </div>
-                    </div>
-
-                    <div class="choose-template-box">
-                        <el-button plain round size="mini" @click="clear">清 空</el-button>
-                        <div class="choose-template scroll-bar">
-                            <template v-for="(item, index) in chooseExamineList">
-                                <div v-if="item.isCheck" class="flex-box-ce choose-template-item"
-                                    style="justify-content: space-between;">
-                                    {{ item.title }}<i class="el-icon-close" @click="deleteItem(item, index)"></i>
-                                </div>
-                            </template>
-                            <div ref="placeholder" style="height: 50px;"></div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div slot="footer">
-                <el-button @click="dialogVisible = false">取 消</el-button>
-                <el-button type="primary" @click="confirm">确 定</el-button>
-            </div>
-        </el-dialog>
-
-        <div style="height: 50px;"></div>
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import moment from 'moment';
-import cloneDeep from 'lodash.clonedeep';
-
-export default {
-    data() {
-        return {
-            checkAll: false,
-            isIndeterminate: true,
-            dialogVisible: false,
-            activeName: "0",
-            loading: false,
-            treeData: {},
-            // 周期类型 0-未定义 1-年度 2-半年度 3-季度 4-月度
-            cycleType: '-1',
-            cycleOptions: [
-                { label: "全部", value: '-1' },
-                { label: "未定义", value: '0' },
-                { label: "年度", value: '1' },
-                { label: "半年度", value: '2' },
-                { label: "季度", value: '3' },
-                { label: "月度", value: '4' },
-            ],
-            status: -1,
-            options: [{
-                value: -1,
-                label: '全部'
-            }, {
-                value: '0',
-                label: '未完成'
-            }, {
-                value: '1',
-                label: '已完成'
-            }],
-            params: {
-                startDate: '',
-                endDate: '',
-                status: -1, // 不传默认返回全部 0-未完成 1-已完成
-            },
-            pickerOptions: {
-                shortcuts: [{
-                    text: '最近一周',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }, {
-                    text: '最近一个月',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }, {
-                    text: '最近三个月',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }]
-            },
-            date: [],
-            examineList: [], // 考核表列表
-            tableHeader: [],
-            tableData: [],
-            userList: [],
-            chooseExamineList: [],
-            selectExamineList: [], // 显示选择的数据
-            isAllCheck: false
-        }
-    },
-    watch: {
-        isAllCheck(v) {
-            if (v) {
-                this.examineList.forEach(item => item.isCheck = true)
-                this.chooseExamineList = this.examineList
-            } else {
-                this.examineList.forEach(item => item.isCheck = false)
-                this.chooseExamineList = []
-            }
-        }
-    },
-    filters: {
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        }
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-    },
-    created() {
-        this.getRecords();
-        this.dialogVisible = true;
-    },
-    methods: {
-
-        // 自定义表头
-        renderHeader(h, { column, $index }) {
-            let that = this;
-            return h(
-                'div', {
-                style: { display: "flex", alignItems: "center", justifyContent: "center" }
-            }, [
-                h('el-button', {
-                    props: {
-                        icon: 'el-icon-delete',
-                        size: 'mini'
-                    },
-                    style: 'padding: 5px',
-                    on: {
-                        click: function () {
-                            that.clickButton({ column, $index });
-                        }
-                    }
-                }, column.label)
-            ])
-        },
-
-        clickButton(obj) {
-            let { column, $index } = obj;
-            this.handleTagDelete($index - 1);
-        },
-
-        openChooseExamineItem() {
-            this.chooseExamineList = this.selectExamineList;
-            this.examineList.forEach(item => {
-                if (this.chooseExamineList && this.chooseExamineList.length > 0) {
-                    let flag = this.chooseExamineList.find(chooseExamine => chooseExamine.reviewPackageId == item.reviewPackageId)
-                    if (flag) {
-                        item.isCheck = true
-                    } else {
-                        item.isCheck = false
-                    }
-                }
-            })
-            this.dialogVisible = true
-        },
-
-        chooseTemplate(item) {
-            item.isCheck = !item.isCheck
-            let flag = this.chooseExamineList.find(chooseExamine => chooseExamine.reviewPackageId == item.reviewPackageId)
-            if (item.isCheck) {
-
-                if (!flag) this.chooseExamineList.push(item)
-            } else {
-                if (flag) {
-                    let index = this.chooseExamineList.findIndex(chooseExamine => chooseExamine.reviewPackageId == item.reviewPackageId)
-                    this.chooseExamineList.splice(index, 1)
-                } 
-            }
-            
-            
-            this.chooseExamineList = Array.from(new Set(this.chooseExamineList.map(JSON.stringify))).map(JSON.parse);
-        },
-
-        deleteItem(item, index) {
-            this.examineList.forEach(examine => {
-                
-                if (examine.reviewPackageId == item.reviewPackageId) {
-                    examine.isCheck = false
-                }
-                    
-            })
-            this.chooseExamineList.splice(index, 1)
-        },
-
-        
-
-        handleTagDelete(index) {
-            // 最后一个不能删除
-            if (this.selectExamineList && this.selectExamineList.length > 1)
-                this.selectExamineList.splice(index, 1)
-
-        },
-        getRecords() {
-            this.loading = true;
-
-            if (this.status === '-1') this.params.status = '' // 不传默认返回全部
-            else this.params.status = this.status
-            if (this.cycleType == '-1') {
-                if (this.params.hasOwnProperty('cycleType')) {
-                    delete this.params.cycleType
-                }
-            } else {
-                this.params = { ...this.params, cycleType: this.cycleType }
-            }
-            this.$axiosUser("get", `/performance/statistics/packages/${this.user_info.site_id}`, this.params).then(res => {
-                this.loading = false;
-                let { data: { data: { list, total }, code } } = res;
-                this.examineList = list;
-                this.examineList.forEach(item => {
-                    if (this.chooseExamineList && this.chooseExamineList.length > 0) {
-                        let flag = this.chooseExamineList.find(chooseExamine => chooseExamine.reviewPackageId == item.reviewPackageId)
-                        if (flag) {
-                            item.isCheck = true
-                        } else {
-                            item.isCheck = false
-                        }
-                    }
-                })
-                this.treeData = {
-                    id: 0,
-                    label: "考核对比",
-                    children: []
-                }
-            })
-        },
-        
-        initTableData() {
-            let userList = [];
-            let selectExamineList = this.chooseExamineList;
-
-            selectExamineList.forEach(item => {
-                let { reviewPackageId, title, users } = item;
-                if (users && users.length > 0) {
-                    users.forEach(user => {
-                        let { employeeName, employeeId, score } = user
-                        userList.push({ employeeName, employeeId, score: score ? score : 0 })
-                    })
-                }
-            })
-            this.userList = userList.reduce((acc, obj) => {
-                // 检查当前对象是否已经存在于结果数组中
-                if (!acc.find(item => item.employeeId === obj.employeeId)) { // 假设我们通过id来判断唯一性
-                    acc.push(obj);
-                }
-                return acc;
-            }, []);
-
-        },
-        initTreeData() {
-            this.selectExamineList.forEach(item => {
-                item.id = Date.now() + Math.floor(Math.random() * 10000);
-                item.label = item.title;
-                item.children = item.users;
-                item.users.forEach(user => {
-                    user.id = Date.now() + Math.floor(Math.random() * 10000);
-                    user.label = user.employeeName + ", " + (user.score ? user.score : 0);
-                })
-            })
-            this.treeData = {
-                id: 0,
-                label: "考核对比",
-                children: this.selectExamineList
-            }
-        },
-
-        handleClick(tab, event) {
-            if (this.activeName == '0') { 
-                if (this.selectExamineList && this.selectExamineList.length > 0) {
-                    this.initTableData()
-                }
-            } 
-            if (this.activeName == '1') {
-                if (this.selectExamineList && this.selectExamineList.length > 0) {
-                    this.initTreeData()
-                }
-            } 
-        },
-
-        // 日期选择时间
-        changeDate(v) {
-            if (v && v.length > 0) {
-                this.params.startDate = v[0] || ''
-                this.params.endDate = v[1] || ''
-                this.getRecords();
-            }
-        },
-        //选择周期
-        changeCircle(v) {
-            this.cycleType = v;
-            this.getRecords();
-        },
-        // 选择状态
-        changeStatus(v) {
-            this.getRecords();
-        },
-        // 重置搜索条件
-        reset() {
-            this.cycleType = '-1'
-            this.status = -1
-            this.date = []
-            this.params = {
-                startDate: '',
-                endDate: '',
-                status: -1, // 不传默认返回全部 0-未完成 1-已完成
-            }
-            this.getRecords();
-        },
-
-        // 清空选择的考核列表
-        clear() {
-            this.chooseExamineList.forEach(chooseExamine => {
-                this.examineList.forEach(examine => {
-                    if (chooseExamine.reviewPackageId == examine.reviewPackageId) {
-                        examine.isCheck = false
-                    }
-                })
-            })
-            this.isAllCheck = false;
-            this.chooseExamineList = [];
-        },
-
-        dialogBeforeClose() {
-            this.dialogVisible = false;
-        },
-
-        confirm() {
-            this.selectExamineList = cloneDeep(this.chooseExamineList);
-            if (this.activeName == '0') this.initTableData()
-            if (this.activeName == '1') this.initTreeData()
-            this.dialogVisible = false;
-        }
-    },
-
-}
-
-</script>
-
-
-
-<style scoped="scoped" lang="scss">
-
-.org-tree {
-    margin: 0 auto !important;
-}
-
-.contrast-container {
-    width: 100%;
-    height: 100%;
-    background-color: #fff;
-
-    .el-icon-close {
-        transition: all 0.2s;
-
-        &:hover {
-            font-size: 16px;
-        }
-    }
-
-    .search-box {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        box-sizing: border-box;
-    }
-
-    .title-box {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        margin-bottom: 10px;
-        padding: 0 20px;
-
-        .title {
-            color: #999;
-            font-size: 14px;
-            font-weight: bold;
-        }
-    }
-
-
-    .package-list {
-        width: 100%;
-        height: 400px;
-        display: flex;
-        margin-top: 10px;
-        border: 1px solid #f7f7f7;
-        .template-list-box {
-            width: 50%;
-            padding: 10px;
-            box-sizing: border-box;
-            border-right: 1px solid #f7f7f7;
-            .template-list {
-                width: 100%;
-                height: 350px;
-                overflow-y: auto;
-                display: flex;
-                flex-direction: column;
-                .template-item {
-                    width: 100%;
-                    height: 30px;
-                    line-height: 30px;
-                    border: 1px solid #f1f1f1;
-                    margin-bottom: 5px;
-                    border-radius: 6px;
-                    padding-left: 10px;
-                }
-        
-                .active {
-                    border: 1px solid #409eff;
-                    color: #409eff;
-                }
-            }
-        }
-
-        .choose-template-box {
-            width: 50%;
-            padding: 10px;
-            box-sizing: border-box;
-            .choose-template {
-                width: 100%;
-                height: 350px;
-                overflow-y: auto;
-        
-        
-                .line {
-                    width: 90%;
-                    height: 1px;
-                    background-color: #f7f7f7;
-                    margin: 10px auto;
-                }
-        
-                &-item {
-                    width: 90%;
-                    height: 30px;
-                    line-height: 30px;
-                    padding-left: 10px;
-                    border-bottom: 1px solid #f7f7f7;
-                    margin: 0 auto 10px auto;
-                    box-sizing: border-box;
-                }
-            }
-        }
-    }
-
-
-    .table-box {
-        width: 100%;
-        padding: 0 20px;
-        box-sizing: border-box;
-    }
-
-    /* 设置滚动条的宽度和背景色 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
-        width: 10px;
-        height: 10px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-    }
-
-
-}
-</style>

+ 0 - 11
src/newPerformance/components/ExamineRecord.vue

@@ -1,17 +1,6 @@
 <template>
     <div class="record-container">
-
         <ResultAnalysis  />
-        <!-- 水平线 -->
-        <!-- <div v-if="detailInfo" class="line"></div>
-        <div v-if="detailInfo" v-loading="loading" class="main-content">
-            <ResultAnalysis v-if="reviewPackageId" :detailInfo="detailInfo" />
-        </div>
-
-        <div v-else class="flex-box-v flex-center-center no-data-box" style="">
-            <img src="static/images/invite_new_company.png" style="" />
-            <div class="fontColorB">暂无考核数据</div>
-        </div> -->
     </div>
 </template>
 

+ 0 - 381
src/newPerformance/components/ExamineRecord/LeftExamineRecord.vue

@@ -1,381 +0,0 @@
-<template>
-    <div class="record-left">
-        <!-- 搜索条件 -->
-        <div class="search-box">
-            <div>
-                <el-checkbox v-model="checked" label="我发起的" border size="small"
-                    @change="changeSelfPublish"></el-checkbox>
-            </div>
-
-            <el-popover placement="bottom" trigger="click" ref="searchPopover">
-                <div class="searchBox" style="width: 300px;">
-                    <div
-                        style="border-bottom: 1px solid #f1f1f1;font-size: 16px;font-weight: 700;padding: 0 10px;padding-bottom: 10px;">
-                        筛选
-                    </div>
-                    <div style="margin: 10px 0;">考核表名称</div>
-                    <el-input placeholder="请输入考核表名称" v-model="params.keyword" prefix-icon="el-icon-search"
-                        style="width: 300px;" size="small"></el-input>
-
-                    <div style="margin: 10px 0;">考核周期</div>
-
-                    <el-date-picker v-model="date" type="daterange" align="right" unlink-panels
-                        value-format="yyyy-MM-dd" :picker-options="pickerOptions" @change="changeDate"
-                        style="width: 300px; " size="small">
-                    </el-date-picker>
-                    <div style="margin: 10px 0;">部门</div>
-                    <el-cascader ref="deptSelectRef" v-model="selected_dept_ids" size="small" style="width: 300px; "
-                        :options="deptList" @change="deptChange" filterable placeholder="请选择部门" clearable
-                        :show-all-levels="false" :props="{ checkStrictly: true }">
-                    </el-cascader>
-                    <div style="margin: 10px 0;">状态</div>
-                    <el-select v-model="status" placeholder="请选择" style="width: 100px;" @change="changeStatus"
-                        size="small">
-                        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
-                        </el-option>
-                    </el-select>
-                    <div class="flex-box-end">
-                        <el-button size="small" plain round @click="close">取 消</el-button>
-                        <el-button size="small" type="primary" plain round @click="confirm">确 定</el-button>
-                    </div>
-                </div>
-                <template slot="reference">
-                    <div class="gd"><i class="el-icon-finished" style="margin-right: 5px; color: #999;"></i>筛选</div>
-                </template>
-            </el-popover>
-        </div>
-        <!-- 水平线 -->
-        <div class="line"></div>
-
-        <!-- 表格数据 -->
-        <div class="scroll-bar" style="width: 100%; flex: 1; ">
-            <el-table
-                :data="tableData"
-                v-loading="loading" style="width: 100%; height: 500px;" border
-                :header-cell-style="{ background: '#f5f7fa' }" 
-                @row-click="handleSeleRecord"
-                :row-style="rowStyle"
-                >
-                <el-table-column prop="title" label="考核名称" min-width="30%" align="center">
-                    <template slot-scope="scope">
-                        <PreBox :value="scope.row.title" />
-                    </template>
-                </el-table-column>
-                <el-table-column label="周期" align="center" min-width="30%">
-                    <template slot-scope="scope">
-                        <div>{{ scope.row.startTime | formatDate }} 至 {{ scope.row.endTime | formatDate }}</div>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="start" label="开始时间" min-width="20%" align="center">
-                    <template slot-scope="scope">
-                        <div>{{ scope.row.startTime | formatDate }}</div>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="users" label="进度" min-width="20%" align="center">
-                    <template slot-scope="scope">
-                        <el-progress :percentage="scope.row.users | filterProgress"></el-progress>
-                    </template>
-                </el-table-column>
-            </el-table>
-            <div class="flex-box-ce" style="justify-content: center; margin-top: 20px;">
-                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
-                    :current-page="params.page" :page-sizes="[10, 20, 30, 40, 50]" :page-size="params.pageSize"
-                    layout="total, sizes, prev, pager, next" :total="total">
-                </el-pagination>
-            </div>
-        </div>
-
-    </div>
-</template>
-
-
-<script>
-import { mapGetters } from 'vuex';
-import moment from 'moment';
-import EmployeeSelector from '@/components/EmployeeSelector'; // 选择部门组件
-
-export default {
-    components: {
-        EmployeeSelector,
-        RightExamineRecord
-    },
-    data() {
-        return {
-            isShow: false,
-            total: 0,
-            loading: false,
-            checked: [],
-            status: -1,
-            options: [
-                {
-                    value: -1,
-                    label: '全部'
-                }, {
-                    value: '0',
-                    label: '未完成'
-                }, {
-                    value: '1',
-                    label: '已完成'
-                }
-            ],
-            tableData: [],
-
-            pickerOptions: {
-                shortcuts: [{
-                    text: '最近一周',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }, {
-                    text: '最近一个月',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }, {
-                    text: '最近三个月',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }]
-            },
-            date: [],
-            reviewPackageId: 0,
-            deptList: [], // 部门列表 - 树形结构
-            dept_list: [], // 部门列表
-            selected_dept_ids: [], // 选择的部门列表
-            selfPublish: false,
-            params: {
-                selfPublish: 0,
-                keyword: '',
-                page: 1,
-                pageSize: 10,
-                startDate: '',
-                endDate: '',
-                status: -1, // 不传默认返回全部 0-未完成 1-已完成 
-                deptId: ''
-            },
-            selectedReviewPackageId: '',
-        }
-    },
-    
-    created() {
-        this.getRecords();
-        this.get_dept_list(); // 获取部门列表
-        this.$bus.$on("finishEdit", (reviewPackageId) => {
-            this.selectedReviewPackageId = reviewPackageId
-            this.getRecords();
-        })
-    },
-    computed: {
-        ...mapGetters(['user_info'])
-    },
-    filters: {
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        },
-        filterProgress(list) {
-            if (list && list.length > 0) {
-                let sum = 0;
-                list.forEach(item => {
-                    if (item.status == 1) sum += 1 // 完成的个数
-                })
-                return Number(sum / list.length) * 100
-            }
-        }
-    },
-    methods: {
-        confirm() {
-            this.$refs.searchPopover && this.$refs.searchPopover.doClose();
-            this.getRecords();
-        },
-        close() {
-            this.$refs.searchPopover && this.$refs.searchPopover.doClose();
-        },
-        getRecords() {
-            this.loading = true
-            this.params.selfPublish = this.selfPublish ? 1 : 0
-            if (this.status === '-1') this.params.status = '' // 不传默认返回全部
-            else this.params.status = this.status
-            this.$axiosUser("get", `/performance/statistics/packages/${this.user_info.site_id}`, this.params).then(res => {
-                this.loading = false;
-                let { data: { data: { list, total }, code } } = res
-                this.tableData = list;
-                this.total = total;
-                if (this.selectedReviewPackageId) {
-                    this.$emit('selectRow', this.selectedReviewPackageId);
-                } else {
-                    let { reviewPackageId } = this.tableData[0]
-                    this.reviewPackageId = reviewPackageId
-                    this.$emit('selectRow', reviewPackageId); 
-                }
-                
-            })
-        },
-        // 是否我发起的
-        changeSelfPublish(v) {
-            this.selfPublish = !this.selfPublish;
-            this.params.selfPublish = this.selfPublish ? 1 : 0;
-            this.getRecords();
-        },
-        
-        // 处理部门树状结构数据
-        getTreeData(data) {
-            for (var i = 0; i < data.length; i++) {
-                data[i].checked = false;
-                if (data[i].children.length < 1) {
-                    // children若为空数组,则将children设为undefined
-                    data[i].children = undefined;
-                } else {
-                    // children若不为空数组,则继续 递归调用 本方法
-                    this.getTreeData(data[i].children);
-                }
-            }
-            return data;
-        },
-
-        // 获取部门
-        get_dept_list() {
-            this.$axiosUser('get', '/api/pro/department/tree', '', 'v2').then(res => {
-                this.dept_list = res.data.data.list; // 用来回显选择的部门数据
-                this.deptList = this.getTreeData(this.dept_list); // 处理成树状结构
-            });
-        },
-
-        deptChange(val) {
-            this.params.deptId = val.toString()
-        },
-        
-
-        // 日期选择时间
-        changeDate(v) {
-            this.params.startDate = v[0] || ''
-            this.params.endDate = v[1] || ''
-        },
-
-        handleSizeChange(v) {
-            this.params.pageSize = v
-            this.getRecords();
-        },
-        handleCurrentChange(v) {
-            this.params.page = v
-            this.getRecords();
-        },
-
-        changeStatus(v) {
-            // this.getRecords();
-        },
-
-        // 表格行单击事件
-        handleSeleRecord(data) {
-            let { reviewPackageId } = data;
-            if (this.reviewPackageId == reviewPackageId) return
-            this.reviewPackageId = reviewPackageId
-            this.$emit('selectRow', reviewPackageId)
-            // console.log(data)
-        },
-        // 更改选中行背景色
-        rowStyle({ row }) {
-            if (this.reviewPackageId === row.reviewPackageId) {
-                return {
-                    'background-color': 'rgb(236, 245, 255)', cursor: 'pointer' };
-            }
-            return { cursor: 'pointer' };
-        },
-    }
-}
-
-</script>
-
-<style lang="scss">
-    .record-left {
-        /* 取消表格鼠标进入高亮显示 */ 
-        .el-table__row:hover>td {
-            background-color: transparent;
-        }
-    }
-        
-</style>
-
-<style scoped="scoped" lang="scss">
-    .gd {
-        border-left: 1px solid #f1f1f1;
-        padding: 0 10px;
-        margin-left: 10px;
-        padding-right: 0px;
-        cursor: pointer;
-        position: relative;
-    }
-
-    .gd i {
-        font-size: 18px;
-    }
-    .w300 {
-        width: 300px;
-    }
-    .active {
-        color: #409eff;
-        background: #ecf5ff;
-        border-color: #b3d8ff;
-    }
-    .record-left {
-        width: 49.6%;
-        height: 100%;
-        border-radius: 5px;
-        background: #fff;
-        padding: 10px 20px;
-        box-sizing: border-box;
-        overflow: hidden;
-        overflow-y: auto;
-        display: flex;
-        flex-direction: column;
-        .search-box {
-            display: flex;
-            align-items: center;
-            justify-content: space-between;
-            width: 100%;
-            height: 30px;
-            .btn-box {
-                padding: 7px 5px;
-                border: 1px solid #DCDFE6;
-                border-radius: 4px;
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-    
-        .line {
-            width: 100%;
-            height: 1px;
-            background: #f1f1f1;
-            margin: 10px 0;
-        }
-        ::-webkit-scrollbar {
-            width: 10px;
-            height: 10px;
-            background-color: #f9f9f9;
-        }
-        ::-webkit-scrollbar-thumb {
-            border-radius: 6px;
-            background-color: #c1c1c1;
-        }
-        ::-webkit-scrollbar-thumb:hover {
-                background-color: #a8a8a8;
-            }
-        ::-webkit-scrollbar-track {
-            box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-            border-radius: 6px;
-            background: #ededed;
-        }
-    }
-</style>

+ 0 - 142
src/newPerformance/components/ExamineRecord/PieChart1.vue

@@ -1,142 +0,0 @@
-<template>
-    <!-- 按考核状态分布 -->
-    <div ref="chart1" :style="myChartStyle"></div>
-</template>
-
-<script>
-
-import echarts from 'echarts';
-
-export default {
-    props: {
-        tableData: {
-            type: Array,
-            default: () => []
-        }
-    },
-    data() {
-        return {
-            myChart: null,
-            myChartStyle: { width: "100%", height: "400px" },
-            colorList: [
-                { c1: ' #40d3ff', c2: '#409EFF' }, { c1: ' #ede737', c2: '#FF9600' }, { c1: '#89e398', c2: '#67c23a' },
-                { c1: ' #85E9C7', c2: '#00C4CB' }, { c1: ' #f393a9', c2: '#f56c6c' }, { c1: '#e69cf3', c2: '#de43f9' },
-            ],
-        }
-    },
-
-    computed: {
-        title() {
-            let users = []
-            this.tableData.forEach(item => {
-                if (item.users && item.users.length > 0) {
-                    item.users.forEach(user => {
-                        users.push(user);
-                    })
-                }
-            })
-            return "考核总人数" + users.length
-        },
-        // 考核表状态
-        examineStatus() {
-            let examineStatus = [
-                { name: "进行中", value: 0 },
-                { name: "已结束", value: 0 },
-            ]
-            let users = []
-            this.tableData.forEach(item => {
-                if (item.users && item.users.length > 0) {
-                    item.users.forEach(user => {
-                        users.push(user);
-                    })
-                }
-            })
-            examineStatus[0].value = users.filter(item => item.status == 0).length;
-            examineStatus[1].value = users.filter(item => item.status == 1).length;
-            return examineStatus
-        },
-    },
-
-    watch: {  //此处为关键,监听tableData值的变化,进行echarts渲染
-        tableData(v){
-            this.initEcharts1(); //值发生改变则渲染一次echarts
-        }
-    },
-
-    mounted() {
-        this.initEcharts1();
-    },
-    beforeDestroy() {
-        if (this.myChart) {
-            this.myChart.clear();//清空当前实例,会移除实例中所有的组件和图表
-            this.myChart.dispose();//销毁实例,实例销毁后无法再被使用
-        }
-    },
-    methods: {
-        initEcharts1() {
-            const colorList = this.colorList;
-
-               
-            const option = {
-                title: {
-                    show: true,
-                    text: this.title,
-                    itemGap: 8,
-                    left: '48%',
-                    top: '0',
-                    textStyle: {
-                        color: '#000',
-                        fontSize: 16,
-                    },
-                    
-                    x: 'center',
-                    y: 'center',
-                    textAlign: 'center'
-                },
-                tooltip: {//悬浮提示组件
-                    trigger: 'item',
-                },
-                legend: {
-                    show: true,
-                    icon: "circle",
-                    itemWidth: 10,  // 设置宽度
-                    itemHeight: 10, // 设置高度
-                    x: 'center',
-                    y: 'bottom',
-                    itemGap: 30
-                },
-
-                series: [
-                    {
-                        type: "pie",
-                        radius: ['40%', '65%'],//小的是内径,大的是外径
-                        data: this.examineStatus,
-                        itemStyle: {
-                            emphasis: {
-                                shadowBlur: 9,
-                                shadowOffsetX: 0,
-                                shadowColor: 'rgba(0, 0, 0, 0.5)'
-                            },
-                            normal: {
-                                label: {
-                                    show: true,
-                                    formatter: '{b} : {c}'
-                                },
-                                labelLine: { show: true },
-                                color: function (params) {//颜色渐变函数 前四个参数分别表示四个位置依次为左、下、右、上
-                                    return new echarts.graphic.LinearGradient(0, 1, 0, 0, [{ offset: 0, color: colorList[params.dataIndex].c1 }, { offset: 1, color: colorList[params.dataIndex].c2 }])
-                                }
-                            }
-                        }
-                    }
-                ]
-            };
-            this.myChart = this.$echarts.init(this.$refs.chart1);
-            this.myChart.setOption(option);
-            window.addEventListener("resize", () => {
-                this.myChart.resize();
-            });
-        },
-    }
-}
-</script>

+ 0 - 131
src/newPerformance/components/ExamineRecord/RightEamineComp/EditCateType.vue

@@ -1,131 +0,0 @@
-<template>
-    <!-- 考核分类 -->
-    <div class="circle" style="margin-right: 20px;">
-        <el-popover ref="popoverRef2" placement="right" width="400" trigger="click">
-            <div class="popover-box">
-                <el-select v-model="chooseCateIds" placeholder="请选择考核分类" style="width: 280px; margin-bottom: 10px;"
-                    size="small" multiple @change="changeCateIds">
-                    <el-option v-for="item in cateList" :key="item.cateId" :label="item.name" :value="item.cateId">
-                    </el-option>
-                </el-select>
-                <div class="footer" style="margin-top: 20px;">
-                    <el-button size="mini" @click="cancelChange">取消</el-button>
-                    <el-button type="primary" size="mini" @click="confirmChange">确定</el-button>
-                </div>
-            </div>
-            <template slot="reference">
-                <div class="reference">
-                    <div class="cate-list" v-if="cateIds && cateIds.length > 0">
-                        <template v-for="item in cateList">
-                            <div v-if="cateIds.includes(item.cateId)" class="cate-item" :key="item.cateId">
-                                {{ item.name }}
-                            </div>
-                        </template>
-                    </div>
-                    <div v-else class="fontColorC flex-box-ce">
-                        未绑定考核分类 <i class="el-icon-edit" style="margin-left: 10px; color: #999;"></i>
-                    </div>
-                </div>
-            </template>
-        </el-popover>
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-
-export default {
-    name: "EditCateType",
-    props: {
-        reviewPackageId: {
-            type: String | Number,
-            default: ""
-        },
-        cateIds: {
-            type: Array,
-            default: () => []
-        },
-        cateList: {
-            type: Array,
-            default: () => []
-        },
-    },
-    data() {
-        return {
-            chooseCateIds: []
-        }
-    },
-    watch: {
-        cateIds(v) {
-            this.chooseCateIds = this.cateIds;
-        }
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-    },
-
-    mounted() {
-        this.chooseCateIds = this.cateIds;
-    },
-    methods: {
-        changeCateIds(v) {
-            this.chooseCateIds = v
-        },
-
-        cancelChange() {
-            this.chooseCateIds = []
-            this.$refs.popoverRef2 && this.$refs.popoverRef2.doClose();
-        },
-
-        confirmChange() {
-            let url = `/performance/statistics/bind/cate/${this.user_info.site_id}`
-            let reviewPackageId = this.reviewPackageId
-            let data = {
-                reviewPackageId,
-                cateIds: this.chooseCateIds
-            }
-            this.$http.post(url, data).then(res => {
-                let { code } = res
-                if (code == 1) {
-                    this.$emit('comfirmChanged', this.chooseCateIds)
-                    this.cancelChange()
-                } else {
-                    this.$message.error(res.msg || "操作失败")
-                }
-            })
-        },
-    }
-}
-
-</script>
-<style scoped lang="scss">
-.popover-box {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-}
-
-.reference {
-    width: 100%;
-    border: 1px solid #DCDFE6;
-    border-radius: 4px;
-    padding: 7px 10px 0 10px;
-    box-sizing: border-box;
-    .cate-list {
-        display: flex;
-        flex-wrap: wrap;
-        .cate-item {
-            padding: 5px;
-            border-radius: 4px;
-            background-color: #f7f7f7;
-            color: #999;
-            margin-right: 5px;
-            margin-bottom: 7px;
-            &:hover {
-                cursor: pointer;
-            }
-        }
-    }
-}
-</style>

+ 0 - 259
src/newPerformance/components/ExamineRecord/RightEamineComp/EditCircle.vue

@@ -1,259 +0,0 @@
-<template>
-    <!-- 考核周期 -->
-    <div class="circle" style="margin-right: 20px;">
-        <el-popover ref="popoverRef2" placement="right" width="400" trigger="click">
-            <div class="popover-box">
-                <div class="selectBox">
-                    <SelectPeriod :dateParameter="dateParameter" @confirm="dateConfirm" :id="1">
-                        <div class="flex-box-ce cursor">
-                            <div>{{ dateParameter.year }}</div>
-                            <div style="margin: 0 10px;">{{ dateParameter.name }}</div>
-                            <i class="el-icon-caret-bottom fontColorC"></i>
-                        </div>
-                    </SelectPeriod>
-                </div>
-
-                <el-date-picker v-if="params.cycleType == 0" v-model="date" type="daterange" align="right" unlink-panels
-                    range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd"
-                    :picker-options="pickerOptions" @change="changeDate">
-                </el-date-picker>
-
-                <div class="footer" style="margin-top: 20px;">
-                    <el-button size="mini" @click="cancelChange">取消</el-button>
-                    <el-button type="primary" size="mini" @click="confirmChange">确定</el-button>
-                </div>
-            </div>
-            <template slot="reference">
-                <div
-                    style="width: 100%; border: 1px solid #DCDFE6; border-radius: 4px; padding: 7px 10px; box-sizing: border-box; ">
-                    {{ startTime | formatDate }} 至 {{ endTime | formatDate }}
-                    <i class="el-icon-edit" style="margin-left: 10px; color: #999;"></i>
-                </div>
-            </template>
-        </el-popover>
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import moment from 'moment';
-// 计算某一季度开始日期和结束日期
-function getQuarterDates(year, quarter) {
-    // 计算季度的开始日期(第一个月的第一天)
-    const startDate = moment().year(year).quarter(quarter).startOf('quarter');
-    // 计算季度的结束日期(最后一个月的最后一天)
-    const endDate = moment().year(year).quarter(quarter).endOf('quarter');
-
-    return {
-        start: startDate,
-        end: endDate
-    };
-}
-import SelectPeriod from '@/okr/components/public/SelectPeriod'; //选择周期
-
-export default {
-    name: "EditCircle",
-    components: {
-        SelectPeriod
-    },
-    props: {
-        reviewPackageId: {
-            type: String | Number,
-            default: ""
-        },
-        startTime: {
-            type: String,
-            default: "--"
-        },
-        endTime: {
-            type: String,
-            default: "--"
-        }
-    },
-    data() {
-        return {
-            params: {
-                cycleType: 0, // 周期类型 0-未定义 1-年度 2-半年度 3-季度 4-月度
-                startDate: '',
-                endDate: ''
-            },
-            dateParameter: {
-                year: moment().format('YYYY'),
-                cycle_type: 0,
-                dateId: 1,
-                name: '全部周期'
-            },
-            pickerOptions: {
-                shortcuts: [{
-                    text: '最近一周',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }, {
-                    text: '最近一个月',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }, {
-                    text: '最近三个月',
-                    onClick(picker) {
-                        const end = new Date();
-                        const start = new Date();
-                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
-                        picker.$emit('pick', [start, end]);
-                    }
-                }]
-            },
-            date: [],
-        }
-    },
-    watch: {
-        startTime(v) {
-            this.params.startDate = v
-        },
-        endTime(v) {
-            this.params.endDate = v
-        }
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-    },
-    filters: {
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        }
-    },
-    methods: {
-        // 日期选择时间
-        changeDate(v) {
-            this.params.startDate = v[0] || ''
-            this.params.endDate = v[1] || ''
-        },
-        //选择周期
-        dateConfirm(item) {
-            this.dateParameter = item;
-            let year = item.year;
-            if (item.name == '全部周期') this.params.cycleType = 0
-
-            if (item.name == '年度') {
-                this.params.cycleType = 1
-                // 计算年份的开始时间(即1月1日)
-                const startOfYear = moment().year(year).startOf('year');
-                // 计算年份的结束时间(即12月31日)
-                const endOfYear = moment().year(year).endOf('year');
-                this.params.startDate = startOfYear.format('YYYY-MM-DD');
-                // 年度结束时间
-                this.params.endDate = endOfYear.format('YYYY-MM-DD');
-            }
-            if (item.name == '上半年') {
-                this.params.cycleType = 2
-                // 获取年初
-                let startOfYear = moment().year(year).startOf('year');
-                // 获取上半年结束日(6月30日)
-                let endOfFirstHalfYear = moment().year(year).startOf('year').add(6, 'months').subtract(1, 'days');
-                this.params.startDate = startOfYear.format('YYYY-MM-DD');
-                this.params.endDate = endOfFirstHalfYear.format('YYYY-MM-DD');
-
-            }
-            if (item.name == '下半年') {
-                this.params.cycleType = 2
-                let startOfSecondHalfYear = moment().year(year).startOf('year').add(6, 'months'); // 获取下半年开始日(7月1日)
-                let endOfYear = moment().year(year).endOf('year'); // 获取年末
-                this.params.startDate = startOfSecondHalfYear.format('YYYY-MM-DD');
-                this.params.endDate = endOfYear.format('YYYY-MM-DD');
-            }
-
-            if (item.name.includes('季度')) {
-
-                this.params.cycleType = 3;
-                // 第一季度
-                if (item.name === "第一季度") {
-                    const dates = getQuarterDates(year, 1);
-                    this.params.startDate = dates.start.format('YYYY-MM-DD');
-                    this.params.endDate = dates.end.format('YYYY-MM-DD');
-                }
-
-                // 第一季度
-                if (item.name === "第二季度") {
-                    const dates = getQuarterDates(year, 2);
-                    this.params.startDate = dates.start.format('YYYY-MM-DD');
-                    this.params.endDate = dates.end.format('YYYY-MM-DD');
-                }
-
-                // 第三季度
-                if (item.name === "第三季度") {
-                    const dates = getQuarterDates(year, 3);
-                    this.params.startDate = dates.start.format('YYYY-MM-DD');
-                    this.params.endDate = dates.end.format('YYYY-MM-DD');
-                }
-
-                // 第四季度
-                if (item.name === "第四季度") {
-                    const dates = getQuarterDates(year, 4);
-                    this.params.startDate = dates.start.format('YYYY-MM-DD');
-                    this.params.endDate = dates.end.format('YYYY-MM-DD');
-                }
-            }
-            if (item.name.includes('月')) {
-                this.params.cycleType = 4
-                let month = item.name.substring(0, item.name.length - 1); // 获取月份
-                // 计算开始时间(该月的第1天)
-                const startOfMonth = moment(`${year}-${month}-01`);
-                this.params.startDate = startOfMonth.format('YYYY-MM-DD');
-
-                // 计算结束时间(该月的最后一天)
-                const endOfMonth = moment(startOfMonth).endOf('month');
-                this.params.endDate = endOfMonth.format('YYYY-MM-DD');
-            }
-            // this.getTemplateList()
-        },
-        cancelChange() {
-            this.$refs.popoverRef2 && this.$refs.popoverRef2.doClose();
-        },
-
-        confirmChange() {
-            let url = `/performance/statistics/package/time/${this.user_info.site_id}`
-            let reviewPackageId = this.reviewPackageId
-            let data = {
-                reviewPackageId,
-                ...this.params
-            }
-            this.$http.post(url, data).then(res => {
-
-                let { code, data: { startTime, endTime } } = res
-                if (code == 1) {
-                    this.$refs.popoverRef2 && this.$refs.popoverRef2.doClose();
-                    this.$emit('comfirmChanged', { startTime, endTime })
-                } else {
-                    this.$message.error(res.msg || "操作失败")
-                }
-                
-            })
-        },
-    }
-}
-
-</script>
-<style scoped lang="scss">
-.popover-box {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-
-    .selectBox {
-        border: 1px solid #ccc;
-        border-radius: 25px;
-        padding: 8px 20px;
-        width: 100%;
-        margin: 0 20px 20px 20px;
-    }
-}
-</style>

+ 0 - 78
src/newPerformance/components/ExamineRecord/RightEamineComp/EditTitle.vue

@@ -1,78 +0,0 @@
-<template>
-    <!-- 考核标题 -->
-    <div class="title">
-        <!-- {{ title }}
-        <el-popover ref="popoverRef" placement="right" width="400" trigger="click">
-            <div class="flex-box-ce">
-                <el-input v-model="editTitle" placeholder="请输入模板名称" size="small"></el-input>
-                <el-button type="primary" size="small" style="margin-left: 10px;" @click="handleEditTitle()">确定</el-button>
-            </div>
-            <i class="el-icon-edit" slot="reference" style="margin-left: 10px; color: #999;"></i>
-        </el-popover> -->
-        <el-input v-model="editTitle" placeholder="请输入模板名称" size="small" @blur="handleEditTitle()"></el-input>
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-export default {
-    name: "EditTitle",
-    props: {
-        reviewPackageId: {
-            type: String | Number,
-            default: ""
-        },
-        title: {
-            type: String,
-            default: "默认标题"
-        }
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-    },
-    watch: {
-        title(v) {
-            this.editTitle = this.title
-        }
-    },
-    data() {
-        return {
-            editTitle: ""
-        }
-    },
-    mounted() {
-        this.editTitle = this.title
-    },
-    methods: {
-        // 编辑模板标题
-        handleEditTitle() {
-            let title = this.editTitle
-            let reviewPackageId = this.reviewPackageId
-            if (title !== null && title !== '') {
-                let url = `/performance/statistics/package/title/${this.user_info.site_id}`
-                this.$http.post(url, { reviewPackageId, title }).then(res => {
-                    if (res.code == 1) {
-                        this.$refs.popoverRef && this.$refs.popoverRef.doClose();
-                        this.$emit("handleEditTile", res.data.title);
-                        // this.$bus.$emit("finishEditTitle")
-                    } else {
-                        this.$message.error(res.msg || "操作失败")
-                    }
-                })
-            }
-        },
-    }
-}
-
-</script>
-<style scoped lang="scss">
-
-
-
-    .title {
-        font-size: 16px;
-        font-weight: 600;
-        margin-right: 20px;
-        display: flex;
-    }
-</style>

+ 0 - 685
src/newPerformance/components/ExamineRecord/RightExamineRecord copy.vue

@@ -1,685 +0,0 @@
-<template>
-    <div class="record-right scroll-box" style="overflow-y: auto;" v-loading="loading">
-        <div class="title-container flex-box-ce" style="height: 30px; justify-content: space-between;">
-            <div class="flex-box-ce">
-                <el-popover placement="bottom" trigger="click" ref="searchPopover">
-                    <div class="searchBox">
-                        <div class="search-title"
-                            style="border-bottom: 1px solid #f1f1f1; font-size: 16px; font-weight: 700; padding: 0 10px; padding-bottom: 10px;">
-                            修改考核表
-                        </div>
-
-                        <div style="margin: 10px 0;">考核表名称</div>
-
-                        <EditTitle v-if="reviewPackageId" :reviewPackageId="reviewPackageId" :title="title"
-                            @handleEditTile="changeTitle" />
-                        <div style="margin: 10px 0;">考核表时间</div>
-                        <EditCircle v-if="reviewPackageId" :reviewPackageId="reviewPackageId" :startTime="startTime"
-                            :endTime="endTime" @comfirmChanged="changeDate" />
-                        <div style="margin: 10px 0;">考核分类</div>
-
-                        <EditCateType v-if="reviewPackageId" :reviewPackageId="reviewPackageId" :cateIds="cateIds"
-                            :cateList="cateList" @comfirmChanged="changeCateIds" />
-
-                    </div>
-                    <template slot="reference">
-                        <div class="gd">
-                            <i class="el-icon-edit" style="margin-right: 5px; color: #999;"></i>
-                            <strong style="margin-right: 5px;">{{ title }}</strong>
-                            {{ startTime | formatDate }} 至 {{ endTime | formatDate }}
-                        </div>
-                    </template>
-                </el-popover>
-
-                <el-button v-if="packageOkrs && packageOkrs.length > 0" type="text" style="margin-left: 10px;"
-                    @click="openTargetList(packageOkrs)">考核表OKR</el-button>
-            </div>
-            <div>
-                <!-- 正太规则 -->
-                <EditScoreList v-if="reviewPackageId" :reviewPackageId="reviewPackageId" :scoreList="scoreList" />
-            </div>
-        </div>
-
-        <div class="line"></div>
-
-
-        <!-- 考核人员分数列表 -->
-        <div class="score-list">
-            <div class="score-item heartBeat animated">
-                <div class="score-item-title">总人数</div>
-                <div class="score-item-num">{{ userTotal }}</div>
-                <div class="score-item-percent">{{ userComplete }}人已完成</div>
-            </div>
-            <div v-for="item in gradeLevels" class="score-item heartBeat animated">
-                <div class="score-item-title">{{ item.name }}</div>
-                <div class="score-item-num">{{ users.filter(user => user.level === item.name).length }}</div>
-                <div class="score-item-percent">{{ item.min + '~' + item.max }}</div>
-            </div>
-        </div>
-
-        <!-- 考核人员列表 -->
-        <div class="user-info flex-box-ce">
-            <div class="info-card" v-for="item in users" :key="item.employeeId">
-                <div class="info" style="height: 30px;">{{ item.employeeName }}</div>
-                <div class="info">
-                    <span class="info-label fontColorC">考核状态:</span>
-
-                    <el-tag v-if="item.status" type="success">
-                        已完成
-                    </el-tag>
-                    <el-tag v-else="item.status" type="warning">
-                        进行中
-                    </el-tag>
-                </div>
-                <div class="info">
-                    <span class="info-label fontColorC">评分:</span>
-                    <el-tag v-if="item.level === '未评分'" type="info">
-                        未评分
-                    </el-tag>
-                    <el-tag v-else>
-                        {{ item.level }}
-                    </el-tag>
-                </div>
-                <div class="info">
-                    <span class="info-label fontColorC">正态分布:</span>
-                    <el-tag>
-                        {{ item.scoreResult }}
-                    </el-tag>
-                </div>
-                <div class="info">
-                    <span class="info-label fontColorC">关联okr</span>
-                    <el-button v-if="item.okrs && item.okrs.length > 0" type="text"
-                        @click="openTargetList(item.okrs)">个人OKR</el-button>
-                    <span class="fontColorC" v-else>暂无关联</span>
-                </div>
-            </div>
-        </div>
-        
-
-        <!-- 指标列表 -->
-        <div class="title-container" style="margin: 10px 0;">
-            <div class="title">指标信息</div>
-        </div>
-
-        <el-tabs type="card" v-model="activeName" @tab-click="handleClick">
-            <el-tab-pane label="默认" name="1">
-                <el-table ref="fmeaTableRef2" :data="tableData1" stripe style="width: 100%" border
-                    v-table-move="['fmeaTableRef2']" :header-cell-style="{ background: '#f5f7fa' }" :height="330">
-                    <el-table-column prop="employeeName" label="员工" align="center"></el-table-column>
-                    <el-table-column prop="title" label="指标" align="center">
-                        <template slot-scope="scope">
-                            <el-tooltip class="item" effect="dark" placement="top">
-                                <div v-html="scope.row.title" slot="content" style="max-width:300px"></div>
-                                <div class="oneLine">{{ scope.row.title }}</div>
-                            </el-tooltip>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="target" label="目标" align="center" width="100">
-                        <template slot-scope="scope">
-                            <span v-if="scope.row.target !== null">
-                                {{ `${scope.row.target} ${scope.row.unit ? scope.row.unit : ''}` }}
-                            </span>
-                            <span v-else>--</span>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="result" label="结果" align="center" width="100">
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.result || '--' }}
-                            </div>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="different" label="差距" align="center" width="100">
-                        <template slot-scope="scope">
-                            <el-tag v-if="scope.row.difference > 0" type="success">
-                                {{ scope.row.difference }}
-                            </el-tag>
-                            <el-tag v-else-if="scope.row.difference < 0" type="danger">
-                                {{ scope.row.difference }}
-                            </el-tag>
-                            <div v-else>
-                                --
-                            </div>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="score" label="评分" align="center" width="100">
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.score || '--' }}
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="okrs" label="关联OKR" width="100" align="center">
-                        <template slot-scope="scope">
-                            <el-link v-if="scope.row.okrs && scope.row.okrs.length > 0" type="primary"
-                                @click="openTargetList(scope.row.okrs)">
-                                指标OKR
-                            </el-link>
-                            <span v-else class="fontColorC">暂无关联</span>
-                        </template>
-                    </el-table-column>
-                </el-table>
-            </el-tab-pane>
-
-            <el-tab-pane label="按指标/目标/单位聚合" name="2">
-                <el-table ref="fmeaTableRef3" :data="tableData2" stripe style="width: 100%" border
-                    v-table-move="['fmeaTableRef3']" :header-cell-style="{ background: '#f5f7fa' }" :height="300">
-                    <el-table-column prop="title" label="指标" align="center">
-                        <template slot-scope="scope">
-                            <el-tooltip class="item" effect="dark" placement="top">
-                                <div v-html="scope.row.title" slot="content" style="max-width:300px"></div>
-                                <div class="oneLine">{{ scope.row.title }}</div>
-                            </el-tooltip>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="target" label="目标" align="center" width="100">
-                        <template slot-scope="scope">
-                            <div>
-                                <span v-if="scope.row.target !== null">
-                                    {{ `${scope.row.target} ${scope.row.unit ? scope.row.unit : ''}` }}
-                                </span>
-                                <span v-else>--</span>
-                            </div>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="avgResult" label="均值" align="center">
-
-                    </el-table-column>
-
-                    <el-table-column prop="standardResultRate" label="超出目标比例" align="center">
-                        <template slot-scope="scope">
-                            <el-tag v-if="parseInt(scope.row.standardResultRate) > 0" type="success">
-                                {{ scope.row.standardResultRate }}
-                            </el-tag>
-                            <el-tag v-else-if="parseInt(scope.row.standardResultRate) < 0" type="danger">
-                                {{ scope.row.standardResultRate }}
-                            </el-tag>
-                            <el-tag v-else type="info">
-                                {{ scope.row.standardResultRate }}
-                            </el-tag>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="standardCount" label="达标数" align="center" />
-                    <el-table-column prop="standardRate" label="达标率" align="center">
-                        <template slot-scope="scope">
-                            <el-tag v-if="parseInt(scope.row.standardRate) > 0" type="success">
-                                {{ scope.row.standardRate }}
-                            </el-tag>
-                            <el-tag v-else-if="parseInt(scope.row.standardRate) < 0" type="danger">
-                                {{ scope.row.standardRate }}
-                            </el-tag>
-                            <el-tag v-else type="info">
-                                {{ scope.row.standardRate }}
-                            </el-tag>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="avgScore" label="平均分" align="center" />
-                </el-table>
-            </el-tab-pane>
-        </el-tabs>
-
-        <!-- 关联okr -->
-        <TargetListComp v-if="targetDialogVisible" :dialogVisible="targetDialogVisible" :ids="okrs"
-            @close="closeTargetList">
-        </TargetListComp>
-    </div>
-</template>
-
-
-<script>
-import { mapGetters } from 'vuex';
-import moment from 'moment';
-import _ from "lodash"
-
-import EditTitle from './RightEamineComp/EditTitle'; // 修改考核标题组件
-import EmployeeSelector from '@/components/EmployeeSelector'; // 选择部门组件
-import EditScoreList from './RightEamineComp/EditScoreList'
-import EditCircle from './RightEamineComp/EditCircle.vue';
-import EditCateType from './RightEamineComp/EditCateType.vue';
-import TargetListComp from "@/performance/views/assessManagement/TargetListComp.vue"; // 关联OKR弹框
-
-export default {
-    components: {
-        EditTitle,
-        EditScoreList,
-        EmployeeSelector,
-        EditCircle,
-        EditCateType,
-        TargetListComp
-    },
-    props: {
-        detailInfo: {
-            type: Object,
-            default: () => { }
-        },
-        cateList: {
-            type: Array,
-            default: () => []
-        },
-    },
-    data() {
-        return {
-            loading: false,
-            activeName: "1",
-            reviewPackageId: "",
-            title: "默认标题",
-            startTime: "",
-            endTime: "",
-            scoreList: [],
-            users: [], //考核人员列表
-            tableData1: [], // 考核中的指标列表,
-            tableData2: [], // 按单位/目标/聚合指标列表,
-            distributionId: "",
-            level_enable: false,
-            packages: [],
-            userTotal: 0,
-            userComplete: 0,
-            userIncomplete: 0,
-            infos: [],
-            gradeLevels: [],
-            cateIds: [], // 选择的考核分类
-            targetDialogVisible: false,
-            okrs: [],
-            packageOkrs: []
-        };
-    },
-    watch: {
-        detailInfo(v) {
-            this.loading = true
-            this.activeName = '1'
-            let { data: { data: { cateIds, indicators, startTime, endTime, title, okrs, distribution: { items }, users }, code }, reviewPackageId } = v
-            this.getAllSet();
-            this.packageOkrs = okrs;
-            this.cateIds = cateIds;
-            this.tableData1 = [];
-            this.tableData2 = [];
-            this.reviewPackageId = reviewPackageId;
-            this.title = title;
-            this.startTime = startTime;
-            this.endTime = endTime;
-            this.scoreList = items;
-            this.distributionId = this.scoreList[0].id
-            this.users = users;
-            this.tableData1 = indicators;
-            this.tableData1.forEach(item => {
-                if (item.target && item.result) {
-                    item.difference = item.result - item.target
-                } else {
-                    item.difference = '--'
-                }
-            })
-            this.userTotal = 0;
-            this.userComplete = 0;
-            this.userIncomplete = 0;
-            let distribution = [];
-            let userScores = []
-            this.scoreList.forEach(item => {
-                item.level = item.name;
-                item.ratio = item.scale / 100
-                distribution.push(item)
-            })
-            this.users.forEach(user => {
-                this.userTotal++;
-                this.userComplete += user.status === 1 ? 1 : 0;
-                user.level = this.findGrade(user.score, this.gradeLevels);
-                userScores.push(user.score)
-            })
-            this.infos = [
-                { label: "总人数", num: this.userTotal },
-                { label: "已完成", num: this.userComplete },
-                { label: "未评分", num: this.userIncomplete },
-            ]
-            let scoreResult = this.assignLevels(userScores, distribution);
-
-            this.users.forEach(item => {
-                scoreResult.forEach(result => {
-                    if (result.scores.includes(item.score)) {
-                        item.scoreResult = result.level
-                    }
-                })
-            })
-
-            this.loading = false
-        }
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-        calcScoreList() {
-            let scoreSet = new Set(this.users.map(item => Number(item.score)))
-
-            let scores = [...scoreSet].sort((a, b) => b - a);
-            let rate = 1;
-            let scoreCount = scores.length; // 总人数
-            let scoreIndex = 0;
-            let scoreResult = {};
-
-            this.scoreList.forEach(item => {
-
-                let scale = item.scale / 100;
-                let count = Math.round((scoreCount - scoreIndex) * scale / rate);
-                rate -= scale;
-                if (count <= 0) return;
-
-                for (let i = scoreIndex; i < (scoreIndex + count); i++) {
-                    scoreResult[scores[i]] = item.name;
-                }
-                scoreIndex += count;
-            });
-            return this.users.map(item => {
-                let result = { ...item };
-                result.scoreResult = scoreResult[item.score] || '--'
-                return result;
-            }).sort((a, b) => b.score - a.score);
-        }
-    },
-    filters: {
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        }
-    },
-    created() {
-    },
-    methods: {
-
-        changeCateIds(cateIds) {
-            this.cateIds = cateIds
-            this.$bus.$emit("finishEdit", this.reviewPackageId)
-        },
-        changeTitle(title) {
-            this.title = title;
-            this.$bus.$emit("finishEdit", this.reviewPackageId)
-        },
-
-        changeDate(data) {
-            let { startTime, endTime } = data
-            this.startTime = startTime
-            this.endTime = endTime
-            this.$bus.$emit("finishEdit", this.reviewPackageId)
-        },
-
-        
-
-        // 获取全局等级设置
-        async getAllSet() {
-            let res = await this.$axiosUser('get', 'api/pro/per/user/base_config')
-            let data = res.data.data;
-            let levels = data.level_scope.levels;
-            let gradeLevels = [];
-            let max = 0;//最大值
-            if (levels && levels.length > 0) {
-                levels.forEach((item, index) => {
-                    var obj;
-                    if (index == 0) {
-                        obj = { name: item.name, max: Number(item.value), min: 0 };
-                    } else {
-                        obj = { name: item.name, max: Number(item.value), min: max };//当不是第一个等级时,最小值为上一个的最大值
-                    }
-                    max = item.value;
-                    gradeLevels.push(obj);
-                })
-                this.gradeLevels = gradeLevels
-            }
-        },
-
-        // 查找分数对应的等级
-        findGrade(score, gradeLevels) {
-            for (let i = 0; i < gradeLevels.length; i++) {
-                if (score && score >= gradeLevels[i].min && score && score <= gradeLevels[i].max) {
-                    return gradeLevels[i].name; // 返回对应的等级描述
-                } else if (score && score <= gradeLevels[0].min) {
-                    return gradeLevels[0].name; // 返回对应的等级描述
-                } else if (score && score >= gradeLevels[gradeLevels.length - 1].max) {
-                    return gradeLevels[gradeLevels.length - 1].name; // 返回对应的等级描述
-                }
-            }
-            return "未评分"; // 如果分数不在任何范围内
-        },
-
-        
-
-        assignLevels(scores, levelConfigs) {
-            // 降序排序并去重(假设分数不重复,可省略去重)
-            const sortedScores = [...scores].sort((a, b) => b - a);
-            const total = sortedScores.length;
-            if (total === 0) return [];
-
-            // 归一化处理比例
-            const totalRatio = levelConfigs.reduce((sum, cfg) => sum + cfg.ratio, 0);
-            const normalized = levelConfigs.map(cfg => cfg.ratio / totalRatio);
-
-            // 计算每个等级的初始人数
-            let counts = normalized.map(ratio => Math.floor(total * ratio));
-            let remainder = total - counts.reduce((sum, c) => sum + c, 0);
-
-            // 分配剩余人数,按优先级顺序
-            let idx = 0;
-            while (remainder > 0 && idx < counts.length) {
-                counts[idx]++;
-                remainder--;
-                idx++;
-            }
-
-            // 构建结果:按人数切割数组
-            let start = 0;
-            return counts.map((count, i) => {
-                const end = start + count;
-                const levelScores = sortedScores.slice(start, end);
-                start = end;
-                return {
-                    level: levelConfigs[i].level,
-                    scores: levelScores
-                };
-            });
-        },
-
-        // 选项卡点击事件
-        handleClick(tab, event) {
-            this.tableData2 = []
-            if (this.activeName == 2) {
-                let groups = _.groupBy(this.tableData1, item => `${item.title}(_)${item.target === null || item.target === '' ? 'null' : item.target}(_)${item.unit === null || item.unit === '' ? 'null' : item.unit}`);
-                Object.keys(groups).forEach(key => {
-                    let group = {
-                        title: '',
-                        target: '',
-                        unit: '',
-                        userCount: 0,
-                        scoredCount: 0,
-                        standardCount: 0,
-                        failCount: 0,
-                        standardRate: '--',
-                        totalScore: 0,
-                        totalResult: 0,
-                        avgScore: 0,
-                        avgResult: 0,
-                        standardResultRate: '--'
-                    };
-                    groups[key].forEach(indicator => {
-                        group.title = indicator.title; // 指标名称
-                        group.target = indicator.target; // 目标
-                        group.unit = indicator.unit; // 单位
-                        let standardCount = indicator.difference !== '--' && indicator.difference >= 0 ? 1 : 0; // 
-                        group.userCount += 1;
-                        group.scoredCount += indicator.score !== null ? 1 : 0;
-                        group.standardCount += standardCount;
-                        group.failCount += standardCount === 1 ? 0 : 1;
-                        if (indicator.score !== null) group.totalScore += indicator.score;
-                        if (indicator.result !== null) group.totalResult += indicator.result;
-                    });
-                    group.standardCount = group.standardCount * 100;
-                    if (group.userCount > 0) {
-                        let rate = Math.floor(group.standardCount / group.userCount * 100 * 0.01);
-                        let avgScore = Math.floor(group.totalScore / group.userCount * 100 * 0.01);
-                        let avgResult = Math.floor(group.totalResult / group.userCount * 100 * 0.01);
-                        group.standardRate = rate > 0 ? `${rate}%` : '--';
-                        group.avgScore = avgScore !== 0 ? avgScore : '--';
-                        group.avgResult = avgResult !== 0 ? avgResult : '--';
-
-                        if (group.target !== null && group.avgResult !== '--') {
-                            let standardResultRate = Math.floor((group.avgResult - group.target) / group.target * 100 * 0.01 * 100) ;
-                            group.standardResultRate = standardResultRate !== 0 ? `${standardResultRate}%` : '--';
-                        }
-                    }
-                    this.tableData2.push(group);
-                    console.log(this.tableData2);
-                })
-            }
-        },
-        closeTargetList() {
-            this.targetDialogVisible = false
-        },
-
-        openTargetList(okrs) {
-            if (okrs && okrs.length > 0) {
-                this.okrs = okrs
-                this.targetDialogVisible = true
-            } else {
-                return this.$message.error("暂无关联okr")
-            }
-        }
-    }
-}
-
-</script>
-
-<style>
-.oneLine {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-</style>
-
-
-<style scoped="scoped" lang="scss">
-.record-right {
-    width: 49.6%;
-    height: 100%;
-    border-radius: 5px;
-    background: #fff;
-    padding: 10px 20px;
-    box-sizing: border-box;
-    overflow: hidden;
-    overflow-y: auto;
-
-    .title-container {
-        display: flex;
-        align-items: center;
-
-        .searchBox {
-            width: 300px;
-            .search-title {
-                border-bottom: 1px solid #f1f1f1;
-                font-size: 16px;
-                font-weight: 700;
-                padding: 0 10px;
-                padding-bottom: 10px;
-            }
-        }
-        
-
-        .title {
-            font-weight: 700;
-            font-size: 16px;
-        }
-    }
-
-    .line {
-        width: 100%;
-        height: 1px;
-        background: #f1f1f1;
-        margin: 10px 0;
-    }
-
-    .score-list {
-        display: flex;
-        width: 100%;
-        margin-top: 20px;
-        .score-item {
-            flex: 0 0 calc((100% - 80px) / 5);
-            height: 100px;
-            padding: 10px;
-            margin: 0 20px 20px 0;
-            box-sizing: border-box;
-            border-radius: 6px;
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            justify-content: space-around;
-            font-size: 16px;
-            color: #999;
-            box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
-
-            &-title {
-                font-weight: 600;
-                color: #409EFF;
-            }
-
-            &-num {
-                color: #000;
-                font-weight: 600;
-            }
-
-            &:nth-child(5n) {
-                /* 去除第5n个的margin-right */
-                margin-right: 0;
-            }
-        }
-    }
-       
-
-    .user-info {
-        width: 100%;
-        height: 200px;
-        overflow: hidden;
-        overflow-x: auto;
-        /* 设置滚动条的宽度和背景色 */
-        &::-webkit-scrollbar {
-            width: 10px;
-            height: 10px;
-            background-color: #f9f9f9;
-        }
-    
-        /* 设置滚动条滑块的样式 */
-        &::-webkit-scrollbar-thumb {
-            border-radius: 6px;
-            background-color: #c1c1c1;
-        }
-    
-        /* 设置滚动条滑块hover样式 */
-        &::-webkit-scrollbar-thumb:hover {
-            background-color: #a8a8a8;
-        }
-    
-        /* 设置滚动条轨道的样式 */
-        &::-webkit-scrollbar-track {
-            box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-            border-radius: 6px;
-            background: #ededed;
-        }
-        .info-card {
-            width: 220px;
-            height: 100%;
-            margin-right: 20px;
-            border: 1px solid #f1f1f1;
-            padding: 5px 10px;
-            border-radius: 6px;
-            box-sizing: border-box;
-            box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
-            .info {
-                display: flex;
-                align-items: center;
-                height: 36px;
-        
-                .info-label {
-                    width: 100px;
-                }
-            }
-        }
-        
-    }
-}
-</style>

+ 0 - 789
src/newPerformance/components/ExamineRecord/RightExamineRecord.vue

@@ -1,789 +0,0 @@
-<template>
-    <div class="record-right scroll-box" style="overflow-y: auto;" v-loading="loading">
-        <!-- 考核表详情 -->
-        <div class="title-container" style="margin-bottom: 10px;">
-            <div class="title">考核详情
-            </div>
-        </div>
-        <div class="title-container flex-box-ce" style="height: 30px; justify-content: space-between;">
-            <div class="flex-box-ce">
-                <div class="gd">
-                    <strong style="margin-right: 5px;">{{ title }}</strong>
-                    {{ startTime | formatDate }} 至 {{ endTime | formatDate }}
-                </div>
-
-                <!-- <el-button v-if="packageOkrs && packageOkrs.length > 0" type="text" style="margin-left: 10px;"
-                    @click="openTargetList(packageOkrs)">考核表OKR</el-button> -->
-            </div>
-            <div>
-                <!-- 正太规则 -->
-                <EditScoreList v-if="reviewPackageId" :reviewPackageId="reviewPackageId" :scoreList="scoreList" />
-            </div>
-        </div>
-
-        <div class="line"></div>
-
-
-        <!-- 考核人员分数列表 -->
-        <!-- <div class="score-list">
-            <div class="score-item heartBeat animated">
-                <div class="score-item-title">总人数</div>
-                <div class="score-item-num">{{ userTotal }}</div>
-                <div class="score-item-percent">{{ userComplete }}人已完成</div>
-            </div>
-            <div v-for="item in gradeLevels" class="score-item heartBeat animated">
-                <div class="score-item-title">{{ item.name }}</div>
-                <div class="score-item-num">{{ users.filter(user => user.level === item.name).length }}</div>
-                <div class="score-item-percent">{{ item.min + '~' + item.max }}</div>
-            </div>
-        </div> -->
-
-
-
-        <div style="width: 100%; display: flex;">
-            <div style="width: 50%; border-right: 1px solid #f1f1f1;">
-                <div ref="echarts2" class="echarts"></div>
-            </div>
-            <div style="width: 50%; padding: 0 20px; box-sizing: border-box;">
-                <el-table :data="gradeLevels" style="width: 100%;" stripe :header-cell-style="{ background: '#f5f7fa' }">
-                    <el-table-column prop="name" label="等级">
-                        <template slot-scope="scope">
-                            {{ scope.row.name }} ({{ scope.row.min + '~' + scope.row.max }})
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="name" label="人数">
-                        <template slot-scope="scope">
-                            {{ users.filter(user => user.level === scope.row.name).length }}
-                        </template>
-                    </el-table-column>
-                </el-table>
-            </div>
-        </div>
-
-        <!-- 考核人员列表 -->
-        <div class="title-container" style="margin: 10px 0;">
-            <div class="title">考核人员列表</div>
-        </div>
-
-        <el-table :data="users" style="width: 100%; " :header-cell-style="{ background: '#f5f7fa' }">
-            <el-table-column prop="employeeName" label="员工">
-            </el-table-column>
-
-            <el-table-column prop="status" label="考核状态">
-                <template slot-scope="scope">
-                    <el-tag v-if="scope.row.status" type="success">
-                        已完成
-                    </el-tag>
-                    <el-tag v-else="scope.row.status" type="warning">
-                        进行中
-                    </el-tag>
-                </template>
-            </el-table-column>
-
-            <el-table-column prop="level" label="评分">
-                <template slot-scope="scope">
-                    <el-tag v-if="scope.row.level === '未评分'" type="info">
-                        未评分
-                    </el-tag>
-                    <el-tag v-else>
-                        {{ item.level }}
-                    </el-tag>
-                </template>
-            </el-table-column>
-
-            <el-table-column prop="scoreResult" label="正态分布">
-                <template slot-scope="scope">
-                    <el-tag>
-                        {{ scope.row.scoreResult }}
-                    </el-tag>
-                </template>
-            </el-table-column>
-
-            <el-table-column label="操作">
-                <template slot-scope="scope">
-                    <el-link type="primary" @click="getDetails()">查看详情</el-link>
-                </template>
-            </el-table-column>
-
-        </el-table>
-
-
-        <!-- 指标列表 -->
-        <div class="title-container" style="margin: 10px 0;">
-            <div class="title">指标信息</div>
-        </div>
-
-        <el-tabs type="card" v-model="activeName" @tab-click="handleClick">
-            <el-tab-pane label="默认" name="1">
-                <el-table  :data="tableData1" stripe style="width: 100%" border  :header-cell-style="{ background: '#f5f7fa' }" :height="500">
-                    <el-table-column prop="employeeName" label="员工" align="center"></el-table-column>
-                    <el-table-column prop="title" label="指标" align="center">
-                        <template slot-scope="scope">
-                            <el-tooltip class="item" effect="dark" placement="top">
-                                <div v-html="scope.row.title" slot="content" style="max-width:300px"></div>
-                                <div class="oneLine">{{ scope.row.title }}</div>
-                            </el-tooltip>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="target" label="目标" align="center" >
-                        <template slot-scope="scope">
-                            <span v-if="scope.row.target !== null">
-                                {{ `${scope.row.target} ${scope.row.unit ? scope.row.unit : ''}` }}
-                            </span>
-                            <span v-else>--</span>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="result" label="结果" align="center">
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.result || '--' }}
-                            </div>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="different" label="差距" align="center" >
-                        <template slot-scope="scope">
-                            <el-tag v-if="scope.row.difference > 0" type="success">
-                                {{ scope.row.difference }}
-                            </el-tag>
-                            <el-tag v-else-if="scope.row.difference < 0" type="danger">
-                                {{ scope.row.difference }}
-                            </el-tag>
-                            <div v-else>
-                                --
-                            </div>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="score" label="评分" align="center" >
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.score || '--' }}
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="okrs" label="过程跟踪" align="center">
-                        <template slot-scope="scope">
-                            <el-link v-if="scope.row.okrs && scope.row.okrs.length > 0" type="primary"
-                                @click="openTargetList(scope.row.okrs)">
-                                指标OKR
-                            </el-link>
-                            <span v-else class="fontColorC">暂无关联</span>
-                        </template>
-                    </el-table-column>
-                </el-table>
-                <div style="margin-top: 20px;"></div>
-
-            </el-tab-pane>
-
-            <el-tab-pane label="按指标/目标/单位聚合" name="2">
-                <el-table :data="tableData2" stripe style="width: 100%" border:header-cell-style="{ background: '#f5f7fa' }" :height="500">
-                    <el-table-column prop="title" label="指标" align="center">
-                        <template slot-scope="scope">
-                            <el-tooltip class="item" effect="dark" placement="top">
-                                <div v-html="scope.row.title" slot="content" style="max-width:300px"></div>
-                                <div class="oneLine">{{ scope.row.title }}</div>
-                            </el-tooltip>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="target" label="目标" align="center">
-                        <template slot-scope="scope">
-                            <div>
-                                <span v-if="scope.row.target !== null">
-                                    {{ `${scope.row.target} ${scope.row.unit ? scope.row.unit : ''}` }}
-                                </span>
-                                <span v-else>--</span>
-                            </div>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="avgResult" label="均值" align="center">
-
-                    </el-table-column>
-
-                    <el-table-column prop="standardResultRate" label="超出目标比例" align="center">
-                        <template slot-scope="scope">
-                            <el-tag v-if="parseInt(scope.row.standardResultRate) > 0" type="success">
-                                {{ scope.row.standardResultRate }}
-                            </el-tag>
-                            <el-tag v-else-if="parseInt(scope.row.standardResultRate) < 0" type="danger">
-                                {{ scope.row.standardResultRate }}
-                            </el-tag>
-                            <el-tag v-else type="info">
-                                {{ scope.row.standardResultRate }}
-                            </el-tag>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="standardCount" label="达标数" align="center" />
-                    <el-table-column prop="standardRate" label="达标率" align="center">
-                        <template slot-scope="scope">
-                            <el-tag v-if="parseInt(scope.row.standardRate) > 0" type="success">
-                                {{ scope.row.standardRate }}
-                            </el-tag>
-                            <el-tag v-else-if="parseInt(scope.row.standardRate) < 0" type="danger">
-                                {{ scope.row.standardRate }}
-                            </el-tag>
-                            <el-tag v-else type="info">
-                                {{ scope.row.standardRate }}
-                            </el-tag>
-                        </template>
-                    </el-table-column>
-                    <el-table-column prop="avgScore" label="平均分" align="center" />
-                </el-table>
-
-            </el-tab-pane>
-        </el-tabs>
-
-        <div style="height: 50px;"></div>
-
-        <!-- 关联okr -->
-        <TargetListComp v-if="targetDialogVisible" :dialogVisible="targetDialogVisible" :ids="okrs"
-            @close="closeTargetList">
-        </TargetListComp>
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import moment from 'moment';
-import _ from "lodash"
-import ECharts from 'echarts';
-
-import EditTitle from './RightEamineComp/EditTitle'; // 修改考核标题组件
-import EmployeeSelector from '@/components/EmployeeSelector'; // 选择部门组件
-import EditScoreList from './RightEamineComp/EditScoreList'
-import EditCircle from './RightEamineComp/EditCircle.vue';
-import EditCateType from './RightEamineComp/EditCateType.vue';
-import TargetListComp from "@/performance/views/assessManagement/TargetListComp.vue"; // 关联OKR弹框
-
-export default {
-    components: {
-        EditTitle,
-        EditScoreList,
-        EmployeeSelector,
-        EditCircle,
-        EditCateType,
-        TargetListComp
-    },
-    props: {
-        detailInfo: {
-            type: Object,
-            default: () => { }
-        },
-        cateList: {
-            type: Array,
-            default: () => []
-        },
-    },
-    data() {
-        return {
-            loading: false,
-            activeName: "1",
-            reviewPackageId: "",
-            title: "默认标题",
-            startTime: "",
-            endTime: "",
-            scoreList: [],
-            users: [], //考核人员列表
-            tableData1: [], // 考核中的指标列表,
-            tableData2: [], // 按单位/目标/聚合指标列表,
-            distributionId: "",
-            level_enable: false,
-            packages: [],
-            userTotal: 0,
-            userComplete: 0,
-            userIncomplete: 0,
-            infos: [],
-            gradeLevels: [],
-            cateIds: [], // 选择的考核分类
-            targetDialogVisible: false,
-            okrs: [],
-            packageOkrs: []
-        };
-    },
-    watch: {
-        detailInfo(v) {
-            this.initData();
-        }
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-        calcScoreList() {
-            let scoreSet = new Set(this.users.map(item => Number(item.score)))
-
-            let scores = [...scoreSet].sort((a, b) => b - a);
-            let rate = 1;
-            let scoreCount = scores.length; // 总人数
-            let scoreIndex = 0;
-            let scoreResult = {};
-
-            this.scoreList.forEach(item => {
-
-                let scale = item.scale / 100;
-                let count = Math.round((scoreCount - scoreIndex) * scale / rate);
-                rate -= scale;
-                if (count <= 0) return;
-
-                for (let i = scoreIndex; i < (scoreIndex + count); i++) {
-                    scoreResult[scores[i]] = item.name;
-                }
-                scoreIndex += count;
-            });
-            return this.users.map(item => {
-                let result = { ...item };
-                result.scoreResult = scoreResult[item.score] || '--'
-                return result;
-            }).sort((a, b) => b.score - a.score);
-        }
-    },
-    filters: {
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        }
-    },
-    mounted() {
-        if (this.detailInfo && this.detailInfo.reviewPackageId) this.initData();
-    },
-    created() {
-    },
-    methods: {
-        async initData() {
-            this.loading = true
-            this.activeName = '1'
-            let { data: { data: { cateIds, indicators, startTime, endTime, title, okrs, distribution: { items }, users }, code }, reviewPackageId } = this.detailInfo
-            await this.getAllSet();
-            this.packageOkrs = okrs;
-            this.cateIds = cateIds;
-            this.tableData1 = [];
-            this.tableData2 = [];
-            this.reviewPackageId = reviewPackageId;
-            this.title = title;
-            this.startTime = startTime;
-            this.endTime = endTime;
-            this.scoreList = items;
-            this.distributionId = this.scoreList[0].id
-            this.users = users;
-            this.tableData1 = indicators;
-            this.tableData1.forEach(item => {
-                if (item.target && item.result) {
-                    item.difference = item.result - item.target
-                } else {
-                    item.difference = '--'
-                }
-            })
-            this.userTotal = 0;
-            this.userComplete = 0;
-            this.userIncomplete = 0;
-            let distribution = [];
-            let userScores = []
-            this.scoreList.forEach(item => {
-                item.level = item.name;
-                item.ratio = item.scale / 100
-                distribution.push(item)
-            })
-            this.users.forEach(user => {
-                this.userTotal++;
-                this.userComplete += user.status === 1 ? 1 : 0;
-                user.level = this.findGrade(user.score, this.gradeLevels);
-                userScores.push(user.score)
-            })
-            this.infos = [
-                { label: "总人数", num: this.userTotal },
-                { label: "已完成", num: this.userComplete },
-                { label: "未评分", num: this.userIncomplete },
-            ]
-            let scoreResult = this.assignLevels(userScores, distribution);
-
-            this.users.forEach(item => {
-                scoreResult.forEach(result => {
-                    if (result.scores.includes(item.score)) {
-                        item.scoreResult = result.level
-                    }
-                })
-            })
-            this.getResult();
-            this.loading = false
-        },
-        getResult() {
-            let xData = [], yData = []
-            console.log(this.gradeLevels)
-            console.log(this.users)
-            this.gradeLevels.forEach(item => {
-                xData.push(item.name)
-                yData.push(this.users.filter(user => user.level === item.name).length)
-            })
-            console.log(xData);
-            console.log(yData);
-            let option = {
-                tooltip: {
-                    trigger: 'axis',
-                    axisPointer: {
-                        // 坐标轴指示器,坐标轴触发有效
-                        type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
-                    }
-                },
-                xAxis: {
-                    type: 'category',
-                    data: xData
-                },
-                yAxis: {
-                    type: 'value',
-                    minInterval: 1
-                },
-                series: [
-                    {
-                        data: yData,
-                        type: 'bar',
-                        itemStyle: {
-                            normal: {
-                                //这里是重点
-                                color: function (params) {
-                                    //注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
-                                    var colorList = ['#409EFF', '#4ECB73', '#36CBCB', '#F2637B', '#FBD437', '#749f83', '#ca8622'];
-                                    var index;
-                                    //给大于颜色数量的柱体添加循环颜色的判断
-                                    if (params.dataIndex >= colorList.length) {
-                                        index = params.dataIndex - colorList.length;
-                                        return colorList[index];
-                                    }
-                                    return colorList[params.dataIndex];
-                                }
-                            }
-                        },
-                        barMaxWidth: 30
-                    }
-                ]
-            };
-            var myChart = ECharts.init(this.$refs.echarts2);
-            myChart.setOption(option);
-        },
-
-        getDetails() {
-            this.$emit('changeCurrentId', { currentId: '2', reviewId: this.reviewPackageId })
-        },
-        changeCateIds(cateIds) {
-            this.cateIds = cateIds
-            this.$bus.$emit("finishEdit", this.reviewPackageId)
-        },
-        changeTitle(title) {
-            this.title = title;
-            this.$bus.$emit("finishEdit", this.reviewPackageId)
-        },
-
-        changeDate(data) {
-            let { startTime, endTime } = data
-            this.startTime = startTime
-            this.endTime = endTime
-            this.$bus.$emit("finishEdit", this.reviewPackageId)
-        },
-
-        
-
-        // 获取全局等级设置
-        async getAllSet() {
-            let res = await this.$axiosUser('get', 'api/pro/per/user/base_config')
-            let data = res.data.data;
-            let levels = data.level_scope.levels;
-            let gradeLevels = [];
-            let max = 0;//最大值
-            if (levels && levels.length > 0) {
-                levels.forEach((item, index) => {
-                    var obj;
-                    if (index == 0) {
-                        obj = { name: item.name, max: Number(item.value), min: 0 };
-                    } else {
-                        obj = { name: item.name, max: Number(item.value), min: max };//当不是第一个等级时,最小值为上一个的最大值
-                    }
-                    max = item.value;
-                    gradeLevels.push(obj);
-                })
-                this.gradeLevels = gradeLevels
-            }
-        },
-
-        // 查找分数对应的等级
-        findGrade(score, gradeLevels) {
-            for (let i = 0; i < gradeLevels.length; i++) {
-                if (score && score >= gradeLevels[i].min && score && score <= gradeLevels[i].max) {
-                    return gradeLevels[i].name; // 返回对应的等级描述
-                } else if (score && score <= gradeLevels[0].min) {
-                    return gradeLevels[0].name; // 返回对应的等级描述
-                } else if (score && score >= gradeLevels[gradeLevels.length - 1].max) {
-                    return gradeLevels[gradeLevels.length - 1].name; // 返回对应的等级描述
-                }
-            }
-            return "未评分"; // 如果分数不在任何范围内
-        },
-
-        
-
-        assignLevels(scores, levelConfigs) {
-            // 降序排序并去重(假设分数不重复,可省略去重)
-            const sortedScores = [...scores].sort((a, b) => b - a);
-            const total = sortedScores.length;
-            if (total === 0) return [];
-
-            // 归一化处理比例
-            const totalRatio = levelConfigs.reduce((sum, cfg) => sum + cfg.ratio, 0);
-            const normalized = levelConfigs.map(cfg => cfg.ratio / totalRatio);
-
-            // 计算每个等级的初始人数
-            let counts = normalized.map(ratio => Math.floor(total * ratio));
-            let remainder = total - counts.reduce((sum, c) => sum + c, 0);
-
-            // 分配剩余人数,按优先级顺序
-            let idx = 0;
-            while (remainder > 0 && idx < counts.length) {
-                counts[idx]++;
-                remainder--;
-                idx++;
-            }
-
-            // 构建结果:按人数切割数组
-            let start = 0;
-            return counts.map((count, i) => {
-                const end = start + count;
-                const levelScores = sortedScores.slice(start, end);
-                start = end;
-                return {
-                    level: levelConfigs[i].level,
-                    scores: levelScores
-                };
-            });
-        },
-
-        // 选项卡点击事件
-        handleClick(tab, event) {
-            this.tableData2 = []
-            if (this.activeName == 2) {
-                let groups = _.groupBy(this.tableData1, item => `${item.title}(_)${item.target === null || item.target === '' ? 'null' : item.target}(_)${item.unit === null || item.unit === '' ? 'null' : item.unit}`);
-                Object.keys(groups).forEach(key => {
-                    let group = {
-                        title: '',
-                        target: '',
-                        unit: '',
-                        userCount: 0,
-                        scoredCount: 0,
-                        standardCount: 0,
-                        failCount: 0,
-                        standardRate: '--',
-                        totalScore: 0,
-                        totalResult: 0,
-                        avgScore: 0,
-                        avgResult: 0,
-                        standardResultRate: '--'
-                    };
-                    groups[key].forEach(indicator => {
-                        group.title = indicator.title; // 指标名称
-                        group.target = indicator.target; // 目标
-                        group.unit = indicator.unit; // 单位
-                        let standardCount = indicator.difference !== '--' && indicator.difference >= 0 ? 1 : 0; // 
-                        group.userCount += 1;
-                        group.scoredCount += indicator.score !== null ? 1 : 0;
-                        group.standardCount += standardCount;
-                        group.failCount += standardCount === 1 ? 0 : 1;
-                        if (indicator.score !== null) group.totalScore += indicator.score;
-                        if (indicator.result !== null) group.totalResult += indicator.result;
-                    });
-                    group.standardCount = group.standardCount * 100;
-                    if (group.userCount > 0) {
-                        let rate = Math.floor(group.standardCount / group.userCount * 100 * 0.01);
-                        let avgScore = Math.floor(group.totalScore / group.userCount * 100 * 0.01);
-                        let avgResult = Math.floor(group.totalResult / group.userCount * 100 * 0.01);
-                        group.standardRate = rate > 0 ? `${rate}%` : '--';
-                        group.avgScore = avgScore !== 0 ? avgScore : '--';
-                        group.avgResult = avgResult !== 0 ? avgResult : '--';
-
-                        if (group.target !== null && group.avgResult !== '--') {
-                            let standardResultRate = Math.floor((group.avgResult - group.target) / group.target * 100 * 0.01 * 100) ;
-                            group.standardResultRate = standardResultRate !== 0 ? `${standardResultRate}%` : '--';
-                        }
-                    }
-                    this.tableData2.push(group);
-                    console.log(this.tableData2);
-                })
-            }
-        },
-        closeTargetList() {
-            this.targetDialogVisible = false
-        },
-
-        openTargetList(okrs) {
-            if (okrs && okrs.length > 0) {
-                this.okrs = okrs
-                this.targetDialogVisible = true
-            } else {
-                return this.$message.error("暂无关联okr")
-            }
-        }
-    }
-}
-
-</script>
-
-<style>
-.oneLine {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-</style>
-
-
-<style scoped="scoped" lang="scss">
-.record-right {
-    width: 100%;
-    border-radius: 5px;
-    background: #fff;
-    padding: 10px 20px;
-    box-sizing: border-box;
-    overflow: hidden;
-    overflow-y: auto;
-    .echarts {
-        height: 350px;
-        width: 100%;
-    }
-    /* 设置滚动条的宽度和背景色 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
-        width: 6px;
-        height: 6px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-    }
-
-    .title-container {
-        display: flex;
-        align-items: center;
-
-        .searchBox {
-            width: 300px;
-            .search-title {
-                border-bottom: 1px solid #f1f1f1;
-                font-size: 16px;
-                font-weight: 700;
-                padding: 0 10px;
-                padding-bottom: 10px;
-            }
-        }
-        
-
-        .title {
-            font-weight: 700;
-            font-size: 16px;
-        }
-    }
-
-    .line {
-        width: 100%;
-        height: 1px;
-        background: #f1f1f1;
-        margin: 10px 0;
-    }
-
-    .score-list {
-        display: flex;
-        width: 100%;
-        margin-top: 20px;
-        .score-item {
-            flex: 0 0 calc((100% - 80px) / 5);
-            height: 100px;
-            padding: 10px;
-            margin: 0 20px 20px 0;
-            box-sizing: border-box;
-            border-radius: 6px;
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            justify-content: space-around;
-            font-size: 16px;
-            color: #999;
-            box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
-
-            &-title {
-                font-weight: 600;
-                color: #409EFF;
-            }
-
-            &-num {
-                color: #000;
-                font-weight: 600;
-            }
-
-            &:nth-child(5n) {
-                /* 去除第5n个的margin-right */
-                margin-right: 0;
-            }
-        }
-    }
-       
-
-    .user-info {
-        width: 100%;
-        height: 200px;
-        overflow: hidden;
-        overflow-x: auto;
-        /* 设置滚动条的宽度和背景色 */
-        &::-webkit-scrollbar {
-            width: 10px;
-            height: 10px;
-            background-color: #f9f9f9;
-        }
-    
-        /* 设置滚动条滑块的样式 */
-        &::-webkit-scrollbar-thumb {
-            border-radius: 6px;
-            background-color: #c1c1c1;
-        }
-    
-        /* 设置滚动条滑块hover样式 */
-        &::-webkit-scrollbar-thumb:hover {
-            background-color: #a8a8a8;
-        }
-    
-        /* 设置滚动条轨道的样式 */
-        &::-webkit-scrollbar-track {
-            box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-            border-radius: 6px;
-            background: #ededed;
-        }
-        .info-card {
-            width: 220px;
-            height: 100%;
-            margin-right: 20px;
-            border: 1px solid #f1f1f1;
-            padding: 5px 10px;
-            border-radius: 6px;
-            box-sizing: border-box;
-            box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
-            .info {
-                display: flex;
-                align-items: center;
-                height: 36px;
-        
-                .info-label {
-                    width: 100px;
-                }
-            }
-        }
-        
-    }
-}
-</style>

+ 34 - 251
src/newPerformance/components/IndicatorSetting.vue

@@ -3,79 +3,53 @@
         <div class="create-methods flex-box-ce">
 
             <div class="flex-box-ce">
-                <div class="method-item"  v-for="(item, index) in methods"
+                <div class="method-item" v-for="(item, index) in methods"
                     :class="[currentIndex === index ? 'active' : '', 'method-item' + index]" :key="item.id"
                     @click="changeMethod(item.id, index)">
                     {{ item.title }}
                 </div>
             </div>
-            
+
             <el-tooltip v-if="method == 1" effect="dark" content="教程指引" placement="top">
                 <div class="icon flex-center-center" @click="initStepData()">
                     <i v-if="method == 1" class="el-icon-document" id="startTour"></i>
                 </div>
             </el-tooltip>
+
+
         </div>
 
 
         <div class="setting-content flex-1" v-if="method == 1">
-            <UploadPublish2 ref="UploadPublish2" />
+            <QuickCreate ref="QuickCreateRef" />
         </div>
 
         <div class="setting-content flex-1" v-if="method == 2">
             <UploadPublish />
         </div>
 
-        <el-dialog :visible.sync="dialogVisible" title="已创建的指标库" center width="600px">
-            <div class="dialog-content">
-                <template v-if="templateList.length > 0">
-                    <div class="flex-box-ce template-item" v-for="(item, index) in templateList" :key="index">
-                        <div class="flex-box flex-1" @click="chooseTemplate(item)">
-                            <div style="width: 20px;"><i class="el-icon-tickets blue"></i></div>
-                            <span class="message-content">{{ item.title || '默认标题' }}</span>
-                        </div>
-
-                        <div>
-                            <el-popconfirm confirm-button-text='确定' cancel-button-text='不用了' icon="el-icon-info"
-                                icon-color="red" title="确定删除这个考核模板吗?" @confirm="confirmDelete(item.templateId)"
-                                @cancel="cancelDelete()">
-                                <el-link slot="reference" type="danger">删除</el-link>
-                            </el-popconfirm>
-                        </div>
-                    </div>
-                </template>
-                <noData v-else content="暂无内容" imgW="120px" imgH="120px"></noData>
-            </div>
-        </el-dialog>
     </div>
 </template>
 
 <script>
 
 import { mapGetters } from 'vuex';
-import TemplateDetails from './IndicatorSetting/TemplateDetails.vue';
-import PublishComp from './IndicatorSetting/PublishComp.vue';
-import TemplateMixedPublish from './IndicatorSetting/TemplateMixedPublish.vue';
 import UploadPublish from './IndicatorSetting/UploadPublish.vue';
-import UploadPublish2 from './IndicatorSetting/UploadPublish2.vue';
-import indicatorSettingStep from "@/newPerformance/utils/indicatorSettingStep"
+import QuickCreate from './IndicatorSetting/QuickCreate.vue';
 import introJs from 'intro.js'
 import 'intro.js/introjs.css'
+import indicatorSettingStep from "@/newPerformance/utils/indicatorSettingStep"
+import flowSettingStep from "@/newPerformance/utils/flowSettingStep"
 
 export default {
     components: {
-        TemplateDetails,
-        PublishComp,
-        TemplateMixedPublish,
         UploadPublish,
-        UploadPublish2
+        QuickCreate,
     },
     data() {
         return {
-            dialogVisible: false,
             currentIndex: 0,
             methods: [
-                // { id: 0, title: "方式1:手动创建指标" },
                 { id: 1, title: "方式1:快速创建" },
                 { id: 2, title: "方式2:批量导入指标" },
             ],
@@ -113,12 +87,18 @@ export default {
 
     methods: {
 
+        changeMethod(id, index) {
+            this.method = id;
+            this.currentIndex = index;
+        },
+
         startGuide() {
-            introJs().setOptions({
+            const intro = introJs()
+            intro.setOptions({
                 nextLabel: '下一个',  // 下一个按钮文字
                 prevLabel: '上一个',  // 上一个按钮文字
                 skipLabel: '跳过',    // 跳过按钮文字
-                doneLabel: '立即体验',// 完成按钮文字
+                doneLabel: '下一个',// 完成按钮文字
                 tooltipClass: 'intro-tooltip', /* 引导说明文本框的样式 */
                 highlightClass: 'intro-highlight', /* 说明高亮区域的样式 */
                 exitOnEsc: true, /* 是否使用键盘Esc退出 */
@@ -141,18 +121,15 @@ export default {
                 scrollToElement: true, // 自动滚动到目标元素
                 steps: indicatorSettingStep,
             }).onbeforechange((e) => {
-                
+            }).onafterchange((e) => {
             }).oncomplete((e) => {
-                //点击跳过按钮后执行的事件
-                localStorage.setItem("isLearned", true)
                 this.startGuide2()
             }).onexit((e) => {
-                //点击结束按钮后, 执行的事件
-                localStorage.setItem("isLearned", true)
                 this.startGuide2()
             }).start()
         },
 
+
         // 开启教程指引
         initStepData() {
             setTimeout(() => {
@@ -161,7 +138,6 @@ export default {
 
             
         },
-
         startGuide2() {
             introJs().setOptions({
                 steps: [
@@ -182,129 +158,17 @@ export default {
                 doneLabel: '知道了'
 
             }).onexit((e) => {
+                //点击结束按钮后, 执行的事件
+                localStorage.setItem("isLearned", true)
             }).oncomplete((e) => {
+                //点击结束按钮后, 执行的事件
+                localStorage.setItem("isLearned", true)
             }).onbeforechange((e) => {
             }).start()
         },
 
-        changeMethod(id, index) {
-            this.method = id;
-            this.currentIndex = index;
-        },
-        chooseTemplate(item) {
-            this.templateId = item.templateId
-            this.step = 1;
-            this.dialogVisible = false;
-        },
-        getTemplateList() {
-            this.$axiosUser("get", `/performance/template/list/self/${this.user_info.site_id}`).then(res => {
-                this.templateList = res.data.data.list;
-            })
-        },
-
-        addTemplate() {
-            this.$axiosUser('post', `/performance/template/create/${this.user_info.site_id}`).then(res => {
-                let { data: { data, code } } = res
-                if (code == 1) {
-                    this.$axiosUser("get", `/performance/template/list/self/${this.user_info.site_id}`).then(res => {
-                        this.templateList = res.data.data.list
-                        this.templateId = this.templateList[this.templateList.length - 1].templateId;
-                        this.$message.success("创建成功")
-                        this.step = 1;
-                    })
-                }
-            });
-        },
-
-
-        // 确认删除模板
-        confirmDelete(templateId) {
-            this.$axiosUser('post', `/performance/template/remove/${this.user_info.site_id}/${templateId}`).then(res => {
-                this.$axiosUser("get", `/performance/template/list/self/${this.user_info.site_id}`).then(res => {
-                    this.templateList = res.data.data.list
-                })
-            })
-        },
-
-        cancelDelete() {
-            console.log("取消删除");
-        },
-
-        prevStep() {
-            if (this.step <= 0) return;
-            this.step--;
-        },
-        nextStep() {
-            if (this.step >= 2) return;
-            this.step++;
-        },
-
-        // 发布考核弹框的回调
-        onPubishConfirm(params, selectOkrs) {
-            let templateId = this.templateId;
-            let { title, startDate, endDate, cycleType, employeeIds, okrs, cateId } = params
-            let employees = employeeIds.map(employee => ({
-                employeeId: employee,
-                ids: [],
-                interviewFlow: {
-                    nodes: [
-                        {
-                            id: "IT_1894283564934688769",
-                            type: "interview",
-                            allows: [],
-                            enable: false,
-                            weight: 0,
-                            children: [],
-                            assigneeIds: [],
-                            leaderLevel: 1,
-                            assigneeType: "self",
-                            multipleType: "or"
-                        }
-                    ]
-                }
-            }))
-
-            let requireParams = {
-                title,
-                cycleType,
-                startDate,
-                endDate,
-                okrs,
-                templates: [
-                    {
-                        templateId,
-                        employees
-                    }
-                ],
-                cateId
-            }
-            
-            let url = `/performance/review/publish/templates/${this.user_info.site_id}`;
-            this.loading = true
-            this.$http.post(url, requireParams).then(res => {
-                console.log(res)
-                let { data, code, message } = res
-                this.loading = false
-                if (code == 1) {
-                    this.$message.success("发布成功");
-                    this.$emit("changeCurrentId", {currentId: '1'})
-                    setTimeout(() => {
-                        this.$router.push("newPerformance")
-                    }, 1000);
-                } else {
-                    this.$message.error(message || '发布失败');
-                }
-            })
-        },
-
-        activeStep(index, flag = true) {
-            this.activeIndex = index;
-            if (flag) this.step = index - 1;
-        },
-
-        changeStep(step) {
-            this.activeIndex = step + 1;
-        }
+        
+        
     }
 }
 
@@ -315,6 +179,9 @@ export default {
 
 <style lang="scss">
 
+
+
+
 .introjs-helperLayer {
     box-shadow: rgba(33, 33, 33, 0.8) 0px 0px 1px 0px, rgba(33, 33, 33, 0.5) 0px 0px 0px 5000px !important;
     border: 3px dashed #409eff;
@@ -453,100 +320,15 @@ export default {
 
 <style scoped lang="scss">
 
-
-.carousel {
-    position: relative;
-    width: 100%;
-    max-width: 600px;
-    margin: 0 auto;
-    overflow: hidden;
-}
-
-.carousel-inner {
-    display: flex;
-    transition: transform 0.5s ease;
-}
-
-.carousel-item {
-    min-width: 100%;
-    background-size: cover;
-    background-position: center;
-}
-
-.carousel-item img {
-    width: 100%;
-    height: auto;
-}
-
-.prev,
-.next {
-    position: absolute;
-    top: 50%;
-    transform: translateY(-50%);
-    background-color: rgba(0, 0, 0, 0.5);
-    color: white;
-    border: none;
-    padding: 10px;
-    cursor: pointer;
-    z-index: 10;
+::v-deep .el-drawer__header {
+    margin-bottom: 20px;
 }
 
-.prev {
-    left: 10px;
+::v-deep .el-drawer__header span {
+    font-size: 18px !important;
+    font-weight: bold !important;
 }
 
-.next {
-    right: 10px;
-}
-
-
-.dialog-content {
-    width: 100%;
-    height: 500px;
-    overflow-y: auto;
-    padding-bottom: 20px;
-    box-sizing: border-box;
-
-    .template-item {
-        padding: 5px;
-        box-sizing: border-box;
-        transition: all 0.3s;
-
-        &:hover {
-            cursor: pointer;
-            background: #f7f7f7;
-        }
-    }
-
-    /* 设置滚动条的宽度和背景色 */
-    &::-webkit-scrollbar {
-        width: 6px;
-        height: 6px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    &::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    &::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    &::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-    }
-
-}
-
-
-
 .all {
     width: 100%;
     height: 100%;
@@ -555,6 +337,7 @@ export default {
     display: flex;
     flex-direction: column;
 
+    
     .create-methods {
         background: #fff;
         padding: 10px;

+ 0 - 347
src/newPerformance/components/IndicatorSetting/PerCcSelector.vue

@@ -1,347 +0,0 @@
-<template>
-  <el-dialog
-    :visible.sync="innerVisible"
-    @close="handleClose"
-    @open="initData"
-    @closed="dataReset"
-    append-to-body
-    :close-on-click-modal="false"
-    center
-    title="结果录入节点配置"
-    width="600px"
-  >
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch
-          v-model="currentNode.enable"
-        />
-      </el-form-item>
-
-      <el-form-item label="抄送人">
-        <el-radio-group
-          v-model="currentNode.assigneeType"
-          :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange"
-        >
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <el-form-item label="">
-        <template v-if="currentNode.assigneeType === 'leader'">
-          <el-select
-            v-model="currentNode.leaderLevel"
-            placeholder="请选择管理员"
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="leader"
-            @change="onOrgManagerChange"
-          >
-            <el-option
-              v-for="item in levelOptions"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-        <template v-if="currentNode.assigneeType === 'user'">
-          <el-select
-            v-model="userSelected"
-            placeholder="请选择指定人员"
-            multiple
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="user"
-            @change="onUserChange"
-          >
-            <el-option
-              v-for="item in employees"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-        <template v-if="currentNode.assigneeType === 'post'">
-          <el-select
-            v-model="postSelected"
-            placeholder="请选择岗位"
-            multiple
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="post"
-            @change="onPostChange"
-          >
-            <el-option
-              v-for="item in postList"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-        <template v-if="currentNode.assigneeType === 'deptLeader'">
-          <el-select
-            v-model="deptSelected"
-            placeholder="请选择部门"
-            multiple
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="deptLeader"
-            @change="onDeptChange"
-          >
-            <el-option
-              v-for="item in deptList"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-      </el-form-item>
-    </el-form>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-export default {
-  name: "PerCcSelector",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-    indicator:{
-      type: Object,
-      default: () =>{
-        return null
-      }
-    }
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading || !this.indicator) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.indicator.flow.nodes.find(node => node.type === 'cc');
-
-          switch (this.currentNode.assigneeType){
-            case 'user':
-              this.userSelected = this.currentNode.assigneeIds;
-              break;
-            case 'post':
-              this.postSelected = this.currentNode.assigneeIds;
-              break;
-            case 'deptLeader':
-              this.deptSelected = this.currentNode.assigneeIds;
-              break;
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 0 - 362
src/newPerformance/components/IndicatorSetting/PerCcSelectorOnly.vue

@@ -1,362 +0,0 @@
-<template>
-  <el-dialog
-    :visible.sync="innerVisible"
-    @close="handleClose"
-    @open="initData"
-    @closed="dataReset"
-    append-to-body
-    :close-on-click-modal="false"
-    center
-    title="结果录入节点配置"
-    width="600px"
-  >
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch
-          v-model="currentNode.enable"
-        />
-      </el-form-item>
-
-      <el-form-item label="抄送人">
-        <el-radio-group
-          v-model="currentNode.assigneeType"
-          :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange"
-        >
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <el-form-item label="">
-        <template v-if="currentNode.assigneeType === 'leader'">
-          <el-select
-            v-model="currentNode.leaderLevel"
-            placeholder="请选择管理员"
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="leader"
-            @change="onOrgManagerChange"
-          >
-            <el-option
-              v-for="item in levelOptions"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-        <template v-if="currentNode.assigneeType === 'user'">
-          <el-select
-            v-model="userSelected"
-            placeholder="请选择指定人员"
-            multiple
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="user"
-            @change="onUserChange"
-          >
-            <el-option
-              v-for="item in employees"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-        <template v-if="currentNode.assigneeType === 'post'">
-          <el-select
-            v-model="postSelected"
-            placeholder="请选择岗位"
-            multiple
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="post"
-            @change="onPostChange"
-          >
-            <el-option
-              v-for="item in postList"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-        <template v-if="currentNode.assigneeType === 'deptLeader'">
-          <el-select
-            v-model="deptSelected"
-            placeholder="请选择部门"
-            multiple
-            :disabled="!currentNode.enable"
-            filterable
-            style="width: 300px;"
-            key="deptLeader"
-            @change="onDeptChange"
-          >
-            <el-option
-              v-for="item in deptList"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-              style="width: 300px;"
-            />
-          </el-select>
-        </template>
-      </el-form-item>
-    </el-form>
-    <template v-if="currentNode" #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button
-            type="primary"
-            @click="onConfirm"
-          >
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-export default {
-  name: "PerCcSelectorOnly",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    defaultNode(){
-      const node = JSON.parse("{\"id\":\"CC_1907236768800382984\",\"type\":\"cc\",\"enable\":false,\"assigneeType\":\"user\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[],\"weight\":0,\"children\":[]}");
-      node.id = "CC_" + this.generalId();
-      return node;
-    },
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.defaultNode();
-
-          switch (this.currentNode.assigneeType){
-            case 'user':
-              this.userSelected = this.currentNode.assigneeIds;
-              break;
-            case 'post':
-              this.postSelected = this.currentNode.assigneeIds;
-              break;
-            case 'deptLeader':
-              this.deptSelected = this.currentNode.assigneeIds;
-              break;
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    onConfirm(){
-      this.$emit('confirm',this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 2 - 1
src/newPerformance/components/IndicatorSetting/PerEmployeeSelector.vue

@@ -113,7 +113,8 @@ export default {
   },
   
   methods: {
-    handleClose(){
+    handleClose() {
+      this.searchValue = '';
       this.$emit('update:showVisible',false)
     },
     initData() {

+ 0 - 316
src/newPerformance/components/IndicatorSetting/PerResultInputSelector.vue

@@ -1,316 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="结果录入节点配置" width="600px">
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-
-      <el-form-item label="录入人">
-        <el-radio-group v-model="currentNode.assigneeType" :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange">
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <div class="flex-center-center" style="margin-left: 100px;">
-        <el-form-item label="">
-          <template v-if="currentNode.assigneeType === 'leader'">
-            <el-select v-model="currentNode.leaderLevel" placeholder="请选择管理员" :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="leader" @change="onOrgManagerChange">
-              <el-option v-for="item in levelOptions" :key="item.value" :label="item.label" :value="item.value"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-          </template>
-          <template v-if="currentNode.assigneeType === 'user'">
-            <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="user" @change="onUserChange">
-              <el-option v-for="item in employees" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-          </template>
-          <template v-if="currentNode.assigneeType === 'post'">
-            <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="post" @change="onPostChange">
-              <el-option v-for="item in postList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-          </template>
-          <template v-if="currentNode.assigneeType === 'deptLeader'">
-            <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="deptLeader" @change="onDeptChange">
-              <el-option v-for="item in deptList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-          </template>
-        </el-form-item>
-      </div>
-
-      <el-form-item label="多人时">
-        <el-radio-group v-model="currentNode.multipleType" :disabled="!currentNode.enable">
-          <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-          <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-          <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-        </el-radio-group>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-        </div>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-        </div>
-      </el-form-item>
-
-      <el-form-item label="允许">
-        <el-checkbox-group
-          v-model="currentNode.allows"
-          :disabled="!currentNode.enable"
-        >
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-
-export default {
-  name: "PerResultInputSelector",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-    indicator:{
-      type: Object,
-      default: () =>{
-        return null
-      }
-    }
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading || !this.indicator) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.indicator.flow.nodes.find(node => node.type === 'resultInput');
-
-          switch (this.currentNode.assigneeType){
-            case 'user':
-              this.userSelected = this.currentNode.assigneeIds;
-              break;
-            case 'post':
-              this.postSelected = this.currentNode.assigneeIds;
-              break;
-            case 'deptLeader':
-              this.deptSelected = this.currentNode.assigneeIds;
-              break;
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 0 - 324
src/newPerformance/components/IndicatorSetting/PerResultInputSelectorOnly.vue

@@ -1,324 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="结果录入节点配置" width="600px" class="result-input-dialog">
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-
-      <el-form-item label="录入人">
-        <el-radio-group v-model="currentNode.assigneeType" :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange">
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <div class="flex-center-center" style="margin-left: 100px;">
-        <el-form-item label="">
-          <template v-if="currentNode.assigneeType === 'leader'">
-            <el-select v-model="currentNode.leaderLevel" placeholder="请选择管理员" :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="leader" @change="onOrgManagerChange">
-              <el-option v-for="item in levelOptions" :key="item.value" :label="item.label" :value="item.value"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-          </template>
-          <template v-if="currentNode.assigneeType === 'user'">
-            <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="user" @change="onUserChange">
-              <el-option v-for="item in employees" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-          </template>
-          <template v-if="currentNode.assigneeType === 'post'">
-            <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="post" @change="onPostChange">
-              <el-option v-for="item in postList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-          </template>
-          <template v-if="currentNode.assigneeType === 'deptLeader'">
-            <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="deptLeader" @change="onDeptChange">
-              <el-option v-for="item in deptList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-          </template>
-        </el-form-item>
-      </div>
-      <el-form-item label="多人时">
-        <el-radio-group v-model="currentNode.multipleType" :disabled="!currentNode.enable">
-          <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-          <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-          <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-        </el-radio-group>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-        </div>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-        </div>
-      </el-form-item>
-
-      <el-form-item label="允许">
-        <el-checkbox-group v-model="currentNode.allows" :disabled="!currentNode.enable">
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-
-export default {
-  name: "PerResultInputSelectorOnly",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    idGeneral(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    defaultNode(){
-      const node = JSON.parse("{\"id\":\"RI_1907236768800382977\",\"type\":\"resultInput\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[]}");
-      node.id = "RI_" + this.idGeneral();
-      return node;
-    },
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.defaultNode();
-
-          switch (this.currentNode.assigneeType){
-            case 'user':
-              this.userSelected = this.currentNode.assigneeIds;
-              break;
-            case 'post':
-              this.postSelected = this.currentNode.assigneeIds;
-              break;
-            case 'deptLeader':
-              this.deptSelected = this.currentNode.assigneeIds;
-              break;
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.assigneeIds = [];
-      this.currentNode.leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.assigneeIds = [...v];
-      this.currentNode.leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    onConfirm(){
-      this.$emit('confirm', this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 0 - 364
src/newPerformance/components/IndicatorSetting/PerReviewsSelector.vue

@@ -1,364 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="审批节点配置" width="600px">
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-      <el-form-item label="">
-        <div class="handler-list">
-          <el-tag v-for="(item,index) in currentNode.children" :key="`hl_${index}`"
-            :type="childIndex === index ? '' : 'info'" closable @close="removeChild(index)" @click="childSelect(index)">
-            {{assigneeMap[item.assigneeType] || '未知'}}
-          </el-tag>
-          <el-button v-show="currentNode.enable" icon="el-icon-plus" size="mini" style="margin-bottom: 10px;"
-            @click="addChild" />
-        </div>
-      </el-form-item>
-      <el-form-item label="审批人">
-        <el-radio-group v-model="currentNode.children[childIndex].assigneeType" :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange">
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <div class="flex-center-center" style="margin-left: 100px;">
-        <el-form-item label="">
-          <template v-if="currentNode.children[childIndex].assigneeType === 'leader'">
-            <el-select v-model="currentNode.children[childIndex].leaderLevel" placeholder="请选择管理员"
-              :disabled="!currentNode.enable" filterable style="width: 300px;" key="leader"
-              @change="onOrgManagerChange">
-              <el-option v-for="item in levelOptions" :key="`leader_${item.value}`" :label="item.label"
-                :value="item.value" style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'user'">
-            <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="user" @change="onUserChange">
-              <el-option v-for="item in employees" :key="`user_${item.id}`" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'post'">
-            <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="post" @change="onPostChange">
-              <el-option v-for="item in postList" :key="`post_${item.id}`" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'deptLeader'">
-            <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="deptLeader" @change="onDeptChange">
-              <el-option v-for="item in deptList" :key="`deptLeader_${item.id}`" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-          </template>
-        </el-form-item>
-      </div>
-
-      <el-form-item label="多人时">
-        <el-radio-group v-model="currentNode.children[childIndex].multipleType" :disabled="!currentNode.enable">
-          <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-          <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-          <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-        </el-radio-group>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-        </div>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-        </div>
-      </el-form-item>
-      <el-form-item label="允许">
-        <el-checkbox-group
-          v-model="currentNode.children[childIndex].allows"
-          :disabled="!currentNode.enable"
-        >
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-
-export default {
-  name: "PerReviewsSelector",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-    indicator:{
-      type: Object,
-      default: () =>{
-        return null
-      }
-    }
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      childIndex: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.childIndex = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading || !this.indicator) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.indicator.flow.nodes.find(node => node.type === 'reviews');
-
-          this.childIndex = this.currentNode.children && this.currentNode.children.length > 0 ? 0 : null;
-
-          if (this.childIndex !== null && !!this.currentNode.children[this.childIndex]){
-            switch (this.currentNode.children[this.childIndex].assigneeType){
-              case 'user':
-                this.userSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'post':
-                this.postSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'deptLeader':
-                this.deptSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-            }
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    addChild(){
-      let id = "R_" + this.generalId();
-      this.currentNode.children.push({
-        id:id,
-        type:'review',
-        enable:true,
-        assigneeType:'leader',
-        leaderLevel:1,
-        assigneeIds:[],
-        multipleType:'or',
-        allows:['transfer'],
-        weight:0,
-        children:[],
-      });
-    },
-    removeChild(index){
-      if (this.currentNode.children.length <= 1 || !this.currentNode.children[index]) return;
-      let selectChildId = this.currentNode.children[index].id;
-      this.childIndex = 0;
-      this.currentNode.children = this.currentNode.children.filter((_,i) => i !== index);
-      if (selectChildId){
-        this.currentNode.children.forEach((child,i) => {
-          if (child.id === selectChildId) this.childIndex = i;
-        })
-      }
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    childSelect(index){
-      if (!this.currentNode.children[index]) return;
-      this.childIndex = index;
-      this.userSelected = this.currentNode.children[this.childIndex].assigneeType === 'user' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.postSelected = this.currentNode.children[this.childIndex].assigneeType === 'post' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.deptSelected = this.currentNode.children[this.childIndex].assigneeType === 'deptLeader' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-    }
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 0 - 380
src/newPerformance/components/IndicatorSetting/PerReviewsSelectorOnly.vue

@@ -1,380 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="审批节点配置" width="600px">
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-      <el-form-item label="">
-        <div class="handler-list">
-          <el-tag v-for="(item,index) in currentNode.children" :key="`hl_${index}`"
-            :type="childIndex === index ? '' : 'info'" closable @close="removeChild(index)" @click="childSelect(index)">
-            {{assigneeMap[item.assigneeType] || '未知'}}
-          </el-tag>
-          <el-button v-show="currentNode.enable" icon="el-icon-plus" size="mini" style="margin-bottom: 10px;"
-            @click="addChild" />
-        </div>
-      </el-form-item>
-      <el-form-item label="审批人">
-        <el-radio-group v-model="currentNode.children[childIndex].assigneeType" :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange">
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <div class="flex-center-center" style="margin-left: 100px;">
-
-        <el-form-item label="">
-          <template v-if="currentNode.children[childIndex].assigneeType === 'leader'">
-            <el-select v-model="currentNode.children[childIndex].leaderLevel" placeholder="请选择管理员"
-              :disabled="!currentNode.enable" filterable style="width: 300px;" key="leader"
-              @change="onOrgManagerChange">
-              <el-option v-for="item in levelOptions" :key="`leader_${item.value}`" :label="item.label"
-                :value="item.value" style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'user'">
-            <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="user" @change="onUserChange">
-              <el-option v-for="item in employees" :key="`user_${item.id}`" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'post'">
-            <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="post" @change="onPostChange">
-              <el-option v-for="item in postList" :key="`post_${item.id}`" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'deptLeader'">
-            <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="deptLeader" @change="onDeptChange">
-              <el-option v-for="item in deptList" :key="`deptLeader_${item.id}`" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-          </template>
-        </el-form-item>
-
-      </div>
-      <el-form-item label="多人时">
-        <el-radio-group v-model="currentNode.children[childIndex].multipleType" :disabled="!currentNode.enable">
-          <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-          <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-          <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-        </el-radio-group>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-        </div>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-        </div>
-      </el-form-item>
-      <el-form-item label="允许">
-        <el-checkbox-group
-          v-model="currentNode.children[childIndex].allows"
-          :disabled="!currentNode.enable"
-        >
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-
-export default {
-  name: "PerReviewsSelectorOnly",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      childIndex: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    defaultNode(){
-      const node = JSON.parse("{\"id\":\"RS_1907236768800382982\",\"type\":\"reviews\",\"enable\":true,\"assigneeType\":\"leader\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[{\"id\":\"R_1907236768800382983\",\"type\":\"review\",\"enable\":true,\"assigneeType\":\"leader\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[]}]}");
-      node.id = "RS_" + this.generalId();
-      node.children.forEach((_,i) => {
-        node.children[i].id = "R_" + this.generalId();
-      });
-      return node;
-    },
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.childIndex = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.defaultNode();
-
-          this.childIndex = this.currentNode.children && this.currentNode.children.length > 0 ? 0 : null;
-
-          if (this.childIndex !== null && !!this.currentNode.children[this.childIndex]){
-            switch (this.currentNode.children[this.childIndex].assigneeType){
-              case 'user':
-                this.userSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'post':
-                this.postSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'deptLeader':
-                this.deptSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-            }
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    addChild(){
-      let id = "R_" + this.generalId();
-      this.currentNode.children.push({
-        id:id,
-        type:'review',
-        enable:true,
-        assigneeType:'leader',
-        leaderLevel:1,
-        assigneeIds:[],
-        multipleType:'or',
-        allows:['transfer'],
-        weight:0,
-        children:[],
-      });
-    },
-    removeChild(index){
-      if (this.currentNode.children.length <= 1 || !this.currentNode.children[index]) return;
-      let selectChildId = this.currentNode.children[index].id;
-      this.childIndex = 0;
-      this.currentNode.children = this.currentNode.children.filter((_,i) => i !== index);
-      if (selectChildId){
-        this.currentNode.children.forEach((child,i) => {
-          if (child.id === selectChildId) this.childIndex = i;
-        })
-      }
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    childSelect(index){
-      if (!this.currentNode.children[index]) return;
-      this.childIndex = index;
-      this.userSelected = this.currentNode.children[this.childIndex].assigneeType === 'user' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.postSelected = this.currentNode.children[this.childIndex].assigneeType === 'post' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.deptSelected = this.currentNode.children[this.childIndex].assigneeType === 'deptLeader' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-    },
-    onConfirm(){
-      this.$emit('confirm',this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 0 - 97
src/newPerformance/components/IndicatorSetting/PerScoreEachOther.vue

@@ -1,97 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="互评节点配置" width="600px">
-    <el-alert class="bounce animated" type="warning" :title="alertTilte" :closable="false" show-icon
-      style="width: 100%; margin-bottom: 10px;"></el-alert>
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-      <el-form-item label="允许">
-        <el-checkbox-group v-model="currentNode.allows" :disabled="!currentNode.enable">
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-
-export default {
-  name: "PerScoreSelfOnly",
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-
-    indicator: {
-      type: Object,
-      default: () => {
-        return null
-      }
-    }
-    
-  },
-  data(){
-    return {
-      alertTilte: "互评的评分仅仅作为评分的参考,不会影响指标最终的评分",
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-    }
-  },
-  
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    dataReset() {
-      this.currentNode = null
-    },
-    idGeneral() {
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    defaultNode() {
-      const node = JSON.parse("{\"id\":\"SEO_1907236768800382977\",\"type\":\"scoreEachOther\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[]}");
-      node.id = "RI_" + this.idGeneral();
-      return node;
-    },
-    
-    initData() {
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-      this.currentNode = this.indicator.flow.nodes.find(node => node.type === 'scoreEachOther');
-      this.loading = false;
-    },
-    
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    
-    onConfirm(){
-      this.$emit('confirm',this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 87
src/newPerformance/components/IndicatorSetting/PerScoreEachOtherOnly.vue

@@ -1,87 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="互评节点配置" width="600px">
-    <el-alert class="bounce animated" type="warning" :title="alertTilte" :closable="false" show-icon
-      style="width: 100%; margin-bottom: 10px;"></el-alert>
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-      <el-form-item label="允许">
-        <el-checkbox-group v-model="currentNode.allows" :disabled="!currentNode.enable">
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-
-export default {
-  name: "PerScoreSelfOnly",
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data(){
-    return {
-      alertTilte: "互评的评分仅仅作为评分的参考,不会影响指标最终的评分",
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-    }
-  },
-  
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    dataReset() { },
-    idGeneral() {
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    defaultNode() {
-      const node = JSON.parse("{\"id\":\"SEO_1907236768800382977\",\"type\":\"scoreEachOther\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[]}");
-      node.id = "RI_" + this.idGeneral();
-      return node;
-    },
-    
-    initData() {
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-      this.currentNode = this.defaultNode();
-      this.loading = false;
-    },
-    
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    
-    onConfirm(){
-      this.$emit('confirm',this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 102
src/newPerformance/components/IndicatorSetting/PerScoreSelf.vue

@@ -1,102 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="自评节点配置" width="600px">
-    <el-alert class="bounce animated" type="warning" :title="alertTilte" :closable="false" show-icon
-      style="width: 100%; margin-bottom: 10px;"></el-alert>
-    <el-form v-if="currentNode" label-width="200">
-
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-      <el-form-item label="允许">
-        <el-checkbox-group v-model="currentNode.allows" :disabled="!currentNode.enable">
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-
-export default {
-  name: "PerScoreSelfOnly",
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-
-    indicator: {
-      type: Object,
-      default: () => {
-        return null
-      }
-    }
-
-  },
-  data(){
-    return {
-      alertTilte: "自评的评分仅仅作为评分的参考,不会影响指标最终的评分",
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-    }
-  },
-  
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    dataReset() {
-      this.currentNode = null
-    },
-    idGeneral() {
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    defaultNode() {
-      const node = JSON.parse("{\"id\":\"SS_1907236768800382977\",\"type\":\"scoreSelf\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[]}");
-      node.id = "RI_" + this.idGeneral();
-      return node;
-    },
-    
-    initData() {
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-      this.currentNode = this.indicator.flow.nodes.find(node => node.type === 'scoreSelf');
-      this.loading = false;
-    },
-    
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    
-           
-   
-    onConfirm() {
-      console.log("this.currentNode")
-      console.log(this.currentNode)
-      this.$emit('confirm', this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 89
src/newPerformance/components/IndicatorSetting/PerScoreSelfOnly.vue

@@ -1,89 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="自评节点配置" width="600px">
-    <el-alert class="bounce animated" type="warning" :title="alertTilte" :closable="false" show-icon
-      style="width: 100%; margin-bottom: 10px;"></el-alert>
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-      <el-form-item label="允许">
-        <el-checkbox-group v-model="currentNode.allows" :disabled="!currentNode.enable">
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-
-export default {
-  name: "PerScoreSelfOnly",
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data(){
-    return {
-      alertTilte: "自评的评分仅仅作为评分的参考,不会影响指标最终的评分",
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      innerVisible: this.showVisible,
-      loading:false,
-    }
-  },
-  
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    dataReset() { },
-    idGeneral() {
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    defaultNode() {
-      const node = JSON.parse("{\"id\":\"SS_1907236768800382977\",\"type\":\"scoreSelf\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[]}");
-      node.id = "RI_" + this.idGeneral();
-      return node;
-    },
-    
-    initData() {
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-      this.currentNode = this.defaultNode();
-      this.loading = false;
-    },
-    
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    
-           
-   
-    onConfirm(){
-      this.$emit('confirm',this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 505
src/newPerformance/components/IndicatorSetting/PerScoresSelector.vue

@@ -1,505 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="评分节点配置" width="600px">
-    <div v-if="currentNode" class="dialog-box" style="position: relative;">
-      <el-popover ref="popoverRef" placement="bottom" trigger="hover">
-        <template #reference>
-          <el-link type="primary" class="reference">
-            <i class="el-icon-s-opportunity"></i>
-            评分示例
-          </el-link>
-        </template>
-
-        <div>
-          <p>1、评分节点设置多人评分时,在默认的权重100%状态下,各评价人的评价权重自动均分。</p>
-          <p>举例说明:</p>
-          <table class="base-table">
-            <thead>
-              <tr>
-                <th>评分人</th>
-                <th>负责人</th>
-                <th>评分</th>
-                <th>评分权重</th>
-                <th>公式</th>
-              </tr>
-            </thead>
-            <tbody>
-              <tr>
-                <td>管理员</td>
-                <td>一级管理员</td>
-                <td>90</td>
-                <td>100%</td>
-                <td rowspan="3">
-                  (90 + 100 + 80) / 3 = 90
-                </td>
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>张三</td>
-                <td>100</td>
-                <td>100%</td>
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>李四</td>
-                <td>80</td>
-                <td>100%</td>
-              </tr>
-
-              <tr>
-                <td>指标最终得分</td>
-                <td colspan="4">90</td>
-              </tr>
-            </tbody>
-          </table>
-
-          <p>2、系统支持不同的评价人设置不同的评价权重,最终指标得分=(各评分人分数*评价权重)之和</p>
-          <p>举例说明:</p>
-          <table class="base-table">
-            <thead>
-              <tr>
-                <th>评分人</th>
-                <th>负责人</th>
-                <th>评分</th>
-                <th>评分权重</th>
-                <th>加权得分</th>
-              </tr>
-            </thead>
-            <tbody>
-              <tr>
-                <td>管理员</td>
-                <td>一级管理员</td>
-                <td>90</td>
-                <td>50%</td>
-                <td>45</td>
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>张三</td>
-                <td>100</td>
-                <td>30%</td>
-                <td>30</td>
-
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>李四</td>
-                <td>80</td>
-                <td>20%</td>
-                <td>16</td>
-              </tr>
-
-              <tr>
-                <td colspan="4">指标最终得分</td>
-                <td>90</td>
-              </tr>
-            </tbody>
-          </table>
-          <p>公式:90×50%+100×30%+80×20%=91分</p>
-        </div>
-      </el-popover>
-      <el-form label-width="200">
-        <el-form-item label="启用">
-          <el-switch v-model="currentNode.enable" disabled />
-        </el-form-item>
-
-        <el-form-item label="">
-          <div class="handler-list">
-            <el-tag v-for="(item,index) in currentNode.children" :key="`hl_${index}`"
-              :type="childIndex === index ? '' : 'info'" closable @close="removeChild(index)"
-              @click="childSelect(index)">
-              {{assigneeMap[item.assigneeType] || '未知'}}
-            </el-tag>
-            <el-button v-show="currentNode.enable" icon="el-icon-plus" size="mini" style="margin-bottom: 10px;"
-              @click="addChild" />
-          </div>
-        </el-form-item>
-        <el-form-item label="评分人">
-          <el-radio-group v-model="currentNode.children[childIndex].assigneeType" :disabled="!currentNode.enable"
-            @change="onAssigneeTypeChange">
-            <el-radio-button label="leader">组织管理员</el-radio-button>
-            <el-radio-button label="user">指定人员</el-radio-button>
-            <el-radio-button label="self">被考核人</el-radio-button>
-            <el-radio-button label="post">岗位</el-radio-button>
-            <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-          </el-radio-group>
-        </el-form-item>
-
-        <div class="flex-center-center" style="margin-left: 100px;">
-          <el-form-item label="">
-            <template v-if="currentNode.children[childIndex].assigneeType === 'leader'">
-              <el-select v-model="currentNode.children[childIndex].leaderLevel" placeholder="请选择管理员"
-                :disabled="!currentNode.enable" filterable style="width: 300px;" key="leader"
-                @change="onOrgManagerChange">
-                <el-option v-for="item in levelOptions" :key="`leader_${item.value}`" :label="item.label"
-                  :value="item.value" style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-
-            </template>
-            <template v-if="currentNode.children[childIndex].assigneeType === 'user'">
-              <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable"
-                filterable style="width: 300px;" key="user" @change="onUserChange">
-                <el-option v-for="item in employees" :key="`user_${item.id}`" :label="item.name" :value="item.id"
-                  style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-            </template>
-            <template v-if="currentNode.children[childIndex].assigneeType === 'post'">
-              <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-                style="width: 300px;" key="post" @change="onPostChange">
-                <el-option v-for="item in postList" :key="`post_${item.id}`" :label="item.name" :value="item.id"
-                  style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-            </template>
-            <template v-if="currentNode.children[childIndex].assigneeType === 'deptLeader'">
-              <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-                style="width: 300px;" key="deptLeader" @change="onDeptChange">
-                <el-option v-for="item in deptList" :key="`deptLeader_${item.id}`" :label="item.name" :value="item.id"
-                  style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-            </template>
-          </el-form-item>
-        </div>
-        <el-form-item label="多人时">
-          <el-radio-group v-model="currentNode.children[childIndex].multipleType" :disabled="!currentNode.enable">
-            <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-            <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-            <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-          </el-radio-group>
-          <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-            ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-          </div>
-          <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-            ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-          </div>
-        </el-form-item>
-
-        <el-form-item label="权重">
-          <el-input v-model="currentNode.children[childIndex].weight" :disabled="!currentNode.enable"
-            style="width: 200px;">
-            <template slot="append">%</template>
-          </el-input>
-        </el-form-item>
-
-        <el-form-item label="允许">
-          <el-checkbox-group v-model="currentNode.children[childIndex].allows" :disabled="!currentNode.enable">
-            <el-checkbox-button label="transfer">转交</el-checkbox-button>
-          </el-checkbox-group>
-        </el-form-item>
-      </el-form>
-
-    </div>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-
-export default {
-  name: "PerScoresSelector",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-    indicator:{
-      type: Object,
-      default: () =>{
-        return null
-      }
-    }
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      childIndex: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.childIndex = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading || !this.indicator) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.indicator.flow.nodes.find(node => node.type === 'scores');
-
-          this.childIndex = this.currentNode.children && this.currentNode.children.length > 0 ? 0 : null;
-
-          if (this.childIndex !== null && !!this.currentNode.children[this.childIndex]){
-            switch (this.currentNode.children[this.childIndex].assigneeType){
-              case 'user':
-                this.userSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'post':
-                this.postSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'deptLeader':
-                this.deptSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-            }
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    addChild(){
-      let id = "S_" + this.generalId();
-      this.currentNode.children.push({
-        id:id,
-        type:'score',
-        enable:true,
-        assigneeType:'leader',
-        leaderLevel:1,
-        assigneeIds:[],
-        multipleType:'or',
-        allows:['transfer'],
-        weight:100,
-        children:[],
-      });
-    },
-    removeChild(index){
-      if (this.currentNode.children.length <= 1 || !this.currentNode.children[index]) return;
-      let selectChildId = this.currentNode.children[index].id;
-      this.childIndex = 0;
-      this.currentNode.children = this.currentNode.children.filter((_,i) => i !== index);
-      if (selectChildId){
-        this.currentNode.children.forEach((child,i) => {
-          if (child.id === selectChildId) this.childIndex = i;
-        })
-      }
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    childSelect(index){
-      if (!this.currentNode.children[index]) return;
-      this.childIndex = index;
-      this.userSelected = this.currentNode.children[this.childIndex].assigneeType === 'user' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.postSelected = this.currentNode.children[this.childIndex].assigneeType === 'post' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.deptSelected = this.currentNode.children[this.childIndex].assigneeType === 'deptLeader' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-    }
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-.reference {
-  position: absolute;
-  top: -60px;
-  left: 0px;
-}
-
-.base-table {
-  width: 100%;
-  border-collapse: collapse;
-  margin: 10px auto;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
-  background-color: #fff;
-}
-
-.base-table th,
-.base-table td {
-  padding: 3px 6px;
-  text-align: center;
-  border-bottom: 1px solid #ddd;
-  box-sizing: border-box;
-}
-
-.base-table th {
-  background-color: #f2f2f2;
-  font-weight: bold;
-}
-
-.base-table td {
-  border-left: 1px solid #ccc;
-}
-
-.base-table tr:hover {
-  background-color: #f5f5f5;
-}
-
-</style>

+ 0 - 521
src/newPerformance/components/IndicatorSetting/PerScoresSelectorOnly.vue

@@ -1,521 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="评分节点配置" width="600px">
-    <div v-if="currentNode" class="dialog-box" style="position: relative;">
-      <el-popover ref="popoverRef" placement="bottom" trigger="hover">
-        <template #reference>
-          <el-link type="primary" class="reference">
-            <i class="el-icon-s-opportunity"></i>
-            评分示例
-          </el-link>
-        </template>
-
-        <div>
-          <p>1、评分节点设置多人评分时,在默认的权重100%状态下,各评价人的评价权重自动均分。</p>
-          <p>举例说明:</p>
-          <table class="base-table">
-            <thead>
-              <tr>
-                <th>评分人</th>
-                <th>负责人</th>
-                <th>评分</th>
-                <th>评分权重</th>
-                <th>公式</th>
-              </tr>
-            </thead>
-            <tbody>
-              <tr>
-                <td>管理员</td>
-                <td>一级管理员</td>
-                <td>90</td>
-                <td>100%</td>
-                <td rowspan="3">
-                  (90 + 100 + 80) / 3 = 90
-                </td>
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>张三</td>
-                <td>100</td>
-                <td>100%</td>
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>李四</td>
-                <td>80</td>
-                <td>100%</td>
-              </tr>
-
-              <tr>
-                <td>指标最终得分</td>
-                <td colspan="4">90</td>
-              </tr>
-            </tbody>
-          </table>
-
-          <p>2、系统支持不同的评价人设置不同的评价权重,最终指标得分=(各评分人分数*评价权重)之和</p>
-          <p>举例说明:</p>
-          <table class="base-table">
-            <thead>
-              <tr>
-                <th>评分人</th>
-                <th>负责人</th>
-                <th>评分</th>
-                <th>评分权重</th>
-                <th>加权得分</th>
-              </tr>
-            </thead>
-            <tbody>
-              <tr>
-                <td>管理员</td>
-                <td>一级管理员</td>
-                <td>90</td>
-                <td>50%</td>
-                <td>45</td>
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>张三</td>
-                <td>100</td>
-                <td>30%</td>
-                <td>30</td>
-
-              </tr>
-              <tr>
-                <td>指定人</td>
-                <td>李四</td>
-                <td>80</td>
-                <td>20%</td>
-                <td>16</td>
-              </tr>
-
-              <tr>
-                <td colspan="4">指标最终得分</td>
-                <td>90</td>
-              </tr>
-            </tbody>
-          </table>
-          <p>公式:90×50%+100×30%+80×20%=91分</p>
-        </div>
-      </el-popover>
-      <el-form label-width="200">
-        <el-form-item label="启用">
-          <el-switch v-model="currentNode.enable" disabled />
-        </el-form-item>
-
-        <el-form-item label="">
-          <div class="handler-list">
-            <el-tag v-for="(item,index) in currentNode.children" :key="`hl_${index}`"
-              :type="childIndex === index ? '' : 'info'" closable @close="removeChild(index)"
-              @click="childSelect(index)">
-              {{assigneeMap[item.assigneeType] || '未知'}}
-            </el-tag>
-            <el-button v-show="currentNode.enable" icon="el-icon-plus" size="mini" style="margin-bottom: 10px;"
-              @click="addChild" />
-          </div>
-        </el-form-item>
-        <el-form-item label="评分人">
-          <el-radio-group v-model="currentNode.children[childIndex].assigneeType" :disabled="!currentNode.enable"
-            @change="onAssigneeTypeChange">
-            <el-radio-button label="leader">组织管理员</el-radio-button>
-            <el-radio-button label="user">指定人员</el-radio-button>
-            <el-radio-button label="self">被考核人</el-radio-button>
-            <el-radio-button label="post">岗位</el-radio-button>
-            <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-          </el-radio-group>
-        </el-form-item>
-
-        <div class="flex-center-center" style="margin-left: 100px;">
-
-          <el-form-item label="">
-            <template v-if="currentNode.children[childIndex].assigneeType === 'leader'">
-              <el-select v-model="currentNode.children[childIndex].leaderLevel" placeholder="请选择管理员"
-                :disabled="!currentNode.enable" filterable style="width: 300px;" key="leader"
-                @change="onOrgManagerChange">
-                <el-option v-for="item in levelOptions" :key="`leader_${item.value}`" :label="item.label"
-                  :value="item.value" style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-            </template>
-            <template v-if="currentNode.children[childIndex].assigneeType === 'user'">
-              <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable"
-                filterable style="width: 300px;" key="user" @change="onUserChange">
-                <el-option v-for="item in employees" :key="`user_${item.id}`" :label="item.name" :value="item.id"
-                  style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-            </template>
-            <template v-if="currentNode.children[childIndex].assigneeType === 'post'">
-              <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-                style="width: 300px;" key="post" @change="onPostChange">
-                <el-option v-for="item in postList" :key="`post_${item.id}`" :label="item.name" :value="item.id"
-                  style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-            </template>
-            <template v-if="currentNode.children[childIndex].assigneeType === 'deptLeader'">
-              <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-                style="width: 300px;" key="deptLeader" @change="onDeptChange">
-                <el-option v-for="item in deptList" :key="`deptLeader_${item.id}`" :label="item.name" :value="item.id"
-                  style="width: 300px;" />
-              </el-select>
-              <br>
-              <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-            </template>
-          </el-form-item>
-        </div>
-
-        <el-form-item label="多人时">
-          <el-radio-group v-model="currentNode.children[childIndex].multipleType" :disabled="!currentNode.enable">
-            <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-            <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-            <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-          </el-radio-group>
-          <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-            ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-          </div>
-          <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-            ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-          </div>
-        </el-form-item>
-
-        <el-form-item label="权重">
-          <el-input v-model="currentNode.children[childIndex].weight" :disabled="!currentNode.enable"
-            style="width: 200px;">
-            <template slot="append">%</template>
-          </el-input>
-        </el-form-item>
-
-        <el-form-item label="允许">
-          <el-checkbox-group v-model="currentNode.children[childIndex].allows" :disabled="!currentNode.enable">
-            <el-checkbox-button label="transfer">转交</el-checkbox-button>
-          </el-checkbox-group>
-        </el-form-item>
-      </el-form>
-    </div>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-
-export default {
-  name: "PerScoresSelectorOnly",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      childIndex: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    defaultNode(){
-      const node = JSON.parse("{\"id\":\"SS_1907236768800382980\",\"type\":\"scores\",\"enable\":true,\"assigneeType\":\"leader\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":0,\"children\":[{\"id\":\"S_1907236768800382981\",\"type\":\"score\",\"enable\":true,\"assigneeType\":\"leader\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[\"transfer\"],\"weight\":100,\"children\":[]}]}");
-      node.id = "SS_" + this.generalId();
-      node.children.forEach((_,i) => {
-        node.children[i].id = "S_" + this.generalId();
-      });
-      return node;
-    },
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.childIndex = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.defaultNode();
-
-          this.childIndex = this.currentNode.children && this.currentNode.children.length > 0 ? 0 : null;
-
-          if (this.childIndex !== null && !!this.currentNode.children[this.childIndex]){
-            switch (this.currentNode.children[this.childIndex].assigneeType){
-              case 'user':
-                this.userSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'post':
-                this.postSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-              case 'deptLeader':
-                this.deptSelected = [...this.currentNode.children[this.childIndex].assigneeIds];
-                break;
-            }
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    addChild(){
-      let id = "S_" + this.generalId();
-      this.currentNode.children.push({
-        id:id,
-        type:'score',
-        enable:true,
-        assigneeType:'leader',
-        leaderLevel:1,
-        assigneeIds:[],
-        multipleType:'or',
-        allows:['transfer'],
-        weight:100,
-        children:[],
-      });
-    },
-    removeChild(index){
-      if (this.currentNode.children.length <= 1 || !this.currentNode.children[index]) return;
-      let selectChildId = this.currentNode.children[index].id;
-      this.childIndex = 0;
-      this.currentNode.children = this.currentNode.children.filter((_,i) => i !== index);
-      if (selectChildId){
-        this.currentNode.children.forEach((child,i) => {
-          if (child.id === selectChildId) this.childIndex = i;
-        })
-      }
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    childSelect(index){
-      if (!this.currentNode.children[index]) return;
-      this.childIndex = index;
-      this.userSelected = this.currentNode.children[this.childIndex].assigneeType === 'user' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.postSelected = this.currentNode.children[this.childIndex].assigneeType === 'post' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.deptSelected = this.currentNode.children[this.childIndex].assigneeType === 'deptLeader' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-    },
-    onConfirm(){
-      this.$emit('confirm',this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-
-.reference {
-  position: absolute;
-  top: -60px;
-  left: 0px;
-}
-
-.base-table {
-  width: 100%;
-  border-collapse: collapse;
-  margin: 10px auto;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
-  background-color: #fff;
-}
-
-.base-table th,
-.base-table td {
-  padding: 3px 6px;
-  text-align: center;
-  border-bottom: 1px solid #ddd;
-  box-sizing: border-box;
-}
-
-.base-table th {
-  background-color: #f2f2f2;
-  font-weight: bold;
-}
-
-.base-table td {
-  border-left: 1px solid #ccc;
-}
-
-.base-table tr:hover {
-  background-color: #f5f5f5;
-}
-
-</style>

+ 0 - 364
src/newPerformance/components/IndicatorSetting/PerTargetConfirmSelector.vue

@@ -1,364 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="目标确认节点配置" width="600px">
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-
-      <el-form-item label="">
-        <div class="handler-list">
-          <el-tag v-for="(item,index) in currentNode.children" :key="index" :type="childIndex === index ? '' : 'info'"
-            closable @close="removeChild(index)" @click="childSelect(index)">
-            {{assigneeMap[item.assigneeType] || '未知'}}
-          </el-tag>
-          <el-button v-show="currentNode.enable" icon="el-icon-plus" size="mini" style="margin-bottom: 10px;"
-            @click="addChild" />
-        </div>
-      </el-form-item>
-      <el-form-item label="确认人">
-        <el-radio-group v-model="currentNode.children[childIndex].assigneeType" :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange">
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <div class="flex-center-center" style="margin-left: 100px;">
-        <el-form-item label="">
-          <template v-if="currentNode.children[childIndex].assigneeType === 'leader'">
-            <el-select v-model="currentNode.children[childIndex].leaderLevel" placeholder="请选择管理员"
-              :disabled="!currentNode.enable" filterable style="width: 300px;" key="leader"
-              @change="onOrgManagerChange">
-              <el-option v-for="item in levelOptions" :key="item.value" :label="item.label" :value="item.value"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'user'">
-            <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="user" @change="onUserChange">
-              <el-option v-for="item in employees" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'post'">
-            <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="post" @change="onPostChange">
-              <el-option v-for="item in postList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'deptLeader'">
-            <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="deptLeader" @change="onDeptChange">
-              <el-option v-for="item in deptList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-          </template>
-        </el-form-item>
-      </div>
-      <el-form-item label="多人时">
-        <el-radio-group v-model="currentNode.children[childIndex].multipleType" :disabled="!currentNode.enable">
-          <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-          <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-          <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-        </el-radio-group>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-        </div>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-        </div>
-      </el-form-item>
-
-
-
-      <el-form-item label="允许">
-        <el-checkbox-group v-model="currentNode.children[childIndex].allows" :disabled="!currentNode.enable">
-          <el-checkbox-button label="edit">修改指标</el-checkbox-button>
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-
-export default {
-  name: "PerTargetConfirmSelector",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-    indicator:{
-      type: Object,
-      default: () =>{
-        return null
-      }
-    }
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      childIndex: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-    dataReset(){
-      this.currentNode = null;
-      this.childIndex = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    initData(){
-      if (this.loading || !this.indicator) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.indicator.flow.nodes.find(node => node.type === 'targetConfirms');
-
-          this.childIndex = this.currentNode.children && this.currentNode.children.length > 0 ? 0 : null;
-
-          if (this.childIndex !== null && !!this.currentNode.children[this.childIndex]){
-            switch (this.currentNode.children[this.childIndex].assigneeType){
-              case 'user':
-                this.userSelected = this.currentNode.children[this.childIndex].assigneeIds;
-                break;
-              case 'post':
-                this.postSelected = this.currentNode.children[this.childIndex].assigneeIds;
-                break;
-              case 'deptLeader':
-                this.deptSelected = this.currentNode.children[this.childIndex].assigneeIds;
-                break;
-            }
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    addChild(){
-      let id = "TC_" + this.generalId();
-      this.currentNode.children.push({
-        id:id,
-        type:'targetConfirm',
-        enable:true,
-        assigneeType:'self',
-        leaderLevel:1,
-        assigneeIds:[],
-        multipleType:'or',
-        allows:[],
-        weight:0,
-        children:[],
-      });
-    },
-    removeChild(index){
-      if (this.currentNode.children.length <= 1 || !this.currentNode.children[index]) return;
-      let selectChildId = this.currentNode.children[index].id;
-      this.childIndex = 0;
-      this.currentNode.children = this.currentNode.children.filter((_,i) => i !== index);
-      if (selectChildId){
-        this.currentNode.children.forEach((child,i) => {
-          if (child.id === selectChildId) this.childIndex = i;
-        })
-      }
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    childSelect(index){
-      if (!this.currentNode.children[index]) return;
-      this.childIndex = index;
-      this.userSelected = this.currentNode.children[this.childIndex].assigneeType === 'user' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.postSelected = this.currentNode.children[this.childIndex].assigneeType === 'post' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.deptSelected = this.currentNode.children[this.childIndex].assigneeType === 'deptLeader' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-    }
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 0 - 394
src/newPerformance/components/IndicatorSetting/PerTargetConfirmSelectorOnly.vue

@@ -1,394 +0,0 @@
-<template>
-  <el-dialog :visible.sync="innerVisible" @close="handleClose" @open="initData" @closed="dataReset" append-to-body
-    :close-on-click-modal="false" center title="目标确认节点配置" width="600px" class="target-confirm-dialog">
-
-    <!-- <el-alert class="diy-tip" title="可配置多位人员来确定考核的指标" type="success" description>
-      <p>可以是组织管理员,被考核人自己,指定人员,岗位负责人,部门负责人</p>
-      <p>备注:</p>
-      <p>(会签要求所有审批人一致同意)</p>
-      <p>(或签只需任一审批人同意即可)</p>
-    </el-alert> -->
-    <el-form v-if="currentNode" label-width="200">
-      <el-form-item label="启用">
-        <el-switch v-model="currentNode.enable" />
-      </el-form-item>
-
-      <el-form-item label="">
-        <div class="handler-list">
-          <el-tag v-for="(item,index) in currentNode.children" :key="index" :type="childIndex === index ? '' : 'info'"
-            closable @close="removeChild(index)" @click="childSelect(index)">
-            {{assigneeMap[item.assigneeType] || '未知'}}
-          </el-tag>
-          <el-button v-show="currentNode.enable" icon="el-icon-plus" size="mini" style="margin-bottom: 10px;"
-            @click="addChild" />
-        </div>
-      </el-form-item>
-      <el-form-item label="确认人">
-        <el-radio-group v-model="currentNode.children[childIndex].assigneeType" :disabled="!currentNode.enable"
-          @change="onAssigneeTypeChange">
-          <el-radio-button label="leader">组织管理员</el-radio-button>
-          <el-radio-button label="user">指定人员</el-radio-button>
-          <el-radio-button label="self">被考核人</el-radio-button>
-          <el-radio-button label="post">岗位</el-radio-button>
-          <el-radio-button label="deptLeader">部门负责人</el-radio-button>
-        </el-radio-group>
-      </el-form-item>
-
-      <div class="flex-center-center" style="margin-left: 100px;">
-        <el-form-item label="">
-          <template v-if="currentNode.children[childIndex].assigneeType === 'leader'">
-            <el-select v-model="currentNode.children[childIndex].leaderLevel" placeholder="请选择管理员"
-              :disabled="!currentNode.enable" filterable style="width: 300px;" key="leader"
-              @change="onOrgManagerChange">
-              <el-option v-for="item in levelOptions" :key="item.value" :label="item.label" :value="item.value"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>被考核人所在部门的直接上级或上上级 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'user'">
-            <el-select v-model="userSelected" placeholder="请选择指定人员" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="user" @change="onUserChange">
-              <el-option v-for="item in employees" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>直接选择需要的人员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'post'">
-            <el-select v-model="postSelected" placeholder="请选择岗位" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="post" @change="onPostChange">
-              <el-option v-for="item in postList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构下,所属岗位的成员 )</div>
-          </template>
-          <template v-if="currentNode.children[childIndex].assigneeType === 'deptLeader'">
-            <el-select v-model="deptSelected" placeholder="请选择部门" multiple :disabled="!currentNode.enable" filterable
-              style="width: 300px;" key="deptLeader" @change="onDeptChange">
-              <el-option v-for="item in deptList" :key="item.id" :label="item.name" :value="item.id"
-                style="width: 300px;" />
-            </el-select>
-            <br>
-            <div class="fontColorC">(<span style="color: red"> * </span>组织架构中,所设置的部门管理员 )</div>
-          </template>
-        </el-form-item>
-      </div>
-
-
-      <el-form-item label="多人时">
-        <el-radio-group v-model="currentNode.children[childIndex].multipleType" :disabled="!currentNode.enable">
-          <el-radio-button label="or">任一人确认(或签)</el-radio-button>
-          <el-radio-button label="parallel">按顺序确认(会签)</el-radio-button>
-          <el-radio-button label="sequence">同时确认(会签)</el-radio-button>
-        </el-radio-group>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>会签要求所有审批人一致同意</span> )
-        </div>
-        <div class="flex-center-center fontColorC" style="margin-left: 100px;">
-          ( <span style="color: red;"> * </span><span>或签只需任一审批人同意即可</span> )
-        </div>
-      </el-form-item>
-
-      <el-form-item label="允许">
-        <el-checkbox-group v-model="currentNode.children[childIndex].allows" :disabled="!currentNode.enable">
-          <el-checkbox-button label="edit">修改指标</el-checkbox-button>
-          <el-checkbox-button label="transfer">转交</el-checkbox-button>
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-row type="flex" justify="end">
-        <el-col align="end">
-          <el-button type="primary" @click="onConfirm">
-            确认
-          </el-button>
-        </el-col>
-      </el-row>
-    </template>
-  </el-dialog>
-</template>
-
-
-<script>
-import Template from "@/examine/components/Template.vue";
-import introJs from 'intro.js'
-import 'intro.js/introjs.css'
-
-export default {
-  name: "PerTargetConfirmSelectorOnly",
-  components: {Template},
-  props: {
-    showVisible: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data(){
-    return {
-      userInfo: this.$userInfo(),
-      currentNode: null,
-      childIndex: null,
-      innerVisible: this.showVisible,
-      loading:false,
-      employees:[],
-      postList:[],
-      deptList:[],
-      userSelected:[],
-      postSelected:[],
-      deptSelected:[],
-      assigneeMap:{
-        leader:'组织管理员',
-        user:'指定人员',
-        self:'被考核人',
-        post:'岗位',
-        deptLeader:'部门负责人',
-      },
-      levelOptions: [
-        {
-          value: 1,
-          label: '直接管理员'
-        },
-        {
-          value: 2,
-          label: '二级管理员'
-        },
-        {
-          value: 3,
-          label: '三级管理员'
-        },
-        {
-          value: 4,
-          label: '四级管理员'
-        },
-        {
-          value: 5,
-          label: '五级管理员'
-        },
-        {
-          value: 6,
-          label: '六级管理员'
-        }
-      ]
-    }
-  },
-  computed:{
-    employeeMap(){
-      const map = {};
-      this.employees.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    postMap(){
-      const map = {};
-      this.postList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-    deptMap(){
-      const map = {};
-      this.deptList.forEach(e => {
-        if (!map[e.id]) map[e.id] = e.name;
-      });
-      return map;
-    },
-  },
-  watch:{
-    showVisible(val){
-      this.innerVisible = val;
-    },
-  },
-  methods: {
-    idGeneral(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    defaultNode(){
-      const node = JSON.parse("{\"id\":\"TCS_1906993155344510977\",\"type\":\"targetConfirms\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[],\"weight\":0,\"children\":[{\"id\":\"TC_1906993155344510978\",\"type\":\"targetConfirm\",\"enable\":true,\"assigneeType\":\"self\",\"leaderLevel\":1,\"assigneeIds\":[],\"multipleType\":\"or\",\"allows\":[],\"weight\":0,\"children\":[]}]}");
-      node.id = "TCS_" + this.idGeneral();
-      node.children.forEach((_,i) => {
-        node.children[i].id = "TC_" + this.idGeneral();
-      });
-      return node;
-    },
-    matchErrMsg(err){
-      return err.toString().replace(/[(Error: )]/g,'');
-    },
-    handleClose(){
-      this.$emit('update:showVisible',false);
-    },
-
-    dataReset(){
-      this.currentNode = null;
-      this.childIndex = null;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-
-
-    initData() {
-      if (this.loading) return;
-      this.dataReset();
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$axiosUser('get', '/api/pro/employee/index', {page:0,page_size:10,status:1}, 'v2'),
-        this.$axiosUser('get','/org/post'),
-        this.$axiosUser('get', `/org/departments/${this.userInfo.site_id}`)
-      ])
-        .then(([employeeRes,postRes,deptRes]) => {
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.msg);
-          if (postRes.data.code !== 1) throw new Error(postRes.data.message);
-          if (deptRes.data.code !== 1) throw new Error(deptRes.data.message);
-
-          this.employees = employeeRes.data.data.list
-            .filter(e => e.account_id && e.account_id > 0)
-            .map(e => {
-              return {
-                id:e.id,
-                name:e.name,
-              }
-            });
-
-          this.postList = postRes.data.data.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.deptList = deptRes.data.data.list.map(item => {
-            return {
-              id: item.id,
-              name: item.name,
-            }
-          });
-
-          this.currentNode = this.defaultNode();
-
-          this.childIndex = this.currentNode.children && this.currentNode.children.length > 0 ? 0 : null;
-
-          if (this.childIndex !== null && !!this.currentNode.children[this.childIndex]){
-            switch (this.currentNode.children[this.childIndex].assigneeType){
-              case 'user':
-                this.userSelected = this.currentNode.children[this.childIndex].assigneeIds;
-                break;
-              case 'post':
-                this.postSelected = this.currentNode.children[this.childIndex].assigneeIds;
-                break;
-              case 'deptLeader':
-                this.deptSelected = this.currentNode.children[this.childIndex].assigneeIds;
-                break;
-            }
-          }
-        })
-        .catch(err => {
-          this.$message.error(this.matchErrMsg(err));
-          result = false;
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.handleClose();
-        })
-    },
-    generalId(){
-      return Date.now() + Math.floor(Math.random() * 10000);
-    },
-    addChild(){
-      let id = "TC_" + this.generalId();
-      this.currentNode.children.push({
-        id:id,
-        type:'targetConfirm',
-        enable:true,
-        assigneeType:'self',
-        leaderLevel:1,
-        assigneeIds:[],
-        multipleType:'or',
-        allows:[],
-        weight:0,
-        children:[],
-      });
-    },
-    removeChild(index){
-      if (this.currentNode.children.length <= 1 || !this.currentNode.children[index]) return;
-      let selectChildId = this.currentNode.children[index].id;
-      this.childIndex = 0;
-      this.currentNode.children = this.currentNode.children.filter((_,i) => i !== index);
-      if (selectChildId){
-        this.currentNode.children.forEach((child,i) => {
-          if (child.id === selectChildId) this.childIndex = i;
-        })
-      }
-    },
-    onAssigneeTypeChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onOrgManagerChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [];
-      this.currentNode.children[this.childIndex].leaderLevel = v;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onUserChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = v;
-      this.postSelected = [];
-      this.deptSelected = [];
-    },
-    onPostChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = v;
-      this.deptSelected = [];
-    },
-    onDeptChange(v){
-      this.currentNode.children[this.childIndex].assigneeIds = [...v];
-      this.currentNode.children[this.childIndex].leaderLevel = 1;
-      this.userSelected = [];
-      this.postSelected = [];
-      this.deptSelected = v;
-    },
-    childSelect(index){
-      if (!this.currentNode.children[index]) return;
-      this.childIndex = index;
-      this.userSelected = this.currentNode.children[this.childIndex].assigneeType === 'user' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.postSelected = this.currentNode.children[this.childIndex].assigneeType === 'post' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-      this.deptSelected = this.currentNode.children[this.childIndex].assigneeType === 'deptLeader' ? this.currentNode.children[this.childIndex].assigneeIds : [];
-    },
-    onConfirm(){
-      this.$emit('confirm',this.currentNode);
-      this.handleClose();
-    },
-  }
-}
-</script>
-
-<style scoped lang="scss">
-.handler-list {
-  width: 500px;
-  margin: 0 auto 16px auto;
-  border-radius: 6px;
-  border: 1px solid #d7dae2;
-  padding: 10px 0 0 10px;
-  box-sizing: border-box;
-  display: flex;
-  flex-wrap: wrap;
-
-  .el-tag {
-    margin: 0 10px 10px 0;
-    cursor: pointer;
-  }
-}
-
-</style>

+ 1 - 16
src/newPerformance/components/IndicatorSetting/PublishComp.vue

@@ -53,16 +53,7 @@
                     </el-date-picker>
                 </el-form-item>
 
-                <div class="selectBox" v-if="form.cycleType == 2 || form.cycleType == 3">
-                    <SelectCircle :dateParameter="dateParameter" :dateOptions="dateOptions" @confirm="dateConfirm"
-                        :id="1">
-                        <div class="flex-box-ce cursor">
-                            <div>{{ dateParameter.year }}</div>
-                            <div style="margin: 0 10px;">{{ dateParameter.name }}</div>
-                            <i class="el-icon-caret-bottom fontColorC"></i>
-                        </div>
-                    </SelectCircle>
-                </div>
+                
 
                 <el-form-item v-if="form.cycleType == 4" label="选择月份" prop="month">
                     <el-date-picker v-model="form.month" type="month" placeholder="选择月" value-format="yyyy-MM">
@@ -168,16 +159,10 @@ function getQuarterDates(year, quarter) {
 }
 
 import { mapGetters } from 'vuex';
-import SelectCircle from '@/newPerformance/components/TemplateDetails/SelectCircle'; //选择周期
-import CateDetails from "@/newPerformance/components/TemplateDetails/CateDetails.vue" // 考核分类明细抽屉
-import InterviewFlow from "@/newPerformance/components/TemplateDetails/InterviewFlow.vue" // 面谈弹框
 import TargetSearch from '@/performance/views/assessManagement/TargetSearch'; // 对齐目标
 
 export default {
     components: {
-        SelectCircle,
-        CateDetails,
-        InterviewFlow,
         TargetSearch
     },
     model: {

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 220 - 486
src/newPerformance/components/IndicatorSetting/QuickCreate.vue


+ 0 - 928
src/newPerformance/components/IndicatorSetting/TemplateDetails.vue

@@ -1,928 +0,0 @@
-<template>
-    <div class="box boxMinHeight">
-        <el-alert class="bounce animated" type="warning" :title="alertTilte" :closable="false" show-icon
-            style="width: 100%; margin-bottom: 10px;"></el-alert>
-        <header class="header">
-            <div class="header-content flex-box-ce">
-                <!-- 返回按钮 -->
-                <div class="flex-box-ce header-left">
-                    <el-tooltip class="item" effect="dark" :content="templateTitle" placement="bottom">
-                        <div>{{ templateTitle }}</div>
-                    </el-tooltip>
-                    <el-popover ref="popoverRef" placement="right" width="400" trigger="click">
-                        <div class="flex-box-ce">
-                            <el-input v-model="title" placeholder="请输入模板名称" size="small"></el-input>
-                            <el-button v-if="$getRole(1)" type="primary" size="small" style="margin-left: 10px;"
-                                @click="editTitle()">确定</el-button>
-                        </div>
-                        <i class="el-icon-edit" slot="reference" style="margin-left: 10px; color: #999;"></i>
-                    </el-popover>
-                </div>
-
-                <!-- 发布按钮 -->
-                <div class="header-right">
-                    <el-button type="primary" size="small" @click="addData()">添加指标</el-button>
-
-                    <el-button type="danger" :disabled="!(multipleSelection && multipleSelection.length > 0)"
-                        @click="confirmDelete()" size="small">批量删除</el-button>
-
-                    <div class="flex-box-ce" style="margin-left: 10px; color: #999;">
-                        <el-popover placement="right" trigger="hover" class="popover" @show="showPopover">
-                            <div class="flex-box-ce" style="width: 200px; justify-content: space-between;">
-                                <el-checkbox v-model="checkAll" @change="checkAllChangeFn">全选</el-checkbox>
-                                <el-button type="text" @click="reset(true)">重置</el-button>
-                            </div>
-                            <div style="height: 1px; background-color: #DCDFE6; margin: 5px 0;"></div>
-                            <el-checkbox-group v-model="checkColumns" @change="changeColumns"
-                                style="width: 200px; display: flex; flex-direction: column;">
-                                <el-checkbox v-for="(item, key) in this.tableColumn" :label="item.label"
-                                    :key="item.label"></el-checkbox>
-                            </el-checkbox-group>
-                            <div class="flex-box-ce" slot="reference">
-                                <el-button class="primaryBtn" icon="el-icon-s-tools" type="primary"
-                                    size="mini">设置考核流程</el-button>
-                            </div>
-                        </el-popover>
-                    </div>
-                </div>
-            </div>
-        </header>
-
-        <div style="height: 1px; background-color: #DCDFE6; margin-top: 5px;"></div>
-
-        <el-table :data="tableData" v-loading="loading" stripe style="width: 100%; margin-top: 10px;" border
-            :header-cell-style="{ background: '#f5f7fa' }" @selection-change="handleSelectChange">
-            <el-table-column type="selection"></el-table-column>
-            <template v-for="item in tableColumn">
-
-                <el-table-column v-if="item.isShow && item.label === '规则'" :key="item.prop" :prop="item.prop"
-                    :label="item.label" align="center" :min-width="item.width">
-                    <template slot-scope="scope">
-                        <el-tooltip v-if="scope.row.content" class="item" effect="dark" placement="top">
-                            <div v-html="scope.row.content" slot="content"
-                                style="max-width: 300px; white-space: pre-line;">
-                            </div>
-                            <div class="oneLine"
-                                @click="editContent(scope.$index, scope.row.content, scope.row.indicatorId)">
-                                {{ scope.row.content }}
-                            </div>
-                        </el-tooltip>
-                        <el-button v-else
-                            @click="editContent(scope.$index, scope.row.content, scope.row.indicatorId)">编辑规则</el-button>
-                    </template>
-                </el-table-column>
-
-                <el-table-column v-else-if="item.isShow && ['目标', '权重(%)'].includes(item.label)" :key="item.prop"
-                    :prop="item.prop" :label="item.label" align="center" :min-width="item.width">
-                    <template slot-scope="scope">
-                        <el-input v-model="scope.row[item.prop]" :placeholder="item.label" clearable
-                            @blur="handleEdit(item.prop, scope.row[item.prop], scope.row.indicatorId)"
-                            oninput="value=value.replace(/[^\d.]/g,'')"></el-input>
-                    </template>
-                </el-table-column>
-
-                <el-table-column v-else-if="item.isShow && item.label === '计算公式'" prop="formulae" label="计算公式"
-                    align="center" min-width="130">
-                    <template slot-scope="scope">
-                        <el-button @click="openFormula(scope.row, scope.$index)">
-                            {{ scope.row.expression && scope.row.expression.formulas.length > 0 ? `公式
-                            ${scope.row.expression.formulas.length} 条` : '公式' }}
-                        </el-button>
-                    </template>
-                </el-table-column>
-
-                <el-table-column v-else-if="item.isShow && ['指标', '单位'].includes(item.label)" :key="item.prop"
-                    :prop="item.prop" :label="item.label" align="center" :min-width="item.width">
-                    <template slot-scope="scope">
-                        <el-input v-model="scope.row[item.prop]" :placeholder="item.label" clearable
-                            @blur="handleEdit(item.prop, scope.row[item.prop], scope.row.indicatorId)"></el-input>
-                    </template>
-                </el-table-column>
-
-                <el-table-column v-else-if="item.isShow && ['过程跟踪'].includes(item.label)" :key="item.prop"
-                    :prop="item.prop" :label="item.label" align="center" :min-width="item.width">
-                    <template slot-scope="scope">
-                        <el-input v-model="scope.row[item.prop]" :placeholder="item.label" clearable
-                            @blur="handleEdit(item.prop, scope.row[item.prop], scope.row.indicatorId)"></el-input>
-                    </template>
-                </el-table-column>
-
-                <el-table-column v-if="item.isShow && flowColumn.includes(item.label)" :key="item.prop"
-                    :prop="item.prop" :label="item.label" :render-header="(h, obj) => renderHeader(h, item, item.prop)"
-                    align="center" :min-width="item.width" fixed="right">
-                    <template slot-scope="scope">
-                        <template v-if="item.label === '确认目标'">
-                            <el-switch v-if="!scope.row.flow.nodes[0].enable" :value="scope.row.flow.nodes[0].enable"
-                                @input="handleStatusChange(-1, scope.row, 'targetConfirms')"></el-switch>
-                            <ShowDataComp v-else-if="scope.row.flow.nodes[0].enable && isDataShow"
-                                :show-data="scope.row.flow.nodes[0]" :select-nodes="scope.row"
-                                @btnClick="handleBtnClick" />
-                        </template>
-
-                        <template v-if="item.label === '录入结果'">
-                            <el-switch v-if="!scope.row.flow.nodes[1].enable" :value="scope.row.flow.nodes[1].enable"
-                                @input="handleStatusChange(-1, scope.row, 'resultInput')"></el-switch>
-                            <ShowDataComp v-else-if="scope.row.flow.nodes[1].enable && isDataShow"
-                                :show-data="scope.row.flow.nodes[1]" :select-nodes="scope.row"
-                                @btnClick="handleBtnClick" />
-                        </template>
-
-                        <template v-if="item.label === '自评'">
-                            <el-switch v-model="scope.row.flow.nodes[2].enable"
-                                @change="handleScoreSelf(scope.row, scope.$index)"></el-switch>
-                        </template>
-
-                        <template v-if="item.label === '互评'">
-                            <el-switch :value="scope.row.flow.nodes[3].enable"
-                                @input="handleStatusChange(-1, scope.row, 'scoreEachOther')"></el-switch>
-                        </template>
-
-                        <template v-if="item.label === '评分'">
-                            <el-switch v-if="!scope.row.flow.nodes[4].enable" :value="scope.row.flow.nodes[4].enable"
-                                @input="handleStatusChange(-1, scope.row, 'scores')"></el-switch>
-                            <ShowDataComp v-else-if="scope.row.flow.nodes[4].enable && isDataShow"
-                                :show-data="scope.row.flow.nodes[4]" :select-nodes="scope.row"
-                                @btnClick="handleBtnClick" />
-                        </template>
-
-                        <template v-if="item.label === '审批'">
-                            <el-switch v-if="!scope.row.flow.nodes[5].enable" :value="scope.row.flow.nodes[5].enable"
-                                @input="handleStatusChange(-1, scope.row, 'reviews')"></el-switch>
-                            <ShowDataComp v-else-if="scope.row.flow.nodes[5].enable && isDataShow"
-                                :show-data="scope.row.flow.nodes[5]" :select-nodes="scope.row"
-                                @btnClick="handleBtnClick" />
-                        </template>
-
-                        <template v-if="item.label === '抄送'">
-                            <el-switch v-if="!scope.row.flow.nodes[6].enable" :value="scope.row.flow.nodes[6].enable"
-                                @input="handleStatusChange(-1, scope.row, 'cc')"></el-switch>
-                            <ShowDataComp v-else-if="scope.row.flow.nodes[6].enable && isDataShow"
-                                :show-data="scope.row.flow.nodes[6]" :select-nodes="scope.row"
-                                @btnClick="handleBtnClick" />
-                        </template>
-
-                    </template>
-                </el-table-column>
-            </template>
-
-        </el-table>
-
-        <div style="height: 50px;"></div>
-        <!-- <TiptapComp /> -->
-        <!-- 编辑流程节点 -->
-        <!-- <HandleNode v-if="currentIndicator" v-model="dialogVisible" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
-            :indicator-id="selectIndicatorId" @closeDialog="closeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" /> -->
-
-        <!-- 编辑计算公式 -->
-        <FormulaComp v-if="showFormula" v-model="showFormula"
-            :fixed-props="[{ key: 'target', name: '目标' }, { key: 'weight', name: '权重' }, { key: 'result', name: '结果值' }]"
-            :expressions-props="currentIndicator.expression.formulas || []" @onConfirm="onFormulaConfirm" />
-
-        <!-- 发布考核弹框 -->
-        <PublishComp v-if="showPublish" v-model="showPublish" :template-ids="[templateId]"
-            @onConfirm="onPubishConfirm" />
-
-        <!-- 编辑规则 -->
-        <EditContentComp v-if="showEditContent" v-model="showEditContent" :content="content"
-            :indicator-id="selectIndicatorId" :template-id="templateId" @finishEdit="finishEditContent" />
-
-        <!-- 批量修改流程节点 -->
-        <BatchHandleNode v-if="batchHandleDialog" v-model="batchHandleDialog" :template-id="templateId"
-            :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType" :handle-node="handleNode"
-            @onConfirm="finishBatchHandle" />
-
-        <!-- 编辑确认目标节点 -->
-        <TargetConfirms v-if="targetConfirms" v-model="targetConfirms" :form-label="formLabel"
-            :dialog-title="dialogTitle" :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
-            :indicator-id="selectIndicatorId" @closeDialog="closeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑录入结果节点 -->
-        <ResultInput v-if="resultInput" v-model="resultInput" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
-            :indicator-id="selectIndicatorId" @closeDialog="closeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑互评节点 -->
-        <ScoreEachOther v-if="scoreEachOther" v-model="scoreEachOther" :form-label="formLabel"
-            :dialog-title="dialogTitle" :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
-            :indicator-id="selectIndicatorId" @closeDialog="closeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑评分节点 -->
-        <Scores v-if="scores" v-model="scores" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
-            :template-id="templateId" :select-nodes="selectNodes" :indicator-id="selectIndicatorId"
-            @closeDialog="closeDialog" :tag-index="tagIndex" @onConfirm="finishHandle" />
-
-        <Reviews v-if="reviews" v-model="reviews" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
-            :indicator-id="selectIndicatorId" @closeDialog="closeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑审批节点 -->
-        <CC v-if="cc" v-model="cc" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
-            :template-id="templateId" :select-nodes="selectNodes" :indicator-id="selectIndicatorId"
-            @closeDialog="closeDialog" :tag-index="tagIndex" @onConfirm="finishHandle" />
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import FormulaComp from '@/newPerformance/components/TemplateDetails/FormulaComp'; // 计算公式弹框
-import HandleNode from '@/newPerformance/components/TemplateDetails/HandleNode'; //单独设置流程节点弹框
-import PublishComp from '@/newPerformance/components/TemplateDetails/PublishComp'; // 发布考核弹框
-import ShowDataComp from '@/newPerformance/components/PublicComp/ShowData'; // 显示节点数据组件
-import EditContentComp from '@/newPerformance/components/TemplateDetails/EditContent'; // 编辑规则组件
-import BatchHandleNode from '@/newPerformance/components/TemplateDetails/BatchHandleNode'; // 批量设置流程节点
-import TargetConfirms from '@/newPerformance/components/TemplateDetails/TargetConfirms'; // 确认目标流程节点
-import ResultInput from '@/newPerformance/components/TemplateDetails/ResultInput'; // 结果录入流程节点
-import ScoreEachOther from '@/newPerformance/components/TemplateDetails/ScoreEachOther'; // 互评流程节点
-import Scores from '@/newPerformance/components/TemplateDetails/Scores'; // 评分流程节点
-import Reviews from '@/newPerformance/components/TemplateDetails/Reviews'; // 审批流程节点
-import CC from '@/newPerformance/components/TemplateDetails/CC'; // 审批流程节点
-
-export default {
-    components: {
-        HandleNode,
-        FormulaComp,
-        PublishComp,
-        ShowDataComp,
-        EditContentComp,
-        BatchHandleNode,
-        TargetConfirms,
-        ResultInput,
-        ScoreEachOther,
-        Scores,
-        Reviews,
-        CC
-    },
-    props: {
-        // 模板ID
-        templateId: {
-            type: Number | String,
-            default: ''
-        }
-    },
-    data() {
-        return {
-            isDataShow: false,
-            isShow: false,
-            templateTitle: "模板名称",
-            loading: false,
-            title: "模板名称",
-            alertTilte: "可在表格中直接编辑指标,规则 (规则支持富文本) ,目标,单位,权重,计算公式以及流程节点, 注意: 每个指标的标题不能为空!每个指标的评分节点一定要开启!",
-            tableData: [], // 表格数据
-            showFormula: false, // 编辑计算公式弹框显示
-            showPublish: false, // 发布考核弹框显示
-            dialogVisible: false, // 编辑流程节点弹框显示
-            dialogTitle: "", // 编辑流程节点弹框标题
-            isDisable: false, // 是否禁用
-            nodeType: "", // 节点类型
-            currentIndicator: null, // 操作的指标
-            selectIndicatorId: "", // 选择的指标ID
-            selectNodes: [], // 选中指标所有的节点
-            selectIndex: 0, // 表格行索引
-            formLabel: "",
-            tagIndex: 0,
-            multipleSelection: [],
-            content: "", // 指标规则
-            showEditContent: false, // 编辑指标内容弹框
-            deptList: [], // 部门列表 - 树形结构
-            dept_list: [], // 部门列表
-            postList: [], // 岗位列表
-            flowColumn: ["确认目标", "录入结果", "自评", "互评", "评分", "审批", "抄送", "过程跟踪"],
-            tableColumn: [
-                { label: "指标", prop: "title", isShow: true, width: 150 },
-                { label: "规则", prop: "content", isShow: true, width: 150 },
-                { label: "目标", prop: "target", isShow: true, width: 80},
-                { label: "单位", prop: "unit", isShow: true, width: 100 },
-                { label: "权重(%)", prop: "weight", isShow: true, width: 100 },
-                { label: "计算公式", prop: "formulae", isShow: true, width: 120 },
-                { label: "过程跟踪", prop: "okrs", isShow: true, width: 120 },
-                { label: "确认目标", prop: "targetConfirms", isShow: false, width: 100 },
-                { label: "录入结果", prop: "resultInput", isShow: false, width: 100 },
-                { label: "自评", prop: "scoreSelf", isShow: false, width: 100 },
-                { label: "互评", prop: "scoreEachOther", isShow: false, width: 100 },
-                { label: "评分", prop: "scores", isShow: false, width: 100 },
-                { label: "审批", prop: "reviews", isShow: false, width: 100 },
-                { label: "抄送", prop: "cc", isShow: false, width: 100 }
-            ],
-            checkColumns: [],
-            checkAll: false,
-            flowInfo: {},
-            handleNode: {},
-            batchHandleDialog: false,
-            targetConfirms: false,
-            resultInput: false,
-            scoreEachOther: false,
-            scores: false,
-            reviews: false,
-            cc: false
-        }
-    },
-    
-    computed: {
-        ...mapGetters(['user_info']),
-        // 指标标题为空不能发起考核
-        isTitleNull() {
-            return this.tableData.find(item => item.title == '' || item.title == null) ? true : false
-        },
-        // 指标评分为禁用不能发起考核
-        isScoreNull() {
-            return this.tableData.find(item => !item.flow.nodes[4].enable) ? true : false
-        }
-    },
-
-
-    created() {
-        this.get_template_detail();
-        this.get_table_data();
-        this.isDataShow = false
-        // 请求岗位列表,部门列表
-        Promise.all([this.get_dept_list(), this.get_post_list()]).then(([deptRes, postRes]) => {
-            if (deptRes.data.code !== 1) return this.$message.error(deptRes.data.msg || "请求部门列表数据出错")
-            if (postRes.data.code !== 1) return this.$message.error(postRes.data.msg || "请求岗位列表数据出错")
-            this.dept_list = deptRes.data.data.list;
-            this.deptList = this.getTreeData(this.dept_list); // 处理成树状结构
-            this.postList = postRes.data.data.list
-            localStorage.setItem("dept_list", JSON.stringify(this.dept_list))
-            localStorage.setItem("deptList", JSON.stringify(this.deptList))
-            localStorage.setItem("postList", JSON.stringify(this.postList))
-            this.isDataShow = true
-        })
-    },
-    methods: {
-
-        // 处理部门树状结构数据
-        getTreeData(data) {
-            for (var i = 0; i < data.length; i++) {
-                data[i].checked = false;
-                if (data[i].children.length < 1) {
-                    // children若为空数组,则将children设为undefined
-                    data[i].children = undefined;
-                } else {
-                    // children若不为空数组,则继续 递归调用 本方法
-                    this.getTreeData(data[i].children);
-                }
-            }
-            return data;
-        },
-
-        // 获取部门
-        get_dept_list() {
-            return this.$axiosUser('get', '/api/pro/department/tree', '', 'v2')
-        },
-
-        // 岗位列表
-        get_post_list() {
-            let data = {
-                page: 1,
-                page_size: 999,
-                cate_id: -1,
-                name: ''
-            }
-            return this.$axiosUser('get', '/api/pro/post/cate_post_list', data)
-        },
-
-        // 自定义表头
-        renderHeader(h, item, type) {
-            let label = ""
-            const labels = {
-                'targetConfirms': '确认目标',
-                'resultInput': '录入结果',
-                'scoreSelf': '自评',
-                'scoreEachOther': '互评',
-                'scores': '评分',
-                'reviews': '审批',
-                'cc': '抄送'
-            }
-            label = labels[type];
-            let that = this;
-            
-            return h('div', {
-                style: { display: "flex", alignItems: "center", justifyContent: "center" }
-            }, [
-
-                h('el-button', {
-                    props: {
-                        size: 'small'
-                    },
-                    on: {
-                        click: function () {
-                            that.clickButton(type);
-                        }
-                    }
-                }, label),
-            ])
-        },
-
-        clickButton(nodeType) {
-            this.handleNode = this.flowInfo.nodes.find(node => node.type === nodeType)
-            let options = {
-                'targetConfirms': ['确认目标', '确认人'],
-                'resultInput': ['录入结果', '录入人'],
-                'scoreSelf': ['自评', ''],
-                'scoreEachOther': ['互评', '互评人'],
-                'scores': ['评分', '评分人'],
-                'reviews': ['审批', '审批人'],
-                'cc': ['抄送', '抄送人']
-            }
-            this.dialogTitle = options[nodeType][0]
-            this.formLabel = options[nodeType][1]
-            this.nodeType = nodeType; // 节点类型
-            this.batchHandleDialog = true;
-        },
-
-        // 打开编辑规则内容弹框
-        editContent(index, content, indicatorId) {
-            this.selectIndex = index;
-            this.content = content;
-            this.selectIndicatorId = indicatorId;
-            this.showEditContent = true
-        },
-
-        finishEditContent(content) {
-            this.tableData[this.selectIndex].content = content
-        },
-        
-        // 获取模板详情
-        get_template_detail() {
-            this.$axiosUser("get", `/performance/template/info/${this.user_info.site_id}/` + this.templateId).then(res => {
-                let { data: { data: { title, flow } } } = res
-                this.templateTitle = title || '模板名称'
-                this.title = title || '模板名称'
-                this.flowInfo = flow || {}
-            })
-        },
-
-        // 获取表格数据
-        get_table_data() {
-            this.loading = true
-            this.$axiosUser("get", `/performance/indicator/list/${this.user_info.site_id}/` + this.templateId).then(res => {
-                this.loading = false
-                this.tableData = res.data.data.list
-            })
-        },
-
-
-        editTableData() {
-        },
-        // 编辑模板标题
-        editTitle() {
-            let title = this.title
-            if (title !== null && title !== '') {
-                let url = `/performance/template/title/${this.user_info.site_id}`
-                this.$http.post(url, { templateId: this.templateId, title }).then(res => {
-                    if (res.code == 1) {
-                        this.$refs.popoverRef && this.$refs.popoverRef.doClose();
-                        this.get_template_detail();
-                    }
-                    
-                })
-            }
-        },
-
-        // 编辑指标名称,规则,权重,目标,单位
-        handleEdit(props, value, id) {
-            let url = '', data = {};
-            url = `/performance/indicator/${props}/${this.user_info.site_id}/${this.templateId}`;
-            data[props] = value;
-            data['indicatorId'] = id;
-            this.$http.post(url, data).then(res => {
-                if(res.code == 0) return this.$message.error(res.msg || '操作失败')
-            })
-        },
-
-        handleBtnClick(index, node, row) {
-            this.handleStatusChange(index, row, node.type)
-        },
-
-        // 自评节点单独操作
-        handleScoreSelf(row, index) {
-            let { indicatorId, flow: { nodes } } = row
-            let data = {
-                indicatorId, // 指标ID
-                nodes
-            }
-            let url = `/performance/indicator/flow/${this.user_info.site_id}/${this.templateId}`
-            this.$http.post(url, data).then(res => {
-                let { code, data } = res
-                if (code == 1) {
-                    this.tableData.splice(index, 1, data); //替换元素
-                    this.$message.success("操作成功");
-                } else {
-                    this.$message.error(res.message || '操作失败');
-                }
-            })
-        },
-
-        // 操作节点
-        handleStatusChange(index, row, nodeType) {
-            if (index !== -1) this.tagIndex = index // 子节点索引
-            this.currentIndicator = row;
-            let { indicatorId } = row;
-            this.selectIndicatorId = indicatorId; // 指标ID
-            this.selectNodes = row.flow.nodes; // 所有节点
-            this.nodeType = nodeType; // 节点类型
-            if (nodeType == 'targetConfirms') {
-                this.dialogTitle = "确认目标"
-                this.formLabel = "确认人"
-                this.targetConfirms = true;
-            }
-            if (nodeType == 'resultInput') {
-                this.dialogTitle = "录入结果"
-                this.formLabel = "录入人"
-                this.resultInput = true;
-            }
-            if (nodeType == 'scoreSelf') {
-                this.dialogTitle = "自评"
-            }
-            if (nodeType == 'scoreEachOther') {
-                this.dialogTitle = "互评"
-                this.formLabel = "互评人"
-                this.scoreEachOther = true
-            }
-            if (nodeType == 'scores') {
-                this.dialogTitle = "评分"
-                this.formLabel = "评分人"
-                this.scores = true
-
-            }
-            if (nodeType == 'reviews') {
-                this.dialogTitle = "审批"
-                this.formLabel = "审批人"
-                this.reviews = true
-            }
-            if (nodeType == 'cc') {
-                this.dialogTitle = "抄送"
-                this.formLabel = "抄送人"
-                this.cc = true
-            }
-            // this.dialogVisible = true;
-        },
-
-
-        // 添加指标
-        addData() {
-            let url = `/performance/indicator/create/${this.user_info.site_id}/${this.templateId}`
-            this.$http.post(url, {}).then(res => {
-                let { data, code } = res
-                if (code) this.tableData.push(data)
-            })
-        },
-
-        handleSelectChange(val) {
-            this.multipleSelection = val;
-        },
-        // 取消删除
-        cancelDelete() {
-            console.log("取消删除");
-        },
-        // 确认删除
-        confirmDelete() {
-            if (this.multipleSelection && this.multipleSelection.length > 0) {
-                this.$confirm('确定删除选中的指标吗?', '提示', {
-                    type: 'warning'
-                }).then(() => {
-                    // 创建一个包含异步任务的数组,每个任务都是一个 axios 请求
-                    const arrays = []
-                    this.multipleSelection.forEach(item => {
-                        arrays.push(this.deleteIndicator(item))
-                    })
-
-                    // 当所有请求都成功完成时,responses 是一个包含所有响应的数组
-                    Promise.all(arrays).then(responses => {
-                        // console.log(responses)
-                        this.get_table_data();
-                    }).catch(error => {
-                        // 如果任何一个请求失败,将会进入这个 catch 块
-                        console.log(error)
-                    })
-                }).catch(() => { });
-            }
-            
-        },
-        // 删除指标
-        deleteIndicator(item) {
-            let url = `/performance/indicator/remove/${this.user_info.site_id}/${this.templateId}/${item.indicatorId}`
-            return this.$axiosUser('post', url).then(res => {
-                return res.data
-            })
-        },
-        // 打开计算公式弹框
-        openFormula(row, index) {
-            this.currentIndicator = null;
-            this.selectIndex = -1;
-            this.currentIndicator = row;
-            this.selectIndex = index;
-            this.showFormula = true;
-        },
-        // 关闭编辑计算公式弹框
-        closeDialog() {
-            
-        },
-
-        // 全选复选框事件监听
-        checkAllChangeFn(val) {
-            if (val) {
-                // 全选
-                this.tableColumn.forEach(item => {
-                    item.isShow = true
-                })
-            } else {
-                // 反全选
-                this.tableColumn.forEach(item => {
-                    if (this.flowColumn.includes(item.label)) {
-                        item.isShow = false;
-                    } else {
-                        item.isShow = true
-                    }
-                })
-            }
-            this.showPopover();
-        },
-        // 重置,flag: Boolean,全部重置为flag
-        reset(flag) {
-            this.tableColumn.forEach(item => {
-                if (this.flowColumn.includes(item.label)) {
-                    item.isShow = false;
-                } else {
-                    item.isShow = true
-                }
-            })
-            this.showPopover();
-            this.refreshTable();
-        },
-        // 表格列是否显示的方法
-        showColumn(currentColumn) {
-            return this.tableColumn.find(item => item.prop == currentColumn).isShow;
-        },
-        /* 选择列 */
-        changeColumns(val) {
-            this.tableColumn.forEach(item => {
-                item.isShow = false;
-            })
-            // columns将val数组存在的值设为true,不存在的设为false
-            val && val.forEach(item => {
-                let current = this.tableColumn.find(i => i.label == item)
-                current.isShow = true;
-            })
-            // 判断是否全选
-            this.judgeIsCheckAll();
-            // this.refreshTable();
-        },
-        // 重新渲染表格
-        refreshTable() {
-            this.$nextTick(() => {
-                if (this.$refs.fmeaTableRef) this.$refs.fmeaTableRef.doLayout();
-            })
-        },
-        // 气泡框出现
-        showPopover() {
-            this.checkColumns = []
-            this.tableColumn.forEach(item => {
-                if (item.isShow) {
-                    this.checkColumns.push(item.label)
-                }
-            })
-            // 判断是否全选
-            this.judgeIsCheckAll();
-        },
-        // 判断是否全选
-        judgeIsCheckAll() {
-            // 选中的长度 = 表格列的长度  全选按钮就选中
-            if (this.checkColumns.length == this.tableColumn.length)
-                this.checkAll = true
-            else
-                this.checkAll = false
-        },
-        
-        finishHandle(nodes) {
-            let data = nodes
-            let url = `/performance/indicator/flow/${this.user_info.site_id}/${this.templateId}`
-            this.$http.post(url, data).then(res => {
-                let { code, data } = res
-                if (code == 1) {
-                    let { indicatorId } = this.currentIndicator;
-                    let index = this.tableData.findIndex(table => table.indicatorId === indicatorId)
-                    this.tableData.splice(index, 1, data); //替换元素
-                    this.$message.success("操作成功");
-                    this.nodeType = ''
-                    this.dialogTitle = ''
-                    this.selectNodes = []
-                    this.currentIndicator = []
-                    this.selectIndicatorId = ''
-                    this.tagIndex = -1
-                } else {
-                    this.$message.error(res.message || '操作失败');
-                }
-            })
-        },
-
-        // 批量操作成功
-        finishBatchHandle(data) {
-            this.flowInfo = data;
-            this.get_table_data();
-        },
-
-        // 编辑计算公式确定的回调
-        onFormulaConfirm(formulas) {
-            let url = `/performance/indicator/expression/${this.user_info.site_id}/${this.templateId}`;
-            let { indicatorId } = this.currentIndicator;
-            let params = {
-                indicatorId,
-                expression: {
-                    formulas: formulas.map(item => {
-                        return {
-                            condition: item.condition,
-                            expression: item.expression
-                        }
-                    })
-                }
-            }
-            this.$http.post(url, params).then(res => {
-                let { data, code } = res
-                if (code) {
-                    this.tableData.splice(this.selectIndex, 1, data); //替换元素
-                }
-            })
-        },
-        // 发布考核
-        publish() {
-            this.showPublish = true;
-        },
-        // 发布考核弹框的回调
-        onPubishConfirm(params, selectOkrs) {
-            let templateId = this.templateId;
-            let { title, startDate, endDate, cycleType, employeeIds, okrs, cateId } = params
-            let employees = employeeIds.map(employee => ({
-                employeeId: employee,
-                ids: [],
-                interviewFlow: {
-                    nodes: [
-                        {
-                            id: "IT_1894283564934688769",
-                            type: "interview",
-                            allows: [],
-                            enable: false,
-                            weight: 0,
-                            children: [],
-                            assigneeIds: [],
-                            leaderLevel: 1,
-                            assigneeType: "self",
-                            multipleType: "or"
-                        }
-                    ]
-                }
-            }))
-
-            let requireParams = {
-                title,
-                cycleType,
-                startDate,
-                endDate,
-                okrs,
-                templates: [
-                    {
-                        templateId,
-                        employees
-                    }
-                ],
-                cateId
-            }
-            // let url = `/performance/review/publish/${this.user_info.site_id}`;
-            // console.log(requireParams)
-            let url = `/performance/review/publish/templates/${this.user_info.site_id}`;
-            this.loading = true
-            this.$http.post(url, requireParams).then(res => {
-                console.log(res)
-                let { data, code } = res
-                this.loading = false
-                if (code == 1) {
-                    this.$message.success("发布成功");
-                    setTimeout(() => {
-                        this.$router.go(-1)
-                    }, 1000);
-                }
-            })
-        }
-    }
-};
-</script>
-
-<style lang="scss">
-.box {
-    .el-switch__core {
-        width: 30px !important;
-        height: 16px;
-    }
-
-    .el-switch__core::after {
-        width: 14px;
-        height: 14px;
-        margin-top: -1px;
-    }
-
-    .el-switch.is-checked .el-switch__core::after {
-        margin-left: -15px;
-    }
-}
-</style>
-<style scoped="scoped" lang="scss">
-.oneLine {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-.box {
-    padding: 0 10px;
-    font-size: 14px;
-    background-color: #fff;
-    box-sizing: border-box;
-    border-radius: 4px;
-
-    /* 设置滚动条的宽度和背景色 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
-        width: 10px;
-        height: 10px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-    }
-
-    /*头部样式*/
-    .header-content {
-        position: relative;
-        box-sizing: border-box;
-        height: 40px;
-        justify-content: space-between;
-
-        .header-left {
-            width: 230px;
-            box-sizing: border-box;
-            height: 40px;
-            cursor: pointer;
-            .item {
-                font-size: 16px;
-            }
-            .el-icon-arrow-left {
-                font-size: 22px;
-            }
-
-            &:hover {
-                .el-icon-arrow-left {
-                    background-color: #f5f7fa;
-                    color: #222;
-                }
-            }
-
-            .text {
-                font-size: 16px;
-                font-weight: 600;
-                padding-left: 50px;
-
-                &::before {
-                    position: absolute;
-                    content: '';
-                    width: 1px;
-                    height: 36px;
-                    background-color: #ebebeb;
-                    left: 44px;
-                    top: 50%;
-                    margin-top: -18px;
-                }
-            }
-
-        }
-
-        .header-right {
-            display: flex;
-            align-items: center;
-        }
-    }
-
-    .plus-button {
-        display: block;
-        margin: 10px auto;
-    }
-
-}
-</style>

+ 0 - 11
src/newPerformance/components/IndicatorSetting/TemplateMixedPublish.vue

@@ -37,15 +37,6 @@
               <el-date-picker v-model="year" type="year" value-format="yyyy" placeholder="选择年" :key="2" />
             </el-form-item>
 
-            <el-form-item v-if="publishData.cycleType === '2' || publishData.cycleType === '3'" label="日期区间">
-              <SelectCircle :id="1" :dateParameter="dateParameter" :dateOptions="dateOptions" @confirm="dateConfirm">
-                <div class="flex-box-ce cursor">
-                  <div>{{ dateParameter.year }}</div>
-                  <div style="margin: 0 10px;">{{ dateParameter.name }}</div>
-                  <i class="el-icon-caret-bottom fontColorC"></i>
-                </div>
-              </SelectCircle>
-            </el-form-item>
 
             <el-form-item v-if="publishData.cycleType === '4'" label="选择月份" prop="month">
               <el-date-picker v-model="month" type="month" placeholder="月份" value-format="yyyy-MM" :key="3" />
@@ -174,7 +165,6 @@
 
 import Template from "@/examine/components/Template.vue";
 import moment from "moment/moment";
-import SelectCircle from '@/newPerformance/components/TemplateDetails/SelectCircle';
 import TargetSearch from "@/performance/views/assessManagement/TargetSearch";
 import TemplateSelector from "@/newPerformance/components/TemplateSelector.vue";
 import PerEmployeeSelector from "@/newPerformance/components/IndicatorSetting/PerEmployeeSelector.vue";
@@ -186,7 +176,6 @@ export default {
     TemplateSelector,
     TargetSearch,
     Template,
-    SelectCircle,
   },
   props: {
     activeIndex:{

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 197 - 426
src/newPerformance/components/IndicatorSetting/UploadPublish.vue


+ 100 - 52
src/newPerformance/components/IndicatorStore.vue

@@ -8,29 +8,38 @@
         <div style="height: 1px; background-color: #f1f1f1; margin: 10px 0;"></div>
         <el-alert class="bounce animated" type="warning" :title="alertTilte" :closable="false" show-icon
             style="width: 100%; margin-bottom: 10px;"></el-alert>
+        <el-switch v-model="isEdit" active-text="编辑模式(编辑模式下,双击单元格即可编辑)" inactive-text="浏览模式"
+            style="margin-bottom: 10px;"></el-switch>
         <div class="table-box">
 
-            <el-table v-loading="loading" :data="templateList.slice((page - 1) * pageSize, page * pageSize)"
-                :header-cell-style="{ background: '#f5f7fa' }" style="width: 100%; height: auto;">
-                <el-table-column prop="title" label="模板标题">
-                    <template slot-scope="scope">
-                        {{ scope.row.title || "模板名称" }}
+            <vxe-table ref="XTable" :data="templateList.slice((page - 1) * pageSize, page * pageSize)" max-height="600"
+                align="center" border stripe round :row-config="{ isCurrent: true, isHover: true }"
+                :scroll-y="{ enabled: true, gt: 10 }" :edit-config="editConfig" :edit-rules="validRules"
+                @edit-closed="handleEditClosed" >
+                <vxe-table-column field="title" title="指标" min-width="200" align="left" :edit-render="{
+                    name: 'input', attrs: { type: 'text' }, style: { textAlign: 'left' }
+                }">
+                    <template #default="{ row }">
+                        <div :class="[isEdit ? 'cursor-pointer' : '', row.title ? '' : 'color-red']">
+                            <span>{{ row.title || '未定义' }}</span>
+                        </div>
                     </template>
-                </el-table-column>
-                <el-table-column label="操作" width="200">
-                    <template slot-scope="scope">
-                        <el-link type="primary" @click="getDetails(scope.row.templateId)">编辑</el-link>
+                </vxe-table-column>
+
+                <vxe-column title="操作" width="200">
+                    <template #default="{ row }">
+                        <el-link type="primary" @click="getDetails(row.templateId)">编辑</el-link>
                         <el-popconfirm confirm-button-text='确定' cancel-button-text='不用了' icon="el-icon-info"
-                            icon-color="red" title="确定删除这个考核模板吗?" @confirm="confirmDelete(scope.row.templateId)"
+                            icon-color="red" title="确定删除这个考核模板吗?" @confirm="confirmDelete(row.templateId)"
                             @cancel="cancelDelete()">
                             <el-link slot="reference" type="danger">删除</el-link>
                         </el-popconfirm>
                     </template>
-                </el-table-column>
-            </el-table>
-            <div style="height: 50px;"></div>
+                </vxe-column>
+            </vxe-table>
 
         </div>
+        <div style="height: 50px;"></div>
 
         <div class="flex-box-ce" style="width: 100%; justify-content: center; height: 50px;">
             <el-pagination @current-change="handleCurrentChange" :current-page.sync="page" :page-size="pageSize"
@@ -43,11 +52,10 @@
 
 <script>
 import { mapGetters } from 'vuex';
-import Driver from 'driver.js';
-import 'driver.js/dist/driver.min.css';
 export default {
     data() {
         return {
+            isEdit: false,
             loading: false,
             templateId: "",
             templateList: [],
@@ -58,7 +66,25 @@ export default {
         }
     },
     computed: {
-        ...mapGetters(['user_info'])
+        ...mapGetters(['user_info']),
+        // 校验规则
+        validRules() {
+            const newobj = {};
+            newobj['title'] = [{ required: true, message: '必填项未填' }];
+            // this.tableColumns.forEach((item) => {
+
+            // });
+            return newobj;
+        },
+
+        editConfig() {
+            return (this.isEdit ? {
+                trigger: 'dblclick',
+                mode: 'cell',
+                autoFocus: true
+            } : { enabled: false })
+        }
+        
     },
     activated() {
         this.getTemplateList()
@@ -67,49 +93,36 @@ export default {
         this.getTemplateList()
     },
 
-    // mounted() {
-    //     this.$nextTick(() => {
-    //         this.startGuide()
-    //     })
-    // },
+    
 
     methods: {
 
-        startGuide() {
-            const steps = [
-                {
-                    element: '.dispose-left',
-                    popover: {
-                        title: '第一步',
-                        description: '这是第一个引导步骤',
-                        position: 'bottom'
-                    }
-                },
-                {
-                    element: '.template-box',
-                    popover: {
-                        title: '第二步',
-                        description: '这是第二个引导步骤',
-                        position: 'bottom'
+        handleEditClosed(e) {
+            if (!e) return
+            let prop = e.column.field
+            this.handleEditTitle(e.row[prop], e.row.templateId)
+        },
+
+        // 编辑模板标题
+        handleEditTitle(title, templateId) {
+            if (title !== null && title !== '') {
+                let url = `/performance/template/title/${this.user_info.site_id}`
+                this.$http.post(url, { templateId, title }).then(res => {
+                    if (res.code == 1) {
+                        // this.getTemplateList();
+                    } else {
+                        this.$message.error("修改失败")
                     }
-                }
-            ];
-
-            this.driver = new Driver({
-                doneBtnText: '完成',
-                animate: true,
-                stageBackground: '#ffffff',
-                nextBtnText: '下一步',
-                prevBtnText: '上一步',
-                closeBtnText: '关闭'
-            });
-            this.driver.defineSteps(steps);
-            this.driver.start();
+                })
+            }
         },
+
+        
         
         chooseTemplate(item) {
             this.templateId = item.templateId
         },
+
         getTemplateList() {
             this.loading = true
             this.$axiosUser("get", `/performance/template/list/${this.user_info.site_id}`).then(res => {
@@ -135,9 +148,11 @@ export default {
 
         // 确认删除模板
         confirmDelete(templateId) {
+            console.log("删除模板", templateId )
             this.$axiosUser('post', `/performance/template/remove/${this.user_info.site_id}/${templateId}`).then(res => {
-                this.$axiosUser("get", `/performance/template/list/self/${this.user_info.site_id}`).then(res => {
+                this.$axiosUser("get", `/performance/template/list/${this.user_info.site_id}`).then(res => {
                     this.templateList = res.data.data.list
+                    this.total = this.templateList.length
                 })
             })
         },
@@ -161,7 +176,41 @@ export default {
 
 </script>
 
+<style lang="scss">
+.all {
+    .el-switch__core {
+        width: 30px !important;
+        height: 16px;
+    }
+
+    .el-switch__core::after {
+        width: 14px;
+        height: 14px;
+        margin-top: -1px;
+    }
+
+    .el-switch.is-checked .el-switch__core::after {
+        margin-left: -15px;
+    }
+}
+</style>
+
 <style scoped lang="scss">
+
+.color-red {
+    color: #F56C6C;
+}
+
+.cursor-pointer {
+    display: flex !important;
+    text-align: left !important;
+
+    &:hover {
+        cursor: pointer;
+        color: #409eff;
+    }
+}
+
     .all {
         width: 100%;
         height: 100%;
@@ -185,7 +234,6 @@ export default {
         .table-box {
             flex: 1;
             width: 100%;
-            overflow-y: auto;
 
             /* 设置滚动条的宽度和背景色 */
             &::-webkit-scrollbar {

+ 1 - 4
src/newPerformance/components/LevelSetting.vue

@@ -16,6 +16,7 @@
     </div>
 </template>
 
+
 <script>
 import ClassSet from '@/performance/components/public/ClassSet';
 export default {
@@ -25,10 +26,6 @@ export default {
         return {
             loading: false,
             isActive: 2,
-            ruleForm: {
-                region: 'shanghai',
-                delivery: true
-            },
             rules: {},
             inputs: [],//分值区间
             level_enable: true,//是否开启绩效等级

+ 309 - 107
src/newPerformance/components/MyPerformance.vue

@@ -61,14 +61,19 @@
             </div>
 
         </div>
-
+        
 
         <!-- 考核详情 -->
         <div class="table-box" v-if="detailInfo">
             <el-table v-loading="loading" ref="dragTable" :data="tableData" row-key="reviewIndicatorId" stripe
-                style=" width: 100%; height: auto;" border :header-cell-style="{ background: '#f5f7fa' }">
+                style=" width: 100%; height: auto;" border :header-cell-style="{ background: '#f5f7fa' }"
+                :row-style="rowStyle">
                 <el-table-column type="index" label="序号" align="center" width="50"></el-table-column>
                 <el-table-column prop="title" label="指标" align="center" min-width="200">
+                    <template slot-scope="scope">
+                        <span v-if="scope.row.ccFlag" class="cc-flag">抄送</span>
+                        <span class="oneLine">{{ scope.row.title || '--' }}</span>
+                    </template>
                 </el-table-column>
                 <el-table-column prop="target" label="目标" align="center" min-width="100">
                     <template slot-scope="scope">
@@ -97,6 +102,7 @@
                     </template>
                 </el-table-column>
 
+
                 <el-table-column prop="weight" label="权重(%)" align="center" min-width="80">
                     <template slot-scope="scope">
                         {{ scope.row.weight || '--' }}
@@ -114,16 +120,15 @@
 
                 <el-table-column prop="expression" label="计算公式" align="center" min-width="140">
                     <template slot-scope="scope">
-                        <el-link type="primary"
-                            v-if="scope.row.expression && scope.row.expression.formulas && scope.row.expression.formulas.length > 0"
+                        <el-link type="primary" v-if="filterFormulas(scope.row.expression) > 0"
                             @click="openFormula(scope.row, scope.$index)">
-                            {{ scope.row.expression && scope.row.expression.formulas.length > 0 ? `公式
-                            ${scope.row.expression.formulas.length} 条` : '公式' }}
+                            公式{{ filterFormulas(scope.row.expression) }}条
                         </el-link>
                         <div v-else style="color: #999;">暂无公式</div>
                     </template>
                 </el-table-column>
 
+
                 <el-table-column prop="score" label="最终评分" align="center" min-width="100">
                     <template slot-scope="scope">
                         <div>{{ scope.row.score || '--' }}</div>
@@ -150,31 +155,35 @@
 
                 <el-table-column prop="okrs" label="过程管控" align="center">
                     <template slot-scope="scope">
-                        <el-link v-if="scope.row.okrs && scope.row.okrs.length > 0" type="primary"
-                            @click="openTargetList(scope.row.okrs)">
+                        <el-link
+                            v-if="scope.row.okrs && scope.row.okrs.length > 0 || scope.row.plans && scope.row.plans.length > 0"
+                            type="primary" @click="openTargetList(scope.row.reviewIndicatorId)">
                             过程跟踪
                         </el-link>
                         <span v-else class="fontColorC">暂无关联</span>
                     </template>
                 </el-table-column>
 
-                <el-table-column label="操作" align="center" min-width="150">
+                <el-table-column label="操作" align="center">
                     <template slot-scope="scope">
-                        <el-link type="primary" style="margin-right: 10px;"
-                            @click="getProcessTracing({ reviewId: scope.row.reviewId, nodes: scope.row.flow.nodes, reviewIndicatorId: scope.row.reviewIndicatorId })">
-                            审批过程
-                        </el-link>
-                        <el-popover v-if="allowResetIndicator" ref="popoverRef" placement="bottom" trigger="click">
+
+                        <el-popover ref="popoverRef" placement="bottom" trigger="click">
                             <template #reference>
-                                <el-link v-if="allowResetIndicator" slot="reference" type="primary">更多操作</el-link>
+                                <el-link slot="reference" type="primary">更多操作</el-link>
                             </template>
                             <div class="dropdown-box">
-                                <el-link
+                                <el-link style="margin-bottom: 10px;" type="primary"
+                                    @click="getProcessTracing({ reviewId: scope.row.reviewId, nodes: scope.row.flow.nodes, reviewIndicatorId: scope.row.reviewIndicatorId })">
+                                    审批过程
+                                </el-link>
+                                <el-link style="margin-bottom: 10px;"
                                     v-if="allowResetIndicator && scope.row.businessStatus !== 'target_confirm' && allowResetIndicator && scope.row.businessStatus !== 'end'"
                                     type="primary" @click="openResetNodeDialog(scope.row)">重置流程</el-link>
 
-                                <el-link v-if="allowDeleteIndicator && scope.row.businessStatus == 'end'" type="primary"
-                                    @click="openVerifyDialog(scope.row, 'handleReStart')">重新发起</el-link>
+                                <el-link v-if="allowEditOkrs" type="primary" style="margin-bottom: 10px;"
+                                    @click="openTargetBindingDialog(scope.row, scope.$index)">绑定okr数据</el-link>
+                                <el-link v-if="allowDeleteIndicator" type="primary" style="margin-bottom: 10px;"
+                                    @click="openIndicatorDetail(scope.row)">重新发布</el-link>
 
                                 <el-link v-if="allowDeleteIndicator" type="danger"
                                     @click="openVerifyDialog(scope.row, 'handleDeleteIndicator')">删除指标</el-link>
@@ -203,15 +212,65 @@
         </div>
 
         <!-- 编辑计算公式 -->
-        <!-- <FormulaComp v-if="currentIndicator" v-model="showFormula"
-            :fixed-props="[{ key: 'target', name: '目标' }, { key: 'weight', name: '权重' }, { key: 'result', name: '结果值' }]"
-            :expressions-props="currentIndicator.expression.formulas || []" :is-edit="false"
-            @onConfirm="onFormulaConfirm" /> -->
+        <!-- 
+            <FormulaComp v-if="currentIndicator" v-model="showFormula"
+                :fixed-props="[{ key: 'target', name: '目标' }, { key: 'weight', name: '权重' }, { key: 'result', name: '结果值' }]"
+                :expressions-props="currentIndicator.expression.formulas || []" :is-edit="false"
+                @onConfirm="onFormulaConfirm" /> 
+        -->
+
+
 
         <el-dialog :visible.sync="showFormula" append-to-body :close-on-press-escape="true" center width="600px"
             title="计算公式">
-            <div>
-                <div class="formulas-list-box">
+            <div class="scroll-bar" style="max-height: 400px; overflow-y: auto;">
+
+                <el-descriptions :column="1" size="small" border>
+
+                    <template v-for="(item, index) in formulas">
+                        <el-descriptions-item :key="index">
+                            <template slot="label">
+                                公式{{ index + 1 }}
+                            </template>
+                        </el-descriptions-item>
+                        <el-descriptions-item :key="index">
+                            <template slot="label">
+                                触发条件
+                            </template>
+                            <div class="value-box"
+                                v-if="item.condition[0] === '1' && item.condition[1] === '==' && item.condition[2] === '1'">
+                                <div class="special-value">无触发条件</div>
+                            </div>
+                            <div v-else class="value-box">
+                                <template v-for="(con, conIndex) in item.condition">
+                                    <div class="special-value" v-if="con.toString().includes('result')">结果值</div>
+                                    <div class="special-value" v-else-if="con.toString().includes('weight')">权重</div>
+                                    <div class="special-value" v-else-if="con.toString().includes('target')">目标值</div>
+                                    <div class="normal-value" v-else>{{ con }}</div>
+                                </template>
+                            </div>
+                        </el-descriptions-item>
+
+
+                        <el-descriptions-item :key="index">
+                            <template slot="label">
+                                计算公式
+                            </template>
+                            <div class="value-box">
+                                <template v-for="(expr, exprIndex) in item.expression">
+                                    <div class="special-value" v-if="expr.toString().includes('result')">结果值</div>
+                                    <div class="special-value" v-else-if="expr.toString().includes('weight')">权重</div>
+                                    <div class="special-value" v-else-if="expr.toString().includes('target')">目标值</div>
+                                    <div class="normal-value" v-else>{{ expr }}</div>
+                                </template>
+                            </div>
+                        </el-descriptions-item>
+                    </template>
+                </el-descriptions>
+
+
+
+                <!-- <div class="formulas-list-box">
                     <div class="formulas-list" v-for="(item, index) in formulas" :key="index">
                         <div class="formulas-title">公式({{ index + 1 }})</div>
                         <div class="formulas-condition-title">触发条件</div>
@@ -239,7 +298,7 @@
                             </template>
                         </div>
                     </div>
-                </div>
+                </div> -->
             </div>
         </el-dialog>
 
@@ -247,9 +306,9 @@
         <SelectExamineComp v-if="dialogVisible" v-model="dialogVisible" @chooseExamine="choosePerformItem" />
 
         <!-- 关联OKR -->
-        <TargetListComp v-if="targetDialogVisible" :dialogVisible="targetDialogVisible" :ids="okrs"
-            @close="closeTargetList">
-        </TargetListComp>
+        <TargetPlanComp v-if="targetDialogVisible" :dialogVisible="targetDialogVisible"
+            :reviewIndicatorId="reviewIndicatorId" @close="closeTargetList">
+        </TargetPlanComp>
 
         <!-- 展示节点处理数据 -->
         <ShowHandlerComp v-if="showData" v-model="showHandlerDialogVisible" :show-data="showData" />
@@ -265,13 +324,17 @@
 
         <!-- 添加指标 -->
         <AddIndicatorDialog v-model="addIndicatorDialogVisible" :reviewId="logReviewId" :indicator-info="tableData"
-            @finished="getDetails(logReviewId)">
+            :selectedIndicatorInfo="selectedIndicatorInfo" @finished="getDetails(logReviewId)">
         </AddIndicatorDialog>
 
         <!-- 验证弹框 -->
         <!-- <VerifyDialog v-model="verifyDialogVisible" @success="verifySuccess" @error="verifyError" /> -->
 
         <Vcode :show="verifyDialogVisible" @success="verifySuccess" @close="verifyError" />
+
+        <!--  指标okr选择  -->
+        <TargetSearch :visible.sync="showIndicatorTargetSearch" :selectedOkrs="indicatorOkrs"
+            :selectedPlans="indicatorPlans" :key="`indicatorTarget`" @confirm="onIndicatorOkrSelected" />
     </div>
 </template>
 
@@ -284,12 +347,13 @@ import ShowHandlerComp from '@/newPerformance/components/PublicComp/ShowHanderDi
 import FormulaComp from '@/newPerformance/components/TemplateDetails/FormulaComp'; // 计算公式弹框
 import SelectExamineComp from '@/newPerformance/components/MyPerformance/SelectExamine'; // 选择考核列表弹框
 import TargetListComp from "@/performance/views/assessManagement/TargetListComp.vue"; // okr列表
+import TargetPlanComp from "@/newPerformance/components/PublicComp/TargetPlanComp.vue"; // okr列表
 import ExamineLogDialog from '@/newPerformance/components/MyPerformance/ExamineLog'; // 考核日志
 import ResetNodeDialog from '@/newPerformance/components/MyPerformance/ResetNode'; // 重置流程
 import AddIndicatorDialog from '@/newPerformance/components/MyPerformance/AddIndicator'; // 添加指标
 import VerifyDialog from '@/newPerformance/components/PublicComp/VerifyDialog'; // 验证码
-import Sortable from 'sortablejs';
 import Vcode from "vue-puzzle-vcode";
+import TargetSearch from "@/performance/views/assessManagement/TargetSearch";
 
 export default {
     name: "MyPerformance",
@@ -298,11 +362,13 @@ export default {
         FormulaComp,
         SelectExamineComp,
         TargetListComp,
+        TargetPlanComp,
         AddIndicatorDialog,
         ExamineLogDialog,
         ResetNodeDialog,
         VerifyDialog,
-        Vcode
+        Vcode,
+        TargetSearch
     },
     props: {
         reviewId: {
@@ -314,12 +380,16 @@ export default {
             default: ''
         },
     },
+
     data() {
         return {
             isCreator: this.$supremeAuthority('creator'), // 创始人,总经理
             getRole1: this.$getRole(1), // 绩效主管理员,子管理员
             getRole2: this.$getRole(2), // 部门管理员
             getRole3: this.$getRole(3), // 员工
+            showIndicatorTargetSearch: false, // 显示指标okr选择
+            indicatorOkrs: [],
+            indicatorPlans: [],
             fileUrl: "",
             isShow: false,
             dialogVisible: false,
@@ -387,6 +457,7 @@ export default {
                     }
                 }]
             },
+            reviewIndicatorId: '',
             date: [],
             performList: [],
             tableData: [],
@@ -398,10 +469,13 @@ export default {
             resetNodeDialogVisible: false,// 重置流程弹框
             logReviewId: '',
             initRow: null,
-            handleOptions: ''
+            handleOptions: '',
+            selectedIndicatorInfo: {},
+            indicatorIndex: 0
         };
     },
     filters: {
+
         filterNodeStatus(v) {
             // 指标审批状态 
             // start - 开始 
@@ -423,10 +497,12 @@ export default {
             if (v === 'cc') return '抄送'
             if (v === 'end') return '结束'
         },
+
         formatDate(val) {
             if (val) return moment(val).format('YYYY-MM-DD')
             else return "--"
         },
+        
         formatDeptName(val) {
             let str = '';
             if (val && val.length > 0) {
@@ -452,13 +528,13 @@ export default {
 
         // 允许添加指标
         allowAddIndicator() {
-            if (this.isCreator|| this.getRole1) return true
+            if (this.isCreator || this.getRole1) return true
             else return false
         },
 
         // 允许删除指标,重新发起这个指标的考核
         allowDeleteIndicator() {
-            if (this.isCreator || this.getRole1 ) return true
+            if (this.isCreator || this.getRole1) return true
             else return false
         },
 
@@ -468,6 +544,12 @@ export default {
             else return false
         },
 
+        // 被考核人 主管理员,子管理员可以修改 绑定的OKR,计划
+        allowEditOkrs() {
+            let isSelf = this.selectedIndicatorInfo && this.selectedIndicatorInfo.employeeId == this.user_info.id
+            return (this.isCreator || this.getRole1 || isSelf)
+        },
+
     },
 
     created() {
@@ -486,10 +568,10 @@ export default {
         } else {
             this.getTemplateList();
         }
-        this.$nextTick(() => {
-            this.initSortTable();
-        })
-        
+        // this.$nextTick(() => {
+        //     this.initSortTable();
+        // })
+
     },
 
     beforeDestroy() {
@@ -497,42 +579,90 @@ export default {
     },
 
     
+
     methods: {
+        onIndicatorOkrSelected(okrs, data) {
+            this.indicatorOkrs = okrs;
+            this.indicatorPlans = data;
+            this.bindingData();
+            this.showIndicatorTargetSearch = false;
+        },
 
-        initSortTable() {
-            const elTbody = this.$refs.dragTable && this.$refs.dragTable.$el.querySelector('.el-table__body-wrapper tbody');
-            if (!elTbody) return
-            this.sortable = Sortable.create(elTbody, {
-                delay: 0,
-                animation: 300,
-                onEnd: (evt) => {
-                    const currRow = this.tableData.splice(evt.oldIndex, 1)[0];
-                    this.tableData.splice(evt.newIndex, 0, currRow);
-                    this.$nextTick(() => {
-                        this.tableData.forEach((item, index) => {
-                            item.id = index + 1;
-                        });
-                    });
+        bindingData() {
+            // 绑定数据
+            let url = `/performance/statistics/okrs/bind/indicator/${this.user_info.site_id}/${this.selectedIndicatorInfo.reviewIndicatorId}`
+            let data = {
+                oids: [...this.indicatorOkrs, ...this.indicatorPlans].toString(),
+                planIds: this.indicatorPlans.toString(),
+            }
+            this.$http.post(url, data).then(res => {
+                let { code, message } = res
+                if (code == 1) {
+                    this.selectedIndicatorInfo.okrs = this.indicatorOkrs;
+                    this.selectedIndicatorInfo.plans = this.indicatorPlans;
+                    this.tableData.splice(this.indicatorIndex, 1, this.selectedIndicatorInfo); //替换元素
+                    this.$message.success('绑定成功');
+                } else {
+                    this.$message.error(message || '绑定失败');
                 }
             });
         },
 
+        
+
+        openTargetBindingDialog(row, index) {
+            let { okrs, plans } = row
+            this.indicatorIndex = index
+            this.selectedIndicatorInfo = row;
+            this.indicatorOkrs = okrs;
+            this.indicatorPlans = plans;
+            this.showIndicatorTargetSearch = true;
+        },
+
+        rowStyle({ row }) {
+            return { background: row.ccFlag ? '#ecf5ff' : '', fontWeight: row.ccFlag ? 'bold' : '' }
+        },
+
+        /* 开启 dialog 时:禁用返回键 */
+        onDialogOpen() {
+            // 立即往 history 里插一条空记录,拦截返回
+            history.pushState(null, null, location.href);
+            // 监听 popstate
+            window.addEventListener('popstate', this.blockPopstate, false);
+        },
+
+
+        /* 拦截浏览器返回键 */
+        blockPopstate(e) {
+            // 阻止默认返回行为
+            e.preventDefault();
+            // 可以选择关闭 dialog
+            this.targetDialogVisible = false;
+            // 重新插入一条记录,防止再次返回
+            history.pushState(null, null, location.href);
+        },
+
+        openIndicatorDetail(row) {
+            let { title, unit, content, target, weight, okrs, plans, expression, flow, reviewIndicatorId } = row
+            this.selectedIndicatorInfo = { title, unit, content, target, weight, okrs, plans, expression, flow, reviewIndicatorId };
+            this.addIndicatorDialogVisible = true;
+        },
+
+        filterFormulas(v) {
+            let formulas = v.formulas
+            let sum = 0
+            if (formulas && formulas.length > 0) {
+                if (formulas) {
+                    formulas.forEach(item => {
+                        if (item.expression && item.expression.length > 0) {
+                            sum += 1
+                        }
+                    })
+                }
+            }
+            return sum
+        },
 
-        // // 行拖拽
-        // rowDrop() {
-        //     // 要侦听拖拽响应的DOM对象(数据存储在.el-table__body-wrapper > .el-table__row > tbody标签中(el-table的数据部分的“最外层”class名为el-table__body-wrapper))
-        //     const tbody = document.querySelector('.el-table__body-wrapper tbody');
-        //     const that = this;
-        //     if (!tbody) return
-        //     Sortable.create(tbody, {
-        //         // 结束拖拽后的回调函数
-        //         onEnd({ newIndex, oldIndex }) {
-        //             console.log('拖动了行,序号(index)"' + oldIndex + '"拖动到序号(index)"' + newIndex + '"');
-        //             const currentRow = that.tableData.splice(oldIndex, 1)[0]; // 将oldIndex位置的数据删除并取出,oldIndex后面位置的数据会依次前移一位
-        //             that.tableData.splice(newIndex, 0, currentRow); // 将被删除元素插入到新位置(currRow表示上面的被删除数据)
-        //         }
-        //     })
-        // },
 
 
         changePage() {
@@ -562,20 +692,22 @@ export default {
             }
         },
 
+
+
         // 删除考核
         deleteExamine() {
             let url = `/performance/review/remove/${this.user_info.site_id}/${this.logReviewId}`
             this.$http.post(url).then(res => {
                 this.verifyDialogVisible = false
                 if (res.code == 1) {
-                    this.$message.success("操作成功")
+                    this.$message.success("操作成功");
+                    this.getTemplateList()
+                    this.$emit("hasDeleteExamine")
                 } else {
                     this.$message.error("操作失败")
                 }
             })
         },
-
-
         // 过程跟踪
         getProcessTracing(row) {
             this.showData = row;
@@ -590,7 +722,9 @@ export default {
 
         // 添加指标
         openAddIndicatorDialog(row) {
-            this.initRow = row
+            // console.log("添加指标", row)
+            // this.initRow = row
+            this.selectedIndicatorInfo = {};
             this.addIndicatorDialogVisible = true;
         },
 
@@ -608,7 +742,7 @@ export default {
                     }
                     this.verifyDialogVisible = false
                 })
-            // 重新发起
+                // 重新发起
             } else {
                 let url = `/performance/review/indicator/repost/${this.user_info.site_id}/${row.reviewId}/${row.reviewIndicatorId}`
                 this.$http.post(url).then(res => {
@@ -624,9 +758,9 @@ export default {
         },
 
         // 取消操作
-        handleCancel() {},
+        handleCancel() { },
+
 
-        
         handleChange(value) {
             if (value[1]) this.getDetails(value[1]);
         },
@@ -636,18 +770,24 @@ export default {
             this.getDetails(item.reviewId)
         },
 
+        // 打开验证弹框
         openVerifyDialog(row, options) {
             this.initRow = row
             this.handleOptions = options
             this.verifyDialogVisible = true;
         },
 
+        
+
         verifySuccess(msg) {
             // console.log("用户通过了验证")
+            // 重新发起指标的考核
             if (this.handleOptions === 'handleReStart') this.handleConfirm(this.initRow, 1)
+            // 删除指标
             if (this.handleOptions === 'handleDeleteIndicator') this.handleConfirm(this.initRow, 2)
+            // 删除考核
             if (this.handleOptions === 'deleteExamine') this.deleteExamine()
-            
+
         },
 
         verifyError() {
@@ -683,7 +823,7 @@ export default {
             this.$axiosUser('get', url).then(res => {
                 let { data: { title, indicators, levelName, startTime, endTime, cycleType, score, status }, code } = res.data
                 if (code == 1) {
-                    
+
                     this.detailInfo = res.data.data;
                     this.title = title || ''
                     this.cycleType = cycleType || ''
@@ -734,10 +874,12 @@ export default {
         // 打开计算公式弹框
         openFormula(row, index) {
             this.currentIndicator = row;
-            this.formulas = row.expression.formulas
+            this.formulas = row.expression.formulas;
             this.showFormula = true;
         },
 
+
+
         onFormulaConfirm() { },
 
         changeShow() {
@@ -750,20 +892,21 @@ export default {
             this.targetDialogVisible = false
         },
 
-        openTargetList(okrs) {
-            if (okrs && okrs.length > 0) {
-                this.okrs = okrs
-                this.targetDialogVisible = true
-            }
-            else {
-                return this.$message.error("暂无关联okr")
-            }
-        }
+        openTargetList(reviewIndicatorId) {
+            this.reviewIndicatorId = reviewIndicatorId;
+            this.targetDialogVisible = true
+            this.onDialogOpen();
+        },
+        
     }
 };
 </script>
 
+
+
 <style lang="scss">
+
+
 .performance {
     .el-switch__core {
         width: 30px !important;
@@ -789,7 +932,6 @@ export default {
 </style>
 
 <style scoped="scoped" lang="scss">
-
 .vue-puzzle-vcode {
     z-index: 99999;
 }
@@ -832,6 +974,7 @@ export default {
     z-index: 10;
     margin: 10px 0 10px auto;
     box-sizing: border-box;
+
     .status-btn-green {
         width: 100%;
         height: 100%;
@@ -842,6 +985,7 @@ export default {
         font-size: 20px;
         height: 36px;
     }
+
     .status-btn-orange {
         width: 100%;
         height: 100%;
@@ -854,6 +998,33 @@ export default {
     }
 }
 
+.value-box {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    overflow: hidden;
+    font-size: 12px;
+
+    div {
+        margin: 0 0 3px 3px;
+    }
+}
+
+.special-value {
+    display: inline-block;
+    padding: 3px;
+    border: 1px solid #409eff;
+    color: #409eff;
+    margin-right: 5px;
+    border-radius: 4px;
+}
+
+.normal-value {
+    font-size: 14px;
+    letter-spacing: 2px;
+    margin: 0 3px;
+}
+
 
 .formulas-list-box {
     width: 100%;
@@ -861,8 +1032,10 @@ export default {
     box-sizing: border-box;
     background-color: #f7f7f7;
     border-radius: 4px;
+
     .formulas-list {
         margin-bottom: 20px;
+
         .formulas-title {
             font-size: 18px;
             font-weight: 500;
@@ -870,27 +1043,14 @@ export default {
             padding: 5px;
             box-sizing: border-box;
         }
+
         .formulas-condition-title {
             font-size: 16px;
             font-weight: 400;
             margin-bottom: 5px;
         }
-        .value-box {
-            display: flex;
-            align-items: center;
-        }
-        .special-value {
-            display: inline-block;
-            padding: 3px;
-            border: 1px solid #409eff;
-            color: #409eff;
-            border-radius: 4px;
-        }
-        .normal-value {
-            font-size: 14px;
-            letter-spacing: 2px;
-            margin: 0 3px;
-        }
+
+        
     }
 }
 
@@ -916,14 +1076,16 @@ export default {
         padding: 0 10px;
         box-sizing: border-box;
         position: relative;
+
         .back {
             position: absolute;
             top: 20px;
             left: 10px;
+
             .el-icon-arrow-left {
                 font-size: 18px;
             }
-        
+
             &:hover {
                 .el-icon-arrow-left {
                     background-color: #f5f7fa;
@@ -931,6 +1093,7 @@ export default {
                 }
             }
         }
+
         .perform-title {
             width: 100%;
             height: 50px;
@@ -982,6 +1145,9 @@ export default {
                     line-height: 40px;
                     text-align: center;
                     background: #fff;
+                    text-overflow: ellipsis;
+                    overflow: hidden;
+                    white-space: nowrap;
                 }
             }
         }
@@ -1009,6 +1175,7 @@ export default {
         justify-content: space-between;
         color: #999;
         background-color: #fff;
+
         .more {
             &:hover {
                 cursor: pointer;
@@ -1048,8 +1215,45 @@ export default {
             border-radius: 6px;
             background: #ededed;
         }
+
+        /deep/ .el-table__body-wrapper {
+            /* 设置滚动条的宽度和背景色 */
+            &::-webkit-scrollbar {
+                width: 6px;
+                height: 6px;
+                background-color: #f9f9f9;
+            }
+        
+            /* 设置滚动条滑块的样式 */
+            &::-webkit-scrollbar-thumb {
+                border-radius: 6px;
+                background-color: #c1c1c1;
+            }
+        
+            /* 设置滚动条滑块hover样式 */
+            &::-webkit-scrollbar-thumb:hover {
+                background-color: #a8a8a8;
+            }
+        
+            /* 设置滚动条轨道的样式 */
+            &::-webkit-scrollbar-track {
+                box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
+                border-radius: 4px;
+                background: #ededed;
+            }
+        }
+
+        .cc-flag {
+            border: 1px solid #e6a23c;
+            color: #e6a23c;
+            font-size: 12px;
+            padding: 3px;
+            border-radius: 4px;
+            box-sizing: border-box;
+        }
     }
 
+
     .no-data-box {
         width: 100%;
         height: 100%;
@@ -1057,6 +1261,7 @@ export default {
         background-color: #fff;
         box-sizing: border-box;
         border-radius: 4px;
+
         img {
             width: 200px;
             height: 200px;
@@ -1064,7 +1269,4 @@ export default {
         }
     }
 }
-
-
-
 </style>

+ 0 - 822
src/newPerformance/components/MyPerformance/AddIndicator copy.vue

@@ -1,822 +0,0 @@
-<template>
-    <el-dialog title="添加指标" :visible.sync="addIndicatorDialogVisible" width="700px" :before-close="dialogBeforeClose"
-        append-to-body @open="initNodes()">
-        <div>
-
-            <div v-loading="loading" class="scroll-bar" style="max-height: 500px; overflow-y: auto;">
-                <el-form ref="form" :model="form" label-width="80px">
-
-                    <el-form-item label="指标名称" prop="title">
-                        <el-input v-model="form.title" placeholder="指标名称" clearable></el-input>
-                    </el-form-item>
-
-                    <el-form-item label="指标规则">
-                        <el-link type="primary" @click="showEditContent = true">
-                            {{ form.content ? form.content : '点击设置指标规则' }}
-                        </el-link>
-                    </el-form-item>
-
-                    <el-form-item label="过程跟踪">
-                        <template v-if="form.okrs && form.okrs.length > 0">
-                            <div class="okr-list-box">
-                                <div class="edit-box">
-                                    <el-link type="primary" @click="showIndicatorTargetSearch = true">
-                                        <i class="el-icon-edit"></i>
-                                    </el-link>
-                                </div>
-                                <div class="okr-list-title">
-                                    <el-link type="primary">
-                                        共 {{ form.okrs.length }} 个目标
-                                    </el-link>
-                                </div>
-                                <div class="okr-list">
-                                    <div v-for="item in indicatorOkrs" :key="item.id">
-                                        {{ item.name }}
-                                    </div>
-                                </div>
-
-                            </div>
-
-                        </template>
-                        <el-link v-else type="primary" @click="showIndicatorTargetSearch = true">
-                            {{ '点击设置关联OKR' }}
-                        </el-link>
-                    </el-form-item>
-
-                    <el-form-item label="目标值" prop="target">
-                        <el-input v-model="form.target" placeholder="目标值" clearable></el-input>
-                    </el-form-item>
-
-                    <el-form-item label="单位" prop="unit">
-                        <el-input v-model="form.unit" placeholder="单位" clearable></el-input>
-                    </el-form-item>
-
-                    <el-form-item label="权重(%)" prop="weight">
-                        <el-input v-model="form.weight" placeholder="权重(%)" clearable></el-input>
-                    </el-form-item>
-
-                    <el-form-item label="计算公式">
-
-                        <template v-if="form.expression.formulas && form.expression.formulas.length > 0">
-                            <div class="formulas-list-box">
-                                <div class="edit-box">
-                                    <el-link type="primary" @click="showFormula = true">
-                                        <i class="el-icon-edit"></i>
-                                    </el-link>
-                                </div>
-                                <div class="formulas-list" v-for="(item, index) in form.expression.formulas"
-                                    :key="index">
-                                    <div class="formulas-title">公式({{ index + 1 }})</div>
-                                    <div class="formulas-condition-title">触发条件</div>
-                                    <div class="value-box">
-                                        <template v-for="(con, conIndex) in item.condition">
-                                            <div class="special-value" v-if="con === '#result'">结果值</div>
-                                            <div class="special-value" v-else-if="con === '#weight'">权重</div>
-                                            <div class="special-value" v-else-if="con === '#target'">目标值</div>
-                                            <div class="normal-value" v-else>{{ con }}</div>
-                                        </template>
-                                    </div>
-                                    <div class="formulas-condition-title">计算公式</div>
-                                    <div class="value-box">
-                                        <template v-for="(expr, exprIndex) in item.expression">
-                                            <div class="special-value" v-if="expr === '#result'">结果值</div>
-                                            <div class="special-value" v-else-if="expr === '#weight'">权重</div>
-                                            <div class="special-value" v-else-if="expr === '#target'">目标值</div>
-                                            <div class="normal-value" v-else>{{ expr }}</div>
-                                        </template>
-                                    </div>
-                                </div>
-                            </div>
-                        </template>
-
-                        <el-link v-else type="primary" @click="showFormula = true">点击设置计算公式</el-link>
-                    </el-form-item>
-
-                    <el-form-item label="确认目标">
-                        <el-switch v-if="!form.flow.nodes[0].enable" :value="form.flow.nodes[0].enable"
-                            @input="handleStatusChange(-1, form, 'targetConfirms')"></el-switch>
-                        <ShowDataComp v-else :show-data="form.flow.nodes[0]" :select-nodes="form"
-                            @btnClick="handleBtnClick" :compStyle="compStyle" />
-                    </el-form-item>
-
-                    <el-form-item label="录入结果">
-                        <el-switch v-if="!form.flow.nodes[1].enable" :value="form.flow.nodes[1].enable"
-                            @input="handleStatusChange(-1, form, 'resultInput')"></el-switch>
-                        <ShowDataComp v-else :show-data="form.flow.nodes[1]" :select-nodes="form"
-                            @btnClick="handleBtnClick" :compStyle="compStyle" />
-                    </el-form-item>
-
-                    <el-form-item label="自评">
-                        <el-switch v-if="!form.flow.nodes[2].enable" :value="form.flow.nodes[2].enable"
-                            @input="handleStatusChange(-1, form, 'scoreSelf')"></el-switch>
-                        <div v-else class="flex-box-ce">
-                            <el-switch v-if="form.flow.nodes[2].enable" :value="form.flow.nodes[2].enable"
-                                @input="handleStatusChange(-1, form, 'scoreSelf')"></el-switch>
-                        </div>
-                    </el-form-item>
-
-                    <el-form-item label="互评">
-                        <el-switch v-if="!form.flow.nodes[3].enable" :value="form.flow.nodes[3].enable"
-                            @input="handleStatusChange(-1, form, 'scoreEachOther')"></el-switch>
-                        <div v-else class="flex-box-ce">
-                            <el-switch v-if="form.flow.nodes[3].enable" :value="form.flow.nodes[3].enable"
-                                @input="handleStatusChange(-1, form, 'scoreEachOther')"></el-switch>
-                        </div>
-                    </el-form-item>
-
-                    <el-form-item label="评分">
-                        <el-switch v-if="!form.flow.nodes[4].enable" :value="form.flow.nodes[4].enable"
-                            @input="handleStatusChange(-1, form, 'scores')"></el-switch>
-                        <ShowDataComp v-else :show-data="form.flow.nodes[4]" :select-nodes="form"
-                            @btnClick="handleBtnClick" :compStyle="compStyle" />
-                    </el-form-item>
-
-                    <el-form-item label="审批">
-                        <el-switch v-if="!form.flow.nodes[5].enable" :value="form.flow.nodes[5].enable"
-                            @input="handleStatusChange(-1, form, 'reviews')"></el-switch>
-                        <ShowDataComp v-else :show-data="form.flow.nodes[5]" :select-nodes="form"
-                            @btnClick="handleBtnClick" :compStyle="compStyle" />
-                    </el-form-item>
-
-                </el-form>
-            </div>
-
-            <div slot="footer" class="flex-box-ce" style="justify-content: center;">
-                <el-button type="primary" @click="confirm()">确 定</el-button>
-                <el-button @click="cancel()">取 消</el-button>
-            </div>
-        </div>
-        
-        <!-- 编辑计算公式 -->
-        <FormulaComp v-if="showFormula" v-model="showFormula"
-            :fixed-props="[{ key: 'target', name: '目标' }, { key: 'weight', name: '权重' }, { key: 'result', name: '结果值' }]"
-            :expressions-props="form.expression.formulas || []" @onConfirm="onFormulaConfirm" />
-
-
-        <!-- 编辑规则 -->
-        <EditContentComp v-if="showEditContent" v-model="showEditContent" :content="form.content"
-            @finishEdit="finishEditContent" no-request />
-
-        <!-- 编辑确认目标节点 -->
-        <TargetConfirms v-if="targetConfirms" v-model="targetConfirms" :form-label="formLabel"
-            :dialog-title="dialogTitle" :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog"
-            :tag-index="tagIndex" @onConfirm="finishHandle" />
-
-        <!-- 编辑录入结果节点 -->
-        <ResultInput v-if="resultInput" v-model="resultInput" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑自评节点 -->
-        <ScoreSelf v-if="scoreSelf" v-model="scoreSelf" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑互评节点 -->
-        <ScoreEachOther v-if="scoreEachOther" v-model="scoreEachOther" :form-label="formLabel"
-            :dialog-title="dialogTitle" :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog"
-            :tag-index="tagIndex" @onConfirm="finishHandle" />
-
-        <!-- 编辑评分节点 -->
-        <Scores v-if="scores" v-model="scores" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
-            :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑审批节点 -->
-        <Reviews v-if="reviews" v-model="reviews" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑审批节点 -->
-        <CC v-if="cc" v-model="cc" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
-            :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 指标okr选择 -->
-        <TargetSearch :visible.sync="showIndicatorTargetSearch" :selectedCheckList="indicatorOkrs"
-            :showSelectedData="indicatorOkrs" :key="`indicatorTarget`" @confirm="onIndicatorOkrSelected" />
-    </el-dialog>
-
-</template>
-
-
-
-<script>
-import { mapGetters } from 'vuex';
-import TargetSearch from "@/performance/views/assessManagement/TargetSearch"; // 选择OKR
-import FormulaComp from '@/newPerformance/components/TemplateDetails/FormulaComp'; // 计算公式弹框
-import HandleNode from '@/newPerformance/components/TemplateDetails/HandleNode'; //单独设置流程节点弹框
-import ShowDataComp from '@/newPerformance/components/PublicComp/ShowData'; // 显示节点数据组件
-import EditContentComp from '@/newPerformance/components/TemplateDetails/EditContent'; // 编辑规则组件
-import BatchHandleNode from '@/newPerformance/components/TemplateDetails/BatchHandleNode'; // 批量设置流程节点
-import TargetConfirms from '@/newPerformance/components/TemplateDetails/TargetConfirms'; // 确认目标流程节点
-import ResultInput from '@/newPerformance/components/TemplateDetails/ResultInput'; // 结果录入流程节点
-import ScoreSelf from '@/newPerformance/components/TemplateDetails/ScoreSelf'; // 自评流程节点
-import ScoreEachOther from '@/newPerformance/components/TemplateDetails/ScoreEachOther'; // 互评流程节点
-import Scores from '@/newPerformance/components/TemplateDetails/Scores'; // 评分流程节点
-import Reviews from '@/newPerformance/components/TemplateDetails/Reviews'; // 审批流程节点
-import CC from '@/newPerformance/components/TemplateDetails/CC'; // 审批流程节点
-
-export default {
-    components: {
-        HandleNode,
-        ShowDataComp,
-        EditContentComp,
-        TargetSearch,
-        FormulaComp,
-        BatchHandleNode,
-        TargetConfirms,
-        ResultInput,
-        ScoreSelf,
-        ScoreEachOther,
-        Scores,
-        Reviews,
-        CC
-    },
-
-    model: {
-        prop: 'addIndicatorDialogVisible',
-        event: 'close-dialog'
-    },
-
-    props: {
-        addIndicatorDialogVisible: {
-            type: Boolean,
-            default: false
-        },
-
-        reviewId: {
-            type: String | Number,
-            default: () => {}
-        }
-    },
-
-    computed: {
-        ...mapGetters(['user_info'])
-    },
-
-    data() {
-        return {
-            loading: false,
-            templateId: '',
-            selectIndicatorId: '',
-            selectNodes: '',
-            dialogTitle: '',
-            nodeType: '',
-            formLabel: '',
-            showFormula: false, // 编辑计算公式弹框显示
-            showEditContent: false, // 编辑指标内容弹框
-            showIndicatorTargetSearch: false, // 选择OKRS
-            targetConfirms: false,
-            resultInput: false,
-            scoreSelf: false,
-            scoreEachOther: false,
-            scores: false,
-            reviews: false,
-            cc: false,
-            compStyle: {
-                flexDirection: 'row',
-                alignItems: 'center',
-                justifyContent: 'flex-start'
-            },
-            indicatorOkrs: [],
-
-            tagIndex: 0,
-            form: {
-                title: "",
-                content: "",
-                target: "",
-                unit: "",
-                weight: "",
-                expression: {
-                    formulas: []
-                },
-                expandData: [],
-                flow:
-                {
-                    nodes: [
-                        {
-                            id: "",
-                            type: "targetConfirms",
-                            enable: false,
-                            assigneeType: "self",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [],
-                            weight: 0,
-                            children: [
-                                {
-                                    id: "",
-                                    type: "targetConfirm",
-                                    enable: true,
-                                    assigneeType: "self",
-                                    leaderLevel: 1,
-                                    assigneeIds: [],
-                                    multipleType: "or",
-                                    allows: [],
-                                    weight: 0,
-                                    children: []
-                                }
-                            ]
-                        },
-                        {
-                            id: "",
-                            type: "resultInput",
-                            enable: false,
-                            assigneeType: "self",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: []
-                        },
-                        {
-                            id: "",
-                            type: "scoreSelf",
-                            enable: false,
-                            assigneeType: "self",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: []
-                        },
-                        {
-                            id: "",
-                            type: "scoreEachOther",
-                            enable: false,
-                            assigneeType: "self",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "parallel",
-                            allows: [],
-                            weight: 0,
-                            children: []
-                        },
-                        {
-                            id: "",
-                            type: "scores",
-                            enable: true,
-                            assigneeType: "leader",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: [
-                                {
-                                    id: "",
-                                    type: "score",
-                                    enable: true,
-                                    assigneeType: "leader",
-                                    leaderLevel: 1,
-                                    assigneeIds: [],
-                                    multipleType: "or",
-                                    allows: [
-                                        "transfer"
-                                    ],
-                                    weight: 100,
-                                    children: []
-                                }
-                            ]
-                        },
-                        {
-                            id: "",
-                            type: "reviews",
-                            enable: false,
-                            assigneeType: "leader",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: [
-                                {
-                                    id: "",
-                                    type: "review",
-                                    enable: true,
-                                    assigneeType: "leader",
-                                    leaderLevel: 1,
-                                    assigneeIds: [],
-                                    multipleType: "or",
-                                    allows: [
-                                        "transfer"
-                                    ],
-                                    weight: 0,
-                                    children: []
-                                }
-                            ]
-                        },
-                        {
-                            id: "",
-                            type: "cc",
-                            enable: false,
-                            assigneeType: "user",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [],
-                            weight: 0,
-                            children: []
-                        }
-                    ]
-                },
-                employeeId: 0,
-                okrs: []
-            }
-        }
-    },
-
-    methods: {
-
-        initNodes() {
-            this.form.flow.nodes.forEach((item, index) => {
-                if (index == 0) {
-                    item.id = "TCS_" + Date.now() + Math.floor(Math.random() * 10000)
-                    item.children[0].id = "TC_" + Date.now() + Math.floor(Math.random() * 10000)
-                } 
-                if (index == 1) item.id = "RI_" + Date.now() + Math.floor(Math.random() * 10000)
-                if (index == 2) item.id = "SELF_" + Date.now() + Math.floor(Math.random() * 10000)
-                if (index == 3) item.id = "EO_" + Date.now() + Math.floor(Math.random() * 10000)
-                if (index == 4) {
-                    item.id = "SS_" + Date.now() + Math.floor(Math.random() * 10000)
-                    item.children[0].id = "S_" + Date.now() + Math.floor(Math.random() * 10000)
-                }
-                if (index == 5) {
-                    item.id = "RS_" + Date.now() + Math.floor(Math.random() * 10000)
-                    item.children[0].id = "R_" + Date.now() + Math.floor(Math.random() * 10000)
-                }
-                if (index == 6) item.id = "CC_" + Date.now() + Math.floor(Math.random() * 10000)
-            })
-
-            console.log(this.form)
-        },
-
-        clearFormData() {
-            this.indicatorOkrs = [];
-            this.loading = false
-            this.tagIndex = 0;
-            this.form = {
-                title: "",
-                content: "",
-                target: "",
-                unit: "",
-                weight: "",
-                expression: {
-                    formulas: []
-                },
-                expandData: [],
-                    flow:
-                    {
-                        nodes: [
-                            {
-                                id: "",
-                                type: "targetConfirms",
-                                enable: false,
-                                assigneeType: "self",
-                                leaderLevel: 1,
-                                assigneeIds: [],
-                                multipleType: "or",
-                                allows: [],
-                                weight: 0,
-                                children: [
-                                    {
-                                        id: "",
-                                        type: "targetConfirm",
-                                        enable: true,
-                                        assigneeType: "self",
-                                        leaderLevel: 1,
-                                        assigneeIds: [],
-                                        multipleType: "or",
-                                        allows: [],
-                                        weight: 0,
-                                        children: []
-                                    }
-                                ]
-                            },
-                        {
-                            id: "",
-                            type: "resultInput",
-                            enable: false,
-                            assigneeType: "self",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: []
-                        },
-                        {
-                            id: "",
-                            type: "scoreSelf",
-                            enable: false,
-                            assigneeType: "self",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: []
-                        },
-                        {
-                            id: "",
-                            type: "scoreEachOther",
-                            enable: false,
-                            assigneeType: "self",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "parallel",
-                            allows: [],
-                            weight: 0,
-                            children: []
-                        },
-                        {
-                            id: "",
-                            type: "scores",
-                            enable: true,
-                            assigneeType: "leader",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: [
-                                {
-                                    id: "",
-                                    type: "score",
-                                    enable: true,
-                                    assigneeType: "leader",
-                                    leaderLevel: 1,
-                                    assigneeIds: [],
-                                    multipleType: "or",
-                                    allows: [
-                                        "transfer"
-                                    ],
-                                    weight: 100,
-                                    children: []
-                                }
-                            ]
-                        },
-                        {
-                            id: "",
-                            type: "reviews",
-                            enable: false,
-                            assigneeType: "leader",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [
-                                "transfer"
-                            ],
-                            weight: 0,
-                            children: [
-                                {
-                                    id: "",
-                                    type: "review",
-                                    enable: true,
-                                    assigneeType: "leader",
-                                    leaderLevel: 1,
-                                    assigneeIds: [],
-                                    multipleType: "or",
-                                    allows: [
-                                        "transfer"
-                                    ],
-                                    weight: 0,
-                                    children: []
-                                }
-                            ]
-                        },
-                        {
-                            id: "",
-                            type: "cc",
-                            enable: false,
-                            assigneeType: "user",
-                            leaderLevel: 1,
-                            assigneeIds: [],
-                            multipleType: "or",
-                            allows: [],
-                            weight: 0,
-                            children: []
-                        }
-                    ]
-                },
-                employeeId: 0,
-                okrs: []
-            }
-        },
-
-        dialogBeforeClose() {
-            this.$emit('close-dialog', false)
-        },
-
-        // 编辑计算公式的回调
-        onFormulaConfirm(formulas) {
-            console.log("公式")
-            console.log(formulas)
-            this.form.expression.formulas = formulas
-            console.log(this.form.expression.formulas)
-        },
-
-
-        // 编辑指标规则
-        finishEditContent(content) {
-            console.log(content)
-            this.form.content = content
-        },
-
-
-        handleBtnClick(index, node, row) {
-            this.handleStatusChange(index, row, node.type)
-        },
-
-        handleStatusChange(index, row, nodeType) {
-            if (index !== -1) this.tagIndex = index // 子节点索引
-            this.selectNodes = row.flow.nodes; // 所有节点
-            this.nodeType = nodeType; // 节点类型
-            if (this.nodeType === 'targetConfirms') {
-                this.dialogTitle = "确认目标"
-                this.formLabel = "确认人"
-                this.targetConfirms = true;
-            }
-            if (nodeType == 'resultInput') {
-                this.dialogTitle = "录入结果"
-                this.formLabel = "录入人"
-                this.resultInput = true;
-            }
-            if (nodeType == 'scoreSelf') {
-                this.dialogTitle = "自评"
-                this.formLabel = "自评"
-                this.scoreSelf = true;
-            }
-            if (nodeType == 'scoreEachOther') {
-                this.dialogTitle = "互评"
-                this.formLabel = "互评人"
-                this.scoreEachOther = true
-            }
-            if (nodeType == 'scores') {
-                this.dialogTitle = "评分"
-                this.formLabel = "评分人"
-                this.scores = true
-
-            }
-            if (nodeType == 'reviews') {
-                this.dialogTitle = "审批"
-                this.formLabel = "审批人"
-                this.reviews = true
-            }
-            if (nodeType == 'cc') {
-                this.dialogTitle = "抄送"
-                this.formLabel = "抄送人"
-                this.cc = true
-            }
-        },
-
-        // 自评节点单独操作
-        handleScoreSelf(row) {
-            let { flow: { nodes } } = row
-            console.log(nodes)
-        },
-
-        closeNodeDialog() { },
-
-        // 编辑节点回调事件
-        finishHandle(data) {
-            let { nodes } = data
-            this.form.flow.nodes = nodes
-            console.log(nodes)
-        },
-
-
-        onIndicatorOkrSelected(okrs, data) {
-            console.log(okrs, data)
-            this.form.okrs = okrs;
-            this.indicatorOkrs = data;
-            this.showIndicatorTargetSearch = false;
-        },
-
-        confirm() {
-            if (this.loading) return
-            this.loading = true
-            if (!this.form.title) return this.$message.error("请输入指标标题")
-            let url = `/performance/review/indicator/post/${this.user_info.site_id}/${this.reviewId}`
-            this.$http.post(url, JSON.stringify(this.form)).then(res => {
-                if (res.code == 1) {
-                    this.clearFormData();
-                    this.dialogBeforeClose();
-                    this.$message.success("操作成功")
-                    this.$emit('finished');
-                } else {
-                    this.$message.error(res.message || "操作失败")
-                }
-                this.loading = false
-            })
-        },
-
-
-        cancel() {
-            this.$emit('close-dialog', false)
-        }
-    }
-}
-
-
-
-
-</script>
-
-<style scoped lang="scss">
-
-.okr-list-box {
-    width: 100%;
-    padding: 10px;
-    box-sizing: border-box;
-    background-color: #f7f7f7;
-    border-radius: 4px;
-    box-sizing: border-box;
-    position: relative;
-
-    .edit-box {
-        position: absolute;
-        top: 0px;
-        right: 20px;
-    }
-
-}
-
-
-.formulas-list-box {
-    width: 100%;
-    padding: 10px;
-    box-sizing: border-box;
-    background-color: #f7f7f7;
-    border-radius: 4px;
-    box-sizing: border-box;
-    position: relative;
-    .edit-box {
-        position: absolute;
-        top: 0px;
-        right: 20px;
-    }
-    .formulas-list {
-        margin-bottom: 10px;
-
-        .formulas-title {
-            font-size: 14px;
-            font-weight: 500;
-            color: #409eff;
-            box-sizing: border-box;
-        }
-
-        .formulas-condition-title {
-            font-size: 14px;
-            font-weight: 400;
-            margin-bottom: 5px;
-        }
-
-        .value-box {
-            display: flex;
-            align-items: center;
-            div {
-                margin-left: 3px;
-            }
-        }
-
-
-        .special-value {
-            display: inline-block;
-            width: 60px;
-            height: 30px;
-            text-align: center;
-            line-height: 30px;
-            border: 1px solid #409eff;
-            color: #409eff;
-            border-radius: 4px;
-            box-sizing: border-box;
-        }
-
-        .normal-value {
-            font-size: 14px;
-            letter-spacing: 2px;
-            margin: 0 3px;
-        }
-    }
-}
-    
-</style>

+ 432 - 244
src/newPerformance/components/MyPerformance/AddIndicator.vue

@@ -1,16 +1,16 @@
 <template>
-    <el-dialog title="添加指标" :visible.sync="addIndicatorDialogVisible" width="600px" :before-close="dialogBeforeClose"
+    <el-dialog :title="title" :visible.sync="addIndicatorDialogVisible" width="600px" :before-close="dialogBeforeClose"
         append-to-body @open="initNodes()">
-        <div>
+        <div class="dialog-box">
 
             <div v-loading="loading" class="scroll-bar" style="max-height: 500px; overflow-y: auto;">
                 <el-form ref="form" :model="form" label-width="80px">
 
-                    <el-form-item label="复制指标">
+                    <!-- <el-form-item label="复制指标">
                         <el-link type="primary" @click="selectIndicatorDialogVisible = true">
-                            选择复制
+                            选择已发起的考核指标
                         </el-link>
-                    </el-form-item>
+                    </el-form-item> -->
 
                     <el-form-item label="指标名称" prop="title">
                         <el-input v-model="form.title" placeholder="指标名称" clearable></el-input>
@@ -23,7 +23,7 @@
                                     <i class="el-icon-edit"></i>
                                 </el-link>
                             </div>
-                            <div v-html="form.content" style="white-space: pre-wrap;"></div>
+                            <div v-html="form.content" style="white-space: pre-wrap; line-height: 20px;"></div>
                         </div>
                         <el-link v-else type="primary" @click="showEditContent = true">
                             {{ form.content ? form.content : '点击设置指标规则' }}
@@ -31,22 +31,22 @@
                     </el-form-item>
 
                     <el-form-item label="过程跟踪">
-                        <template v-if="form.okrs && form.okrs.length > 0">
+                        <template v-if="form.okrs && form.okrs.length > 0 || form.plans && form.plans.length > 0">
                             <div class="okr-list-box">
                                 <div class="edit-box">
                                     <el-link type="primary" @click="showIndicatorTargetSearch = true">
                                         <i class="el-icon-edit"></i>
                                     </el-link>
                                 </div>
-                                <div class="okr-list-title">
+                                <div class="okr-list-title" v-if="form.okrs && form.okrs.length > 0">
                                     <el-link type="primary">
-                                        共 {{ form.okrs.length }} 个目标
+                                        共 {{ form.okrs.length }} 个目标,
                                     </el-link>
                                 </div>
-                                <div class="okr-list">
-                                    <div v-for="item in indicatorOkrs" :key="item.id">
-                                        {{ item.name }}
-                                    </div>
+                                <div class="okr-list-title" v-if="form.plans && form.plans.length > 0">
+                                    <el-link type="primary">
+                                        共 {{ form.plans.length }} 个计划
+                                    </el-link>
                                 </div>
 
                             </div>
@@ -69,15 +69,77 @@
                         <el-input v-model="form.weight" placeholder="权重(%)" clearable></el-input>
                     </el-form-item>
 
+
                     <el-form-item label="计算公式">
 
-                        <template v-if="form.expression.formulas && form.expression.formulas.length > 0">
+                        <template
+                            v-if="form.expression && form.expression.formulas && form.expression.formulas.length > 0">
                             <div class="formulas-list-box">
                                 <div class="edit-box">
                                     <el-link type="primary" @click="showFormula = true">
                                         <i class="el-icon-edit"></i>
                                     </el-link>
                                 </div>
+
+                                <el-descriptions :column="1" size="small" border>
+
+                                    <template v-for="(item, index) in form.expression.formulas">
+                                        <el-descriptions-item :key="index">
+                                            <template slot="label">
+                                                公式{{ index + 1 }}
+                                            </template>
+                                        </el-descriptions-item>
+                                        <el-descriptions-item :key="index"
+                                            v-if="item.condition && item.condition.length > 0">
+                                            <template slot="label">
+                                                触发条件
+                                            </template>
+                                            <div class="value-box"
+                                                v-if="item.condition[0] == '1' && item.condition[1] == '==' && item.condition[2] == '1'">
+                                                <div class="special-value">无触发条件</div>
+                                            </div>
+                                            <div v-else class="value-box">
+                                                <template v-for="(con, conIndex) in item.condition">
+                                                    <div class="special-value" v-if="con.toString().includes('result')">
+                                                        结果值
+                                                    </div>
+                                                    <div class="special-value"
+                                                        v-else-if="con.toString().includes('weight')">权重
+                                                    </div>
+                                                    <div class="special-value"
+                                                        v-else-if="con.toString().includes('target')">目标值
+                                                    </div>
+                                                    <div class="normal-value" v-else>{{ con }}</div>
+                                                </template>
+                                            </div>
+                                        </el-descriptions-item>
+
+
+                                        <el-descriptions-item :key="index"
+                                            v-if="item.expression && item.expression.length > 0">
+                                            <template slot="label">
+                                                计算公式
+                                            </template>
+                                            <div class="value-box">
+                                                <template v-for="(expr, exprIndex) in item.expression">
+                                                    <div class="special-value" v-if="expr.toString().includes('result')">结果值</div>
+                                                    <div class="special-value" v-else-if="expr.toString().includes('weight')">权重
+                                                    </div>
+                                                    <div class="special-value" v-else-if="expr.toString().includes('target')">目标值
+                                                    </div>
+                                                    <div class="normal-value" v-else>{{ expr }}</div>
+                                                </template>
+                                            </div>
+                                        </el-descriptions-item>
+                                    </template>
+                                </el-descriptions>
+                            </div>
+                            <!-- <div class="formulas-list-box">
+                                <div class="edit-box">
+                                    <el-link type="primary" @click="showFormula = true">
+                                        <i class="el-icon-edit"></i>
+                                    </el-link>
+                                </div>
                                 <div class="formulas-list" v-for="(item, index) in form.expression.formulas"
                                     :key="index">
                                     <div class="formulas-title">公式({{ index + 1 }})</div>
@@ -105,13 +167,17 @@
                                     </div>
                                 </div>
                             </div>
+                         -->
                         </template>
 
                         <el-link v-else type="primary" @click="showFormula = true">点击设置计算公式</el-link>
                     </el-form-item>
 
+                    <el-form-item label="考核流程">
+                        <el-link type="primary" @click="setProcessFlow()">点击设置考核流程</el-link>
+                    </el-form-item>
 
-                    <div class="node-settings flex-box-ce">
+                    <!-- <div class="node-settings flex-box-ce">
                         <div class="node-item">
                             <div class="node-title">确认目标</div>
                             <div class="flex-box-ce" style="flex-direction: column; margin-top: 10px;">
@@ -281,7 +347,7 @@
                                 </div>
                             </div>
                         </div>
-                    </div>
+                    </div> -->
 
                 </el-form>
                 <div style="height: 50px;"></div>
@@ -294,7 +360,6 @@
             </div>
         </div>
 
-
         <!-- 编辑计算公式 -->
         <FormulaComp v-if="showFormula" v-model="showFormula"
             :fixed-props="[{ key: 'target', name: '目标' }, { key: 'weight', name: '权重' }, { key: 'result', name: '结果值' }]"
@@ -305,49 +370,26 @@
         <EditContentComp v-if="showEditContent" v-model="showEditContent" :content="form.content"
             @finishEdit="finishEditContent" no-request />
 
-        <!-- 编辑确认目标节点 -->
-        <TargetConfirms v-if="targetConfirms" v-model="targetConfirms" :form-label="formLabel"
-            :dialog-title="dialogTitle" :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog"
-            :tag-index="tagIndex" @onConfirm="finishHandle" />
-
-        <!-- 编辑录入结果节点 -->
-        <ResultInput v-if="resultInput" v-model="resultInput" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑自评节点 -->
-        <ScoreSelf v-if="scoreSelf" v-model="scoreSelf" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑互评节点 -->
-        <ScoreEachOther v-if="scoreEachOther" v-model="scoreEachOther" :form-label="formLabel"
-            :dialog-title="dialogTitle" :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog"
-            :tag-index="tagIndex" @onConfirm="finishHandle" />
-
-        <!-- 编辑评分节点 -->
-        <Scores v-if="scores" v-model="scores" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
-            :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑审批节点 -->
-        <Reviews v-if="reviews" v-model="reviews" :form-label="formLabel" :dialog-title="dialogTitle"
-            :node-type="nodeType" :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
-        <!-- 编辑审批节点 -->
-        <CC v-if="cc" v-model="cc" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
-            :select-nodes="selectNodes" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
-            @onConfirm="finishHandle" />
-
+        
         <!-- 指标okr选择 -->
-        <TargetSearch :visible.sync="showIndicatorTargetSearch" :selectedCheckList="indicatorOkrs"
-            :showSelectedData="indicatorOkrs" :key="`indicatorTarget`" @confirm="onIndicatorOkrSelected" />
+        <TargetSearch :visible.sync="showIndicatorTargetSearch" :selectedOkrs="form.okrs" :selectedPlans="form.plans"
+            :key="`indicatorTarget`" @confirm="onIndicatorOkrSelected" />
 
         <!--选择指标进行复制-->
         <IndicatorList v-if="selectIndicatorDialogVisible" v-model="selectIndicatorDialogVisible"
             :indicatorInfo="indicatorInfo" @confirm="onIndicatorSelected" />
 
+        <!-- 设置考核流程 -->
+        <el-drawer title="考核流程" :visible.sync="handleNodeDialog" direction="rtl" :before-close="handleNodeDialogClose"
+            size="50%" style="margin: 0 !important; padding: 0 !important; " append-to-body>
+            <div class="drawer-box">
+                <WorkFlow v-if="handleNodeDialog" :handleFlow="selectedFlow" @update="updateSelectedNodes" />
+            </div>
+        </el-drawer>
+
+        <!-- 验证弹框 -->
+        <Vcode :show="verifyDialogVisible" @success="verifySuccess" @close="verifyError" />
+
 
     </el-dialog>
 
@@ -359,34 +401,19 @@
 import { mapGetters } from 'vuex';
 import TargetSearch from "@/performance/views/assessManagement/TargetSearch"; // 选择OKR
 import FormulaComp from '@/newPerformance/components/TemplateDetails/FormulaComp'; // 计算公式弹框
-import HandleNode from '@/newPerformance/components/TemplateDetails/HandleNode'; //单独设置流程节点弹框
-import ShowDataComp from '@/newPerformance/components/PublicComp/ShowData'; // 显示节点数据组件
 import EditContentComp from '@/newPerformance/components/TemplateDetails/EditContent'; // 编辑规则组件
-import BatchHandleNode from '@/newPerformance/components/TemplateDetails/BatchHandleNode'; // 批量设置流程节点
-import TargetConfirms from '@/newPerformance/components/TemplateDetails/TargetConfirms'; // 确认目标流程节点
-import ResultInput from '@/newPerformance/components/TemplateDetails/ResultInput'; // 结果录入流程节点
-import ScoreSelf from '@/newPerformance/components/TemplateDetails/ScoreSelf'; // 自评流程节点
-import ScoreEachOther from '@/newPerformance/components/TemplateDetails/ScoreEachOther'; // 互评流程节点
-import Scores from '@/newPerformance/components/TemplateDetails/Scores'; // 评分流程节点
-import Reviews from '@/newPerformance/components/TemplateDetails/Reviews'; // 审批流程节点
-import CC from '@/newPerformance/components/TemplateDetails/CC'; // 审批流程节点
 import IndicatorList from './IndicatorList.vue'; // 复制指标,选择指标复制
+import WorkFlow from '@/newPerformance/components/PublicComp/WorkFlow'; // 工作流组件
+import Vcode from "vue-puzzle-vcode";
+
 export default {
     components: {
-        HandleNode,
-        ShowDataComp,
         EditContentComp,
         TargetSearch,
         FormulaComp,
-        BatchHandleNode,
-        TargetConfirms,
-        ResultInput,
-        ScoreSelf,
-        ScoreEachOther,
-        Scores,
-        Reviews,
-        CC,
-        IndicatorList
+        IndicatorList,
+        WorkFlow,
+        Vcode
     },
 
     model: {
@@ -399,6 +426,7 @@ export default {
             type: Array,
             default: () => []
         },
+
         addIndicatorDialogVisible: {
             type: Boolean,
             default: false
@@ -407,6 +435,11 @@ export default {
         reviewId: {
             type: String | Number,
             default: () => {}
+        },
+
+        selectedIndicatorInfo: {
+            type: Object,
+            default: () => ({})
         }
     },
 
@@ -419,32 +452,20 @@ export default {
             loading: false,
             templateId: '',
             selectIndicatorId: '',
-            selectNodes: '',
-            dialogTitle: '',
-            nodeType: '',
-            formLabel: '',
+            selectedFlow: null,
+            title: "添加指标",
+            handleNodeDialog: false, // 绩效流程弹框显示
+            selectedNodes: [],
             showFormula: false, // 编辑计算公式弹框显示
             showEditContent: false, // 编辑指标内容弹框
             showIndicatorTargetSearch: false, // 选择OKRS
             selectIndicatorDialogVisible: false, // 选择指标进行复制
-            targetConfirms: false,
-            resultInput: false,
-            scoreSelf: false,
-            scoreEachOther: false,
-            scores: false,
-            reviews: false,
-            cc: false,
+            verifyDialogVisible: false,
             compStyle: {
                 flexDirection: 'row',
                 alignItems: 'center',
                 justifyContent: 'flex-start'
             },
-            indicatorOkrs: [],
-            employeeMap: this.$getEmployeeMap(), // 员工列表
-            postList: JSON.parse(localStorage.getItem("postList")), // 岗位列表
-            deptList: JSON.parse(localStorage.getItem("deptList")), // 部门列表 - 树形结构
-            dept_list: JSON.parse(localStorage.getItem("dept_list")), // 部门列表
-            tagIndex: 0,
             form: {
                 title: "",
                 content: "",
@@ -596,86 +617,84 @@ export default {
                     ]
                 },
                 employeeId: 0,
-                okrs: []
+                okrs: [],
+                plans: []
             }
         }
     },
 
     methods: {
 
-        // 获取部门
-        get_dept_list() {
-            return this.$axiosUser('get', '/api/pro/department/tree', '', 'v2')
-        },
 
-        // 岗位列表
-        get_post_list() {
-            let data = {
-                page: 1,
-                page_size: 999,
-                cate_id: -1,
-                name: ''
-            }
-            return this.$axiosUser('get', '/api/pro/post/cate_post_list', data)
-        },
+        
 
-        // 处理部门树状结构数据
-        getTreeData(data) {
-            for (var i = 0; i < data.length; i++) {
-                data[i].checked = false;
-                if (data[i].children.length < 1) {
-                    // children若为空数组,则将children设为undefined
-                    data[i].children = undefined;
-                } else {
-                    // children若不为空数组,则继续 递归调用 本方法
-                    this.getTreeData(data[i].children);
+        initNodes() {
+
+            // 编辑指标
+            if (JSON.stringify(this.selectedIndicatorInfo) !== "{}") {
+                this.form = {
+                    ...this.selectedIndicatorInfo,
+                    employeeId: 0
                 }
+                
+                this.reviewIndicatorId = this.selectedIndicatorInfo.reviewIndicatorId;
+                this.title = "重新发布"
+            // 添加指标
+            } else {
+                this.title = "添加指标"
+                this.form.flow.nodes.forEach((item, index) => {
+                    if (index == 0) {
+                        item.id = "TCS_" + Date.now() + Math.floor(Math.random() * 10000)
+                        item.children[0].id = "TC_" + Date.now() + Math.floor(Math.random() * 10000)
+                    }
+                    if (index == 1) item.id = "RI_" + Date.now() + Math.floor(Math.random() * 10000)
+                    if (index == 2) item.id = "SELF_" + Date.now() + Math.floor(Math.random() * 10000)
+                    if (index == 3) item.id = "EO_" + Date.now() + Math.floor(Math.random() * 10000)
+                    if (index == 4) {
+                        item.id = "SS_" + Date.now() + Math.floor(Math.random() * 10000)
+                        item.children[0].id = "S_" + Date.now() + Math.floor(Math.random() * 10000)
+                    }
+                    if (index == 5) {
+                        item.id = "RS_" + Date.now() + Math.floor(Math.random() * 10000)
+                        item.children[0].id = "R_" + Date.now() + Math.floor(Math.random() * 10000)
+                    }
+                    if (index == 6) item.id = "CC_" + Date.now() + Math.floor(Math.random() * 10000)
+                })
             }
-            return data;
+            
         },
 
-        initNodes() {
-            this.form.flow.nodes.forEach((item, index) => {
-                if (index == 0) {
-                    item.id = "TCS_" + Date.now() + Math.floor(Math.random() * 10000)
-                    item.children[0].id = "TC_" + Date.now() + Math.floor(Math.random() * 10000)
-                } 
-                if (index == 1) item.id = "RI_" + Date.now() + Math.floor(Math.random() * 10000)
-                if (index == 2) item.id = "SELF_" + Date.now() + Math.floor(Math.random() * 10000)
-                if (index == 3) item.id = "EO_" + Date.now() + Math.floor(Math.random() * 10000)
-                if (index == 4) {
-                    item.id = "SS_" + Date.now() + Math.floor(Math.random() * 10000)
-                    item.children[0].id = "S_" + Date.now() + Math.floor(Math.random() * 10000)
-                }
-                if (index == 5) {
-                    item.id = "RS_" + Date.now() + Math.floor(Math.random() * 10000)
-                    item.children[0].id = "R_" + Date.now() + Math.floor(Math.random() * 10000)
-                }
-                if (index == 6) item.id = "CC_" + Date.now() + Math.floor(Math.random() * 10000)
-            })
+        setProcessFlow() {
+            let { nodes } = this.form.flow;
+            this.selectedNodes = nodes
+            this.handleNodeDialog = true;
+        },
+
+        setProcessFlow() {
+            // this.selectIndicatorId = row.indicatorId;
+            this.selectedFlow = this.form.flow;
+            this.handleNodeDialog = true;
+        },
 
-            console.log(this.form)
 
 
-            // 请求岗位列表,部门列表
-            Promise.all([this.get_dept_list(), this.get_post_list()]).then(([deptRes, postRes]) => {
-                if (deptRes.data.code !== 1) return this.$message.error(deptRes.data.msg || "请求部门列表数据出错")
-                if (postRes.data.code !== 1) return this.$message.error(postRes.data.msg || "请求岗位列表数据出错")
-                this.dept_list = deptRes.data.data.list;
-                this.deptList = this.getTreeData(this.dept_list); // 处理成树状结构
-                this.postList = postRes.data.data.list
-                localStorage.setItem("dept_list", JSON.stringify(this.dept_list))
-                localStorage.setItem("deptList", JSON.stringify(this.deptList))
-                localStorage.setItem("postList", JSON.stringify(this.postList))
-                this.isDataShow = true
-            })
+        // 编辑流程节点
+        updateSelectedNodes(nodes) {
+            this.form.flow.nodes = nodes
+            this.handleNodeDialog = false;
+        },
+
+        handleNodeDialogClose() {
+            this.handleNodeDialog = false;
         },
 
         // 清空数据
         clearFormData() {
-            this.indicatorOkrs = [];
-            this.loading = false
-            this.tagIndex = 0;
+            this.templateId = '';
+            this.selectIndicatorId = '';
+            this.selectNodes = '';
+            this.title = '添加指标';
+            this.loading = false;
             this.form = {
                 title: "",
                 content: "",
@@ -714,6 +733,166 @@ export default {
                                     }
                                 ]
                             },
+                            {
+                                id: "",
+                                type: "resultInput",
+                                enable: false,
+                                assigneeType: "self",
+                                leaderLevel: 1,
+                                assigneeIds: [],
+                                multipleType: "or",
+                                allows: [
+                                    "transfer"
+                                ],
+                                weight: 0,
+                                children: []
+                            },
+                            {
+                                id: "",
+                                type: "scoreSelf",
+                                enable: false,
+                                assigneeType: "self",
+                                leaderLevel: 1,
+                                assigneeIds: [],
+                                multipleType: "or",
+                                allows: [
+                                    "transfer"
+                                ],
+                                weight: 0,
+                                children: []
+                            },
+                            {
+                                id: "",
+                                type: "scoreEachOther",
+                                enable: false,
+                                assigneeType: "self",
+                                leaderLevel: 1,
+                                assigneeIds: [],
+                                multipleType: "parallel",
+                                allows: [],
+                                weight: 0,
+                                children: []
+                            },
+                            {
+                                id: "",
+                                type: "scores",
+                                enable: true,
+                                assigneeType: "leader",
+                                leaderLevel: 1,
+                                assigneeIds: [],
+                                multipleType: "or",
+                                allows: [
+                                    "transfer"
+                                ],
+                                weight: 0,
+                                children: [
+                                    {
+                                        id: "",
+                                        type: "score",
+                                        enable: true,
+                                        assigneeType: "leader",
+                                        leaderLevel: 1,
+                                        assigneeIds: [],
+                                        multipleType: "or",
+                                        allows: [
+                                            "transfer"
+                                        ],
+                                        weight: 100,
+                                        children: []
+                                    }
+                                ]
+                            },
+                            {
+                                id: "",
+                                type: "reviews",
+                                enable: false,
+                                assigneeType: "leader",
+                                leaderLevel: 1,
+                                assigneeIds: [],
+                                multipleType: "or",
+                                allows: [
+                                    "transfer"
+                                ],
+                                weight: 0,
+                                children: [
+                                    {
+                                        id: "",
+                                        type: "review",
+                                        enable: true,
+                                        assigneeType: "leader",
+                                        leaderLevel: 1,
+                                        assigneeIds: [],
+                                        multipleType: "or",
+                                        allows: [
+                                            "transfer"
+                                        ],
+                                        weight: 0,
+                                        children: []
+                                    }
+                                ]
+                            },
+                            {
+                                id: "",
+                                type: "cc",
+                                enable: false,
+                                assigneeType: "user",
+                                leaderLevel: 1,
+                                assigneeIds: [],
+                                multipleType: "or",
+                                allows: [],
+                                weight: 0,
+                                children: []
+                            }
+                        ]
+                },
+                employeeId: 0,
+                okrs: [],
+                plans: []
+            }
+        },
+
+
+        
+
+        dialogBeforeClose() {
+            this.form = {
+                title: "",
+                content: "",
+                target: "",
+                unit: "",
+                weight: "",
+                expression: {
+                    formulas: []
+                },
+                expandData: [],
+                flow:
+                {
+                    nodes: [
+                        {
+                            id: "",
+                            type: "targetConfirms",
+                            enable: false,
+                            assigneeType: "self",
+                            leaderLevel: 1,
+                            assigneeIds: [],
+                            multipleType: "or",
+                            allows: [],
+                            weight: 0,
+                            children: [
+                                {
+                                    id: "",
+                                    type: "targetConfirm",
+                                    enable: true,
+                                    assigneeType: "self",
+                                    leaderLevel: 1,
+                                    assigneeIds: [],
+                                    multipleType: "or",
+                                    allows: [],
+                                    weight: 0,
+                                    children: []
+                                }
+                            ]
+                        },
                         {
                             id: "",
                             type: "resultInput",
@@ -827,70 +1006,24 @@ export default {
                     ]
                 },
                 employeeId: 0,
-                okrs: []
-            }
-        },
-
-
-        filterEmployeeNames(assigneeIds) {
-            let employeeNames = []
-            if (assigneeIds && assigneeIds.length > 0) {
-                Object.keys(this.employeeMap).forEach(key => {
-                    assigneeIds.forEach(assigneeId => {
-                        if (key == assigneeId) employeeNames.push(this.employeeMap[key].name)
-                    })
-                })
-            }
-            return employeeNames
-        },
-
-        filterPostNames(assigneeIds) {
-            let select_post_name = []
-            if (assigneeIds && assigneeIds.length > 0) {
-                if (this.postList && this.postList.length > 0) {
-                    this.postList.forEach(post => {
-                        assigneeIds.forEach(assignee => {
-                            if (post.id == assignee) select_post_name.push(post.name)
-                        })
-                    })
-                }
-
-            }
-            return select_post_name
-        },
-
-        filterDeptNames(assigneeIds) {
-            let select_dept_name = []
-            if (assigneeIds && assigneeIds.length > 0) {
-                if (this.dept_list && this.dept_list.length > 0) {
-                    this.dept_list.forEach(dept => {
-                        assigneeIds.forEach(assignee => {
-                            if (dept.id == assignee) {
-                                select_dept_name.push(dept.name)
-                            }
-                        })
-                    })
-                }
-            }
-            return select_dept_name
-        },
-
-        dialogBeforeClose() {
+                okrs: [],
+                plans: []
+            };
+            // this.selectedIndicatorInfo = {}
             this.$emit('close-dialog', false)
         },
 
         // 编辑计算公式的回调
         onFormulaConfirm(formulas) {
-            console.log("公式")
-            console.log(formulas)
-            this.form.expression.formulas = formulas
-            console.log(this.form.expression.formulas)
+            console.log('formulas', formulas)
+
+            this.form.expression.formulas = formulas;
+            this.showFormula = false;
         },
 
 
         // 编辑指标规则
         finishEditContent(content) {
-            console.log(content)
             this.form.content = content
         },
 
@@ -948,31 +1081,49 @@ export default {
         finishHandle(data) {
             let { nodes } = data
             this.form.flow.nodes = nodes
-            console.log(nodes)
         },
 
         onIndicatorSelected(indicator) {
-            console.log(indicator)
             this.form = {
                 ...indicator,
                 employeeId: 0
             }
         },
 
+        verifySuccess(msg) {
+
+            // 添加指标
+            if (this.title === "添加指标") {
+                this.addIndicatorApi();
+            // 编辑指标
+            } else {
+                this.deleteIndicator();
+            }
 
-        onIndicatorOkrSelected(okrs, data) {
-            console.log(okrs, data)
+        },
+
+        verifyError() {
+            this.verifyDialogVisible = false;
+        },
+
+
+        onIndicatorOkrSelected(okrs, plans) {
             this.form.okrs = okrs;
-            this.indicatorOkrs = data;
+            this.form.plans = plans;
             this.showIndicatorTargetSearch = false;
         },
 
         confirm() {
             if (!this.form.title) return this.$message.error("请输入指标标题")
             if (this.loading) return
+            this.verifyDialogVisible = true;
+        },
+
+        addIndicatorApi() {
             this.loading = true
             let url = `/performance/review/indicator/post/${this.user_info.site_id}/${this.reviewId}`
             this.$http.post(url, JSON.stringify(this.form)).then(res => {
+                this.verifyDialogVisible = false
                 if (res.code == 1) {
                     this.clearFormData();
                     this.dialogBeforeClose();
@@ -985,6 +1136,20 @@ export default {
             })
         },
 
+        // 删除指标
+        deleteIndicator() {
+            let url = `/performance/review/indicator/remove/${this.user_info.site_id}/${this.reviewId}/${this.reviewIndicatorId}`
+            this.$http.post(url).then(res => {
+                this.verifyDialogVisible = false
+                if (res.code == 1) {
+                    this.addIndicatorApi()
+                    // this.$message.success("操作成功")
+                } else {
+                    this.$message.success("操作失败")
+                }
+            })
+        },
+
 
         cancel() {
             this.clearFormData();
@@ -1015,6 +1180,19 @@ export default {
 
 <style scoped lang="scss">
 
+.vue-puzzle-vcode {
+    z-index: 99999;
+}
+
+::v-deep .el-drawer__header {
+    margin-bottom: 20px;
+}
+
+::v-deep .el-drawer__header span {
+    font-size: 18px !important;
+    font-weight: bold !important;
+}
+
 .okr-list-box {
     width: 100%;
     padding: 10px;
@@ -1023,7 +1201,7 @@ export default {
     border-radius: 4px;
     box-sizing: border-box;
     position: relative;
-
+    display: flex;
     .edit-box {
         position: absolute;
         top: 0px;
@@ -1032,10 +1210,41 @@ export default {
 
 }
 
+.value-box {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+    overflow: hidden;
+    font-size: 12px;
+    div {
+        margin: 0 0 3px 3px;
+    }
+}
+
+
+.special-value {
+    display: inline-block;
+    padding: 0 5px;
+    height: 24px;
+    font-size: 12px;
+    text-align: center;
+    line-height: 24px;
+    color: #409eff;
+    border-radius: 4px;
+    box-sizing: border-box;
+    border: 1px solid #409eff;
+}
+
+.normal-value {
+    font-size: 14px;
+    letter-spacing: 2px;
+    margin: 0 3px;
+}
+
 
 .formulas-list-box {
     width: 100%;
-    padding: 10px;
+    padding: 20px;
     box-sizing: border-box;
     background-color: #f7f7f7;
     border-radius: 4px;
@@ -1043,8 +1252,8 @@ export default {
     position: relative;
     .edit-box {
         position: absolute;
-        top: 0px;
-        right: 20px;
+        top: -10px;
+        right: 10px;
     }
     .formulas-list {
         margin-bottom: 10px;
@@ -1054,40 +1263,19 @@ export default {
             font-weight: 500;
             color: #409eff;
             box-sizing: border-box;
+            height: 24px;
+            line-height: 24px;
         }
 
         .formulas-condition-title {
             font-size: 14px;
-            font-weight: 400;
-            margin-bottom: 5px;
-        }
-
-        .value-box {
-            display: flex;
-            align-items: center;
-            div {
-                margin-left: 3px;
-            }
-        }
-
-
-        .special-value {
-            display: inline-block;
-            width: 60px;
-            height: 30px;
-            text-align: center;
-            line-height: 30px;
-            border: 1px solid #409eff;
-            color: #409eff;
-            border-radius: 4px;
-            box-sizing: border-box;
+            font-weight: 500;
+            color: #000;
+            height: 24px;
+            line-height: 24px;
         }
 
-        .normal-value {
-            font-size: 14px;
-            letter-spacing: 2px;
-            margin: 0 3px;
-        }
+        
     }
 }
 

+ 1 - 11
src/newPerformance/components/MyPerformance/ExamineLog.vue

@@ -133,7 +133,7 @@ export default {
 <style scoped lang="scss">
 .all {
     width: 100%;
-    min-height: 400px;
+    max-height: 500px;
     overflow-y: auto;
     background-color: #fff;
     font-size: 14px;
@@ -143,16 +143,6 @@ export default {
     display: flex;
     flex-direction: column;
 
-    .header {
-        font-size: 16px;
-        font-weight: 600;
-        height: 30px;
-        line-height: 30px;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-    }
-
     .table-box {
         flex: 1;
         width: 100%;

+ 32 - 27
src/newPerformance/components/MyPerformance/IndicatorList.vue

@@ -1,7 +1,7 @@
 <template>
-    <el-dialog title="请选择指标" :visible.sync="selectIndicatorDialogVisible" width="600px"
+    <el-dialog title="请选择指标" :visible.sync="selectIndicatorDialogVisible" width="500px"
         :before-close="dialogBeforeClose" append-to-body>
-        <div class="flex-box-ce">
+        <div class="dialog-box scroll-box">
             <div class="indicator-item" :class="currentIndex == index ? 'active' : ''"
                 v-for="(item, index) in indicatorInfo" :key="item.reviewIndicatorId" @click="chooseIndicator(index)">
                 {{ item.title }}
@@ -17,6 +17,7 @@
 </template>
 
 
+
 <script>
 
 export default {
@@ -58,9 +59,9 @@ export default {
 
         confirm() {
             if (!this.indicatorInfo[this.currentIndex]) return
-            let { title, unit, content, target, weight, okrs, expression, flow } = this.indicatorInfo[this.currentIndex]
-            console.log(this.indicatorInfo[this.currentIndex]);
-            this.$emit('confirm', { title, unit, content, target, weight, okrs, expression, flow });
+            let { title, unit, content, target, weight, okrs, plans, expression, flow } = this.indicatorInfo[this.currentIndex]
+            // console.log('选择的指标信息', this.indicatorInfo[this.currentIndex])
+            this.$emit('confirm', { title, unit, content, target, weight, okrs, plans, expression, flow });
             this.cancel();
         },
 
@@ -69,34 +70,38 @@ export default {
         },
 
 
-
-
     }
 }
 </script>
 
 
 <style scoped lang="scss">
-.indicator-item {
-    width: 140px;
-    padding: 6px 10px;
-    text-align: center;
-    border-radius: 25px;
-    margin-right: 10px;
-    color: #89919f;
-    background-color: #f5f8fa;
-    cursor: pointer;
-    position: relative;
-    box-sizing: border-box;
-    margin-bottom: 10px;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    overflow: hidden;
-    &.active {
-        border: none;
-        background-color: #409EFF;
-        font-weight: 600;
-        color: #fff;
+.dialog-box {
+    max-height: 400px;
+    overflow-y: auto;
+
+    .indicator-item {
+        padding: 6px 10px;
+        text-align: center;
+        border-radius: 25px;
+        margin-right: 10px;
+        color: #89919f;
+        background-color: #f5f8fa;
+        cursor: pointer;
+        position: relative;
+        box-sizing: border-box;
+        margin-bottom: 10px;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+
+        &.active {
+            border: none;
+            background-color: #409EFF;
+            font-weight: 600;
+            color: #fff;
+        }
     }
 }
+
 </style>

+ 10 - 8
src/newPerformance/components/MyPerformance/SelectExamine.vue

@@ -1,5 +1,6 @@
 <template>
-    <el-dialog title="历史考核记录" :visible.sync="dialogVisible" width="800px" :before-close="dialogBeforeClose" append-to-body >
+    <el-dialog title="历史考核记录" :visible.sync="dialogVisible" width="800px" :before-close="dialogBeforeClose"
+        append-to-body>
         <div>
             <!-- 搜索框 -->
             <div class="search-box">
@@ -42,13 +43,14 @@
                         </div>
                         <div class="perform-item-status" :class="item.status == 1 ? 'green-color' : 'orange-color'">
                             {{
-                            item.status == 1 ? '考核结束' : '考核中' }}</div>
+                                item.status == 1 ? '考核结束' : '考核中' }}</div>
                         <div class="perform-item-progress">{{ item.progress }}</div>
                         <div class="perform-item-score">{{ item.score ? item.score + '分' : '--' }} </div>
                     </div>
                 </template>
                 <noData v-else content="暂无数据" imgW="200px" imgH="200px"></noData>
             </div>
+
             <div v-if="performList && performList.length > 0" class="flex-box-ce"
                 style="justify-content: center; margin-top: 10px;">
                 <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
@@ -78,7 +80,7 @@ export default {
         },
         searchOptions: {
             type: Object,
-            default: () => {}
+            default: () => { }
         }
     },
 
@@ -91,7 +93,7 @@ export default {
                     this.params.cycleType = cycleType
                     this.params.cateId = cateId + ''
                 }
-                
+
                 this.getTemplateList()
             }
         }
@@ -112,7 +114,7 @@ export default {
             cycleType: '-1',
             cycleOptions: [
                 { label: "全部", value: '-1' },
-                { label: "定义", value: '0' },
+                { label: "定义", value: '0' },
                 { label: "年度", value: '1' },
                 { label: "半年度", value: '2' },
                 { label: "季度", value: '3' },
@@ -152,7 +154,7 @@ export default {
         }
     },
 
-    
+
     filters: {
         formatDate(val) {
             if (val) return moment(val).format('YYYY-MM-DD')
@@ -192,7 +194,7 @@ export default {
             let url = `/performance/statistics/reviews/${that.user_info.site_id}`
             let requestdata;
             if (that.cycleType == '-1') requestdata = { ...that.params }
-            else requestdata = { ...that.params, cycleType: that.cycleType } 
+            else requestdata = { ...that.params, cycleType: that.cycleType }
             that.$axiosUser('get', url, requestdata).then(res => {
                 let { data: { data: { list, total }, code } } = res;
                 if (code == 1) {
@@ -235,7 +237,7 @@ export default {
             this.getTemplateList();
         },
 
-        
+
         // 日期选择时间
         changeDate(v) {
             this.params.page = 1;

+ 4 - 3
src/newPerformance/components/OrganizationExamine.vue

@@ -9,7 +9,7 @@
                 </el-select>
 
                 <el-cascader ref="dept" v-model="selected_dept_ids" size="small"
-                    style="width: 300px; margin-left: 10px; " :options="deptList" @change="deptChange"
+                    style="width: 500px; margin-left: 10px; " :options="deptList" @change="deptChange"
                     :props="{ checkStrictly: true, multiple: true }" filterable change-on-select placeholder="请选择部门"
                     clearable></el-cascader>
 
@@ -376,10 +376,10 @@ export default {
         },
 
         deptChange(val) {
+            // 数据去重
             this.selected_dept_ids = Array.from(new Set(this.selected_dept_ids)); // 去重
             this.params.deptIds = this.selected_dept_ids.toString()
-            // 数据去重
-                this.getList();
+            this.getList();
         },
 
 
@@ -526,6 +526,7 @@ export default {
 .blue-color {
     color: #409eff;
 }
+
 .all {
     width: 100%;
     height: 100%;

+ 0 - 759
src/newPerformance/components/PerInterview.vue

@@ -1,759 +0,0 @@
-<template>
-  <el-container style="height: 100%; ">
-    <el-main v-if="interviewInfo" v-loading="loading" >
-      <el-card style="height: 10%; margin-bottom: 10px; ">
-        <el-row type="flex" justify="space-between" align="middle">
-          <el-col>
-            <el-button
-              v-if="canJoinMeeting"
-              type="text"
-              :disabled="loading"
-              @click="initMeeting"
-            >进入会议模式</el-button>
-            <el-button
-              v-if="canExitMeeting"
-              type="warning"
-              :disabled="loading"
-              @click="leaveInterview"
-            >
-              退出会议模式
-            </el-button>
-            <el-button
-              v-if="canCloseMeeting"
-              :disabled="loading"
-              type="primary"
-              @click="closeMeeting"
-            >
-              结束会议
-            </el-button>
-          </el-col>
-          <el-col align="end">
-            <el-rate
-              v-model="interviewInfo.satisfactionLevel"
-              :colors="rateColors"
-              :disabled="!canSatisfaction"
-              @change="sendSatisfaction"
-            />
-          </el-col>
-        </el-row>
-      </el-card>
-      <el-card style="height: 30%; overflow-y: auto; margin-bottom: 10px;">
-        <el-descriptions
-          title="考核信息"
-          :column="3"
-          border
-        >
-          <template
-            v-if="interviewInfo.reviewInfo.indicators && interviewInfo.reviewInfo.indicators.length > 0"
-            #extra
-          >
-            <el-button
-              type="text"
-              @click="showIndicator = true"
-            >
-              查看考核指标
-            </el-button>
-          </template>
-          <el-descriptions-item label="考核">
-            {{interviewInfo.reviewInfo.title}}
-          </el-descriptions-item>
-          <el-descriptions-item
-            v-if="interviewInfo.reviewInfo.cateIds && interviewInfo.reviewInfo.cateIds.length > 0"
-            label="考核分类">
-            <template
-              v-for="cateId in interviewInfo.reviewInfo.cateIds"
-            >
-              <el-link
-                v-if="cateMap[cateId]"
-                :key="cateId"
-                type="primary"
-              >
-                {{ cateMap[cateId] }}
-              </el-link>
-            </template>
-          </el-descriptions-item>
-          <el-descriptions-item label="考核人">
-            {{ interviewInfo.reviewInfo.employeeName }}
-          </el-descriptions-item>
-          <el-descriptions-item label="考核周期">
-            {{ $moment(interviewInfo.reviewInfo.startTime).format("YYYY/MM/DD") }} - {{ $moment(interviewInfo.reviewInfo.endTime).format("YYYY/MM/DD") }}
-            <span v-if="interviewInfo.reviewInfo.cycleType > 0">
-              {{ cycleMap[interviewInfo.reviewInfo.cycleType] || '' }}
-            </span>
-          </el-descriptions-item>
-          <el-descriptions-item label="考核状态">
-            {{ statusMap[interviewInfo.reviewInfo.status] || '--'}}
-          </el-descriptions-item>
-          <el-descriptions-item label="评分">
-            {{ interviewInfo.reviewInfo.score }}
-          </el-descriptions-item>
-          <el-descriptions-item v-if="interviewInfo.reviewInfo.levelName" label="评级">
-            {{ interviewInfo.reviewInfo.levelName }}
-          </el-descriptions-item>
-        </el-descriptions>
-      </el-card>
-      <el-row
-        type="flex"
-        justify="space-between"
-        style="height: 55%;"
-      >
-        <el-col :span="17" style="height: 100%; overflow-y: auto;">
-          <el-row style="height: 100%;" type="flex" justify="space-around">
-            <el-col :span="12" style="height: 100%;">
-              <el-card style="height: 100%;">
-                <template #header>
-                  主持人记录
-                </template>
-                <template #default>
-                  <el-input
-                    type="textarea"
-                    v-model="interviewInfo.assigneeComment"
-                    :rows="canAssigneeComment ? 10 : 11"
-                    :readonly="!canAssigneeComment"
-                  />
-                  <div style="margin-top: 5px; position: relative;">
-                    <el-button
-                      v-if="canAssigneeComment"
-                      type="primary"
-                      style="position: absolute; right: 5px;"
-                      @click="sendAssigneeComment"
-                    >
-                      保存
-                    </el-button>
-                  </div>
-                </template>
-              </el-card>
-            </el-col>
-            <el-col :span="11" style="height: 100%;">
-              <el-card style="height: 100%;">
-                <template #header>
-                  考核人记录
-                </template>
-                <template #default>
-                  <el-input
-                    type="textarea"
-                    v-model="interviewInfo.employeeComment"
-                    :rows="canEmployeeComment ? 10 : 11"
-                    :readonly="!canEmployeeComment"
-                  />
-                  <div style="margin-top: 5px; position: relative;">
-                    <el-button
-                      v-if="canEmployeeComment"
-                      type="primary"
-                      style="position: absolute; right: 5px;"
-                      @click="sendEmployeeComment"
-                    >
-                      保存
-                    </el-button>
-                  </div>
-                </template>
-              </el-card>
-            </el-col>
-          </el-row>
-        </el-col>
-        <el-col :span="7" style="height: 100%;">
-          <el-card style="height: 100%;">
-            <template #header>
-              <div style="height: 15px; line-height: 15px;">
-                <el-dropdown
-                  v-if="hasJoinInterview && userList.length > 0"
-                >
-                  <el-link
-                    type="primary"
-                  >
-                    {{ `${userList.length} 个参与者` }} <i class="el-icon-arrow-down el-icon--right"/>
-                  </el-link>
-                  <el-dropdown-menu slot="dropdown">
-                    <el-dropdown-item
-                      v-for="user in userList"
-                      :key="user.id"
-                    >
-                      {{ user.name }}
-                    </el-dropdown-item>
-                  </el-dropdown-menu>
-                </el-dropdown>
-                <span v-else>聊天记录</span>
-                <el-button
-                  v-if="canInterviewLog"
-                  size="mini"
-                  type="text"
-                  style="float: right;"
-                  @click="showChat = true"
-                >
-                  发送
-                </el-button>
-              </div>
-            </template>
-            <template #default>
-              <div style="height: 300px; overflow-y: auto;">
-                <el-card
-                  v-for="log in interviewLogs"
-                  :key="log.logId"
-                  style="margin-bottom: 10px;"
-                >
-                  <el-row type="flex" justify="start" align="center">
-                    <el-col :span="3">
-                      <el-avatar size="small" :src="employeeMap[log.employeeId].imgUrl">
-                        <el-avatar
-                          icon="el-icon-user-solid"
-                          size="small"
-                        />
-                      </el-avatar>
-                    </el-col>
-                    <el-col :span="11" style="line-height: 28px;">
-                      {{ employeeMap[log.employeeId].name }}
-                    </el-col>
-                    <el-col :span="10" style="line-height: 28px;">
-                      {{ log.ct }}
-                    </el-col>
-                  </el-row>
-                  <el-link type="primary" style="margin-top: 5px;">
-                    {{ log.content }}
-                  </el-link>
-                </el-card>
-                <div ref="chatLogRef"></div>
-              </div>
-            </template>
-          </el-card>
-        </el-col>
-      </el-row>
-    </el-main>
-    <NoData v-else content="暂无面谈记录"></NoData>
-    <el-dialog
-      :visible.sync="showChat"
-      width="600"
-      title="聊天记录"
-      center
-    >
-      <el-card>
-        <el-input
-          v-model="chatContent"
-          type="textarea"
-          autosize
-          style="margin-bottom: 10px;"
-        />
-        <el-button
-          type="primary"
-          style="float: right;margin-bottom: 10px;"
-          @click="sendChatLog"
-        >
-          发送
-        </el-button>
-      </el-card>
-    </el-dialog>
-    <el-dialog
-      v-if="interviewInfo && interviewInfo.reviewInfo.indicators && interviewInfo.reviewInfo.indicators.length > 0"
-      :visible.sync="showIndicator"
-      title="考核指标"
-      center
-    >
-      <el-table
-        :data="interviewInfo.reviewInfo.indicators"
-        max-height="800"
-      >
-        <el-table-column
-          prop="title"
-          label="指标"
-          fixed="left"
-          show-overflow-tooltip
-          align="center"
-        />
-        <el-table-column
-          prop="content"
-          label="规则"
-          show-overflow-tooltip
-          align="center"
-        />
-        <el-table-column
-          prop="target"
-          label="目标"
-          align="center"
-        >
-          <template slot-scope="scope">
-            {{ scope.row.target === null ? '--' : (scope.row.unit ? `${scope.row.target} ${scope.row.unit}` : scope.row.target) }}
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="result"
-          label="结果"
-          align="center"
-        >
-          <template slot-scope="scope">
-            {{ scope.row.result === null ? '--' : (scope.row.unit ? `${scope.row.result} ${scope.row.unit}` : scope.row.result) }}
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="weight"
-          label="权重"
-          align="center"
-        >
-          <template slot-scope="scope">
-            {{ scope.row.weight ? `${scope.row.weight} %` : '--' }}
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="businessStatus"
-          label="考核状态"
-          align="center"
-        >
-          <template slot-scope="scope">
-            <el-link
-              :type="scope.row.businessStatus === 'end' ? 'primary' : 'warning'"
-            >
-              {{ indicatorStatusMap[scope.row.businessStatus] || '--' }}
-            </el-link>
-          </template>
-        </el-table-column>
-        <el-table-column
-          prop="score"
-          label="得分"
-          align="center"
-        />
-      </el-table>
-    </el-dialog>
-  </el-container>
-</template>
-
-
-<script>
-
-import Template from "../../examine/components/Template.vue";
-import Stomp from 'stompjs';
-import {getToken} from '@/utils/auth';
-
-export default {
-  name: "PerInterview",
-  components: {Template},
-  props:{
-    reviewId:{
-      type: Number,
-      required: true
-    },
-    interviewId:{
-      type: Number,
-      require: true,
-    }
-  },
-  watch:{
-    interviewId(v){
-      if (v) this.initData();
-    },
-  },
-  data(){
-    return {
-      userInfo:this.$userInfo(),
-      innerVisible:this.showVisible,
-      loading:false,
-      interviewInfo:null,
-      interviewLogs:[],
-      cateList:[],
-      employeeList:[],
-      cycleMap:{
-        0:'未定义',
-        1:'年度',
-        2:'半年度',
-        3:'季度',
-        4:'月度',
-      },
-      statusMap:{
-        0:'考核中',
-        1:'已结束',
-        2:'面谈',
-      },
-      indicatorStatusMap:{
-        start:'进入考核',
-        target_confirm:'目标确认中',
-        result_input:'结果录入中',
-        score_self:'自评中',
-        score_each_other:'互评中',
-        score:'评分中',
-        review:'审批中',
-        cc:'抄送',
-        end:'已结束',
-      },
-      rateColors:['#99A9BF', '#F7BA2A', '#FF9900'],
-      chatContent:'',
-      interviewConnect:false,
-      hasJoinInterview:false,
-      stompClient:null,
-      userList:[],
-      showChat:false,
-      showIndicator:false,
-    }
-  },
-  computed: {
-    cateMap(){
-      const map = {};
-      this.cateList.forEach(cate => {
-        map[cate.cateId] = cate.name;
-      });
-      return map;
-    },
-    employeeMap(){
-      const map = {};
-      this.employeeList.forEach(e => {
-        map[e.id] = e;
-      });
-      return map;
-    },
-    canSatisfaction(){
-      return this.interviewInfo && this.interviewInfo.assessor;
-    },
-    canAssigneeComment(){
-      return this.interviewInfo && this.interviewInfo.host && this.hasJoinInterview;
-    },
-    canEmployeeComment(){
-      return this.canSatisfaction;
-    },
-    canInterviewLog(){
-      return this.interviewConnect && this.hasJoinInterview;
-    },
-    canExitMeeting(){
-      return this.interviewConnect
-    },
-    canCloseMeeting(){
-      return this.interviewConnect && this.hasJoinInterview && this.interviewInfo.host;
-    },
-    canJoinMeeting(){
-      return this.interviewInfo && this.interviewInfo.businessStatus === 'interview' && !this.interviewConnect;
-    }
-  },
-  methods:{
-    initData(){
-      if (this.loading || !this.reviewId || !this.interviewId || !this.userInfo) return;
-      this.loading = true;
-
-      Promise.all([
-        this.$axiosUser('get',`/performance/interview/info/${this.userInfo.site_id}/${this.interviewId}`),
-        this.$axiosUser('get',`/performance/interview/chat/logs/${this.userInfo.site_id}/${this.interviewId}`),
-        this.$axiosUser('get',`/performance/cate/list/${this.userInfo.site_id}`),
-        this.$axiosUser('get',`/org/employees`),
-      ])
-        .then(([interviewRes,logRes,cateRes,employeeRes]) => {
-          if (interviewRes.data.code !== 1) throw new Error(interviewRes.data.message);
-          if (logRes.data.code !== 1) throw new Error(logRes.data.message);
-          if (cateRes.data.code !== 1) throw new Error(cateRes.data.message);
-          if (employeeRes.data.code !== 1) throw new Error(employeeRes.data.message);
-
-          this.interviewInfo = interviewRes.data.data || null;
-          this.interviewLogs = logRes.data.data.list || [];
-          this.cateList = (cateRes.data.data.list || []).map(cate => {
-            return {
-              cateId:cate.cateId,
-              name:cate.name,
-            }
-          });
-          this.employeeList = employeeRes.data.data || [];
-          this.$nextTick(() => {
-            if (this.$refs.chatLogRef) this.$refs.chatLogRef.scrollIntoView(true);
-          })
-        })
-        .catch(err => {
-          console.warn(err);
-        })
-        .finally(() => {
-          this.loading = false;
-        })
-    },
-    interviewUsers(){
-      if (this.loading) return;
-      this.loading = true;
-
-      Promise.all([
-        this.$axiosUser('get',`/performance/interview/users/${this.userInfo.site_id}/${this.interviewInfo.interviewId}`)
-      ])
-        .then(([userRes]) => {
-          if (userRes.data.code !== 1) throw new Error(userRes.data.message);
-
-          this.userList = userRes.data.data.list || [];
-        })
-        .catch(err => {
-          console.warn(err);
-        })
-        .finally(() => {
-          this.loading = false;
-        })
-    },
-    initMeeting(){
-      if (this.loading || (this.stompClient && this.interviewConnect) || !this.userInfo) return;
-      this.loading = true;
-
-      this.initMeetingState();
-
-      this.stompClient = Stomp.client(process.env.VUE_APP_WEBSOCKET_PERFORMANCE);
-      this.stompClient.connect(
-        {
-          at:getToken()
-        },
-        (res) => {
-          this.loading = false;
-          this.interviewConnect = true;
-
-          this.subscribe();
-
-          this.joinInterview();
-        },
-        (err) => {
-          console.warn('meeting err',err);
-          this.loading = false;
-        }
-      )
-    },
-    initMeetingState(){
-      this.stompClient = null;
-      this.interviewConnect = false;
-      this.hasJoinInterview = false;
-      this.userList = [];
-    },
-    subscribe(){
-      if (!this.stompClient || !this.interviewConnect) return;
-
-      this.stompClient.subscribe(
-        `/topic/interview/join/${this.interviewInfo.interviewId}`,
-        (message) => {
-          const user = JSON.parse(message.body);
-          if (!user) return;
-
-          if (user.id !== this.userInfo.id){
-            this.$notify({
-              title:user.name,
-              message:'加入会议',
-              type:'success',
-              duration:1000,
-            });
-            if(!this.userList.find(u => u.id === user.id)) this.userList.push(user);
-          } else {
-            this.interviewUsers();
-            this.hasJoinInterview = true;
-          }
-        }
-      );
-
-      this.stompClient.subscribe(
-        `/topic/interview/leave/${this.interviewInfo.interviewId}`,
-        (message) => {
-          const user = JSON.parse(message.body);
-          if (!user) return;
-
-          if (this.userInfo.id !== user.id){
-            this.$notify({
-              title:user.name,
-              message: '离开会议',
-              type:'success',
-              duration:1000,
-            });
-          } else {
-            this.disconnect();
-          }
-        }
-      );
-      this.stompClient.subscribe(
-        `/topic/interview/comment/assignee/${this.interviewInfo.interviewId}`,
-        (message) => {
-          if (!this.interviewInfo) return;
-          if (this.interviewInfo.assigneeComment !== message.body) {
-            this.interviewInfo.assigneeComment = message.body;
-          } else {
-            this.$notify({
-              message:'更新完毕',
-              type:'success',
-              duration:1000,
-            });
-          }
-        }
-      );
-      this.stompClient.subscribe(
-        `/topic/interview/comment/employee/${this.interviewInfo.interviewId}`,
-        (message) => {
-
-          if (!this.interviewInfo) return;
-          if (this.interviewInfo.employeeComment !== message.body){
-            this.interviewInfo.employeeComment = message.body;
-          } else {
-            this.$notify({
-              message:'更新完毕',
-              type:'success',
-              duration:1000,
-            });
-          }
-        }
-      );
-      this.stompClient.subscribe(
-        `/topic/interview/chat/log/${this.interviewInfo.interviewId}`,
-        (message) => {
-          let log = JSON.parse(message.body);
-          if (log) this.interviewLogs.push(log);
-          this.$nextTick(() => {
-            if (this.$refs.chatLogRef) this.$refs.chatLogRef.scrollIntoView(false);
-          })
-        }
-      );
-      this.stompClient.subscribe(
-        `/topic/interview/satisfaction/${this.interviewInfo.interviewId}`,
-        (message) => {
-          const tmp = JSON.parse(message.body);
-          if (tmp) this.interviewInfo.satisfactionLevel = tmp.satisfactionLevel || this.interviewInfo.satisfactionLevel;
-        }
-      );
-
-
-      this.stompClient.subscribe(
-        `/topic/interview/close/${this.interviewInfo.interviewId}`,
-        (message) => {
-          console.log('interview close',message);
-
-          const tmp = JSON.parse(message.body);
-          if (!tmp) return;
-
-          this.disconnect();
-          this.$notify({
-            message:'面谈已结束,退出会议模式',
-            type:'success',
-            duration:1000,
-          });
-
-          this.interviewInfo = tmp;
-        }
-      );
-    },
-    joinInterview(){
-      if (!this.stompClient || !this.interviewConnect) return;
-      this.stompClient.send(`/app/interview/join/${this.interviewInfo.interviewId}`);
-
-      this.interviewUsers();
-    },
-    leaveInterview(){
-      if (!this.stompClient || !this.interviewConnect) return;
-      this.stompClient.send(`/app/interview/leave/${this.interviewInfo.interviewId}`);
-    },
-    disconnect(){
-      if (!this.stompClient || !this.interviewConnect) return;
-
-      this.stompClient.disconnect();
-      this.initMeetingState();
-    },
-    apiSatisfaction(){
-      if (!this.canSatisfaction || this.loading) return;
-
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$http.post(`performance/interview/satisfaction/${this.userInfo.site_id}`,{interviewId:this.interviewInfo.interviewId,level:this.interviewInfo.satisfactionLevel}),
-      ])
-        .then(([levelRes]) => {
-          if (levelRes.code !== 1) throw new Error(levelRes.message);
-
-          this.interviewInfo = levelRes.data || null;
-
-          if (!this.interviewInfo) result = false;
-        })
-        .catch(err => {
-          result = false;
-          console.warn(err);
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) this.leaveInterview();
-        })
-    },
-    sendSatisfaction(){
-      if (!this.canSatisfaction) return;
-      if (!this.stompClient || !this.hasJoinInterview){
-        //普通面谈详情模式
-        this.apiSatisfaction();
-      } else {
-        //面谈会议模式
-        this.stompClient.send(
-          `/app/interview/satisfaction/${this.interviewInfo.interviewId}`,
-          {},
-          this.interviewInfo.satisfactionLevel
-        );
-      }
-    },
-    apiEmployeeComment(){
-      if (!this.canEmployeeComment || this.loading) return;
-
-      this.loading = true;
-
-      let result = true;
-      Promise.all([
-        this.$http.post(`performance/interview/comment/employee/${this.userInfo.site_id}`,{interviewId:this.interviewInfo.interviewId,comment:this.interviewInfo.employeeComment}),
-      ])
-        .then(([commentRes]) => {
-          if (commentRes.code !== 1) throw new Error(commentRes.message);
-
-          this.interviewInfo = commentRes.data || null;
-
-          if (!this.interviewInfo) result = false;
-        })
-        .catch(err => {
-          result = false;
-          console.warn(err);
-        })
-        .finally(() => {
-          this.loading = false;
-          if (!result) {
-            this.leaveInterview();
-          } else {
-            this.$notify({
-              message:'更新完毕',
-              type:'success',
-              duration:1000,
-            });
-          }
-        })
-    },
-    sendEmployeeComment(){
-      if (!this.canEmployeeComment) return;
-
-      if (!this.stompClient || !this.hasJoinInterview){
-        //普通面谈模式
-        this.apiEmployeeComment();
-      } else {
-        //面谈会议模式
-        this.stompClient.send(
-          `/app/interview/comment/employee/${this.interviewInfo.interviewId}`,
-          {},
-          this.interviewInfo.employeeComment
-        );
-      }
-    },
-    sendAssigneeComment(){
-      if (!this.canAssigneeComment) return;
-
-      this.stompClient.send(
-        `/app/interview/comment/assignee/${this.interviewInfo.interviewId}`,
-        {},
-        this.interviewInfo.assigneeComment
-      );
-
-    },
-    sendChatLog(){
-      if (!this.stompClient || !this.hasJoinInterview || !this.canInterviewLog || !this.chatContent) return;
-
-      this.stompClient.send(
-        `/app/interview/chat/log/${this.interviewInfo.interviewId}`,
-        {},
-        this.chatContent,
-      );
-
-      this.chatContent = '';
-    },
-    closeMeeting(){
-      if (!this.canCloseMeeting || !this.stompClient) return;
-
-      this.stompClient.send(`/app/interview/close/${this.interviewInfo.interviewId}`);
-    },
-  },
-  mounted(){
-    this.initData();
-  }
-
-}
-</script>
-
-
-<style scoped lang="scss">
-
-</style>

+ 0 - 596
src/newPerformance/components/PerReviewDetail.vue

@@ -1,596 +0,0 @@
-<template>
-  <el-container style="min-width: 1440px; height: 100%;">
-    <el-main v-if="reviewInfo">
-      <el-card style="height: 10%;margin-bottom: 20px;">
-        <el-row type="flex" justify="space-between" align="center">
-          <el-col>
-            <WaStstistics title="考核表" :value="reviewInfo.title" />
-          </el-col>
-          <el-col>
-            <WaStstistics title="周期种类" :value="cycleMap[reviewInfo.cycleType] || '--'" />
-          </el-col>
-          <el-col>
-            <WaStstistics title="考核时间" :value="timeScope" />
-          </el-col>
-          <el-col>
-            <WaStstistics title="考核状态" :value="statusMap[reviewInfo.status] || '--'" />
-          </el-col>
-          <el-col>
-            <WaStstistics title="评分" :value="reviewInfo.score === null ? '--' : reviewInfo.score" />
-          </el-col>
-          <el-col>
-            <WaStstistics title="考核中的指标"
-              :value="reviewInfo.indicators.length > 0 ? (reviewInfo.indicators.length - indicatorEnd) : '--'" />
-          </el-col>
-          <el-col>
-            <WaStstistics title="考核完成的指标" :value="indicatorEnd" />
-          </el-col>
-          <el-col v-if="reviewInfo.interviews && reviewInfo.interviews.length > 0">
-            <el-dropdown trigger="click">
-              <el-button type="text">
-                面谈记录
-              </el-button>
-              <el-dropdown-menu>
-                <el-dropdown-item v-for="interview in reviewInfo.interviews" :key="interview.interviewId">
-                  <span @click="openInterview(interview.interviewId)">
-                    {{ interview.createTime }}
-                  </span>
-                </el-dropdown-item>
-              </el-dropdown-menu>
-            </el-dropdown>
-          </el-col>
-        </el-row>
-      </el-card>
-      <el-card style="height: calc(90% - 20px); position: relative; ">
-
-        <Seal v-if="reviewInfo.levelName" :text="reviewInfo.levelName" :size="100" font-size="24px" :top="10" :left="20"
-          :rotate="-30" :z-index="100" />
-        <div class="flex-box-ce" style="margin-bottom: 10px; justify-content: flex-end;">
-          <el-button type="text" @click="openTargetList(reviewInfo.okrs)">个人OKR</el-button>
-          <el-button type="text" @click="openTargetList(reviewInfo.packageOkrs)"
-            style="margin-right: 10px;">考核表OKR</el-button>
-          <el-switch v-model="showNode" active-text="显示考核节点" inactive-text="隐藏考核节点" />
-        </div>
-        <el-table :data="indicators">
-          <el-table-column prop="title" label="指标" fixed="left" show-overflow-tooltip align="center" />
-          <el-table-column prop="content" label="规则" show-overflow-tooltip align="center" />
-          <el-table-column prop="target" label="目标" align="center">
-            <template slot-scope="scope">
-              {{ scope.row.target === null ? '--' : (scope.row.unit ? `${scope.row.target} ${scope.row.unit}` :
-              scope.row.target) }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="result" label="结果" align="center">
-            <template slot-scope="scope">
-              {{ scope.row.result === null ? '--' : (scope.row.unit ? `${scope.row.result} ${scope.row.unit}` :
-              scope.row.result) }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="weight" label="权重" align="center">
-            <template slot-scope="scope">
-              {{ scope.row.weight ? `${scope.row.weight} %` : '--' }}
-            </template>
-          </el-table-column>
-          <el-table-column prop="businessStatus" label="考核状态" align="center">
-            <template slot-scope="scope">
-              <el-link :type="scope.row.businessStatus === 'end' ? 'primary' : 'warning'">
-                {{ indicatorStatusMap[scope.row.businessStatus] || '--' }}
-              </el-link>
-            </template>
-          </el-table-column>
-          <el-table-column prop="score" label="得分" align="center" />
-          <el-table-column prop="okrs" label="指标OKR" align="center">
-            <template slot-scope="scope">
-              <el-link v-if="scope.row.okrs && scope.row.okrs.length > 0" type="primary"
-                @click="openTargetList(scope.row.okrs)">
-                指标OKR
-              </el-link>
-              <span v-else class="fontColorC">暂无关联</span>
-            </template>
-          </el-table-column>
-          <el-table-column v-if="showNode" prop="targetConfirms" label="目标确认" align="center">
-            <template slot-scope="scope">
-              <el-link v-if="!scope.row.targetConfirms.enable" type="info">
-                禁用
-              </el-link>
-              <el-link v-else-if="scope.row.targetConfirms.tasks.length <= 0" type="info">
-                未开始
-              </el-link>
-              <template v-else>
-                <div @click="openTasks(scope.row.targetConfirms.tasks,'目标确认任务',scope.row.unit)">
-                  <el-link v-if="scope.row.targetConfirms.finishCount > 0" type="primary" style="margin-right: 5px;"
-                    icon="el-icon-check">
-                    {{ scope.row.targetConfirms.finishCount }}
-                  </el-link>
-                  <el-link v-if="scope.row.targetConfirms.runningCount > 0" type="warning" icon="el-icon-warning">
-                    {{ scope.row.targetConfirms.runningCount }}
-                  </el-link>
-                </div>
-              </template>
-            </template>
-          </el-table-column>
-          <el-table-column v-if="showNode" prop="resultInput" label="结果录入">
-            <template slot-scope="scope">
-              <el-link v-if="!scope.row.resultInput.enable" type="info">
-                禁用
-              </el-link>
-              <el-link v-else-if="scope.row.resultInput.tasks.length <= 0" type="info">
-                未开始
-              </el-link>
-              <template v-else>
-                <div @click="openTasks(scope.row.resultInput.tasks,'结果录入任务',scope.row.unit)">
-                  <el-link v-if="scope.row.resultInput.finishCount > 0" type="primary" style="margin-right: 5px;"
-                    icon="el-icon-check">
-                    {{ scope.row.resultInput.finishCount }}
-                  </el-link>
-                  <el-link v-if="scope.row.resultInput.runningCount > 0" type="warning" icon="el-icon-warning">
-                    {{ scope.row.resultInput.runningCount }}
-                  </el-link>
-                </div>
-              </template>
-            </template>
-          </el-table-column>
-          <el-table-column v-if="showNode" prop="scoreSelf" label="自评">
-            <template slot-scope="scope">
-              <el-link v-if="!scope.row.scoreSelf.enable" type="info">
-                禁用
-              </el-link>
-              <el-link v-else-if="scope.row.scoreSelf.tasks.length <= 0" type="info">
-                未开始
-              </el-link>
-              <template v-else>
-                <div @click="openTasks(scope.row.scoreSelf.tasks,'自评任务',scope.row.unit)">
-                  <el-link v-if="scope.row.scoreSelf.finishCount > 0" type="primary" style="margin-right: 5px;"
-                    icon="el-icon-check">
-                    {{ scope.row.scoreSelf.finishCount }}
-                  </el-link>
-                  <el-link v-if="scope.row.scoreSelf.runningCount > 0" type="warning" icon="el-icon-warning">
-                    {{ scope.row.scoreSelf.runningCount }}
-                  </el-link>
-                </div>
-              </template>
-            </template>
-          </el-table-column>
-          <el-table-column v-if="showNode" prop="scoreEachOther" label="互评">
-            <template slot-scope="scope">
-              <el-link v-if="!scope.row.scoreEachOther.enable" type="info">
-                禁用
-              </el-link>
-              <el-link v-else-if="scope.row.scoreEachOther.tasks.length <= 0" type="info">
-                未开始
-              </el-link>
-              <template v-else>
-                <div @click="openTasks(scope.row.scoreEachOther.tasks,'互评任务',scope.row.unit)">
-                  <el-link v-if="scope.row.scoreEachOther.finishCount > 0" type="primary" style="margin-right: 5px;"
-                    icon="el-icon-check">
-                    {{ scope.row.scoreEachOther.finishCount }}
-                  </el-link>
-                  <el-link v-if="scope.row.scoreEachOther.runningCount > 0" type="warning" icon="el-icon-warning">
-                    {{ scope.row.scoreEachOther.runningCount }}
-                  </el-link>
-                </div>
-              </template>
-            </template>
-          </el-table-column>
-          <el-table-column v-if="showNode" prop="scores" label="评分">
-            <template slot-scope="scope">
-              <el-link v-if="!scope.row.scores.enable" type="info">
-                禁用
-              </el-link>
-              <el-link v-else-if="scope.row.scores.tasks.length <= 0" type="info">
-                未开始
-              </el-link>
-              <template v-else>
-                <div @click="openTasks(scope.row.scores.tasks,'评分任务',scope.row.unit)">
-                  <el-link v-if="scope.row.scores.finishCount > 0" type="primary" style="margin-right: 5px;"
-                    icon="el-icon-check">
-                    {{ scope.row.scores.finishCount }}
-                  </el-link>
-                  <el-link v-if="scope.row.scores.runningCount > 0" type="warning" icon="el-icon-warning">
-                    {{ scope.row.scores.runningCount }}
-                  </el-link>
-                </div>
-              </template>
-            </template>
-          </el-table-column>
-          <el-table-column v-if="showNode" prop="reviews" label="审批">
-            <template slot-scope="scope">
-              <el-link v-if="!scope.row.reviews.enable" type="info">
-                禁用
-              </el-link>
-              <el-link v-else-if="scope.row.reviews.tasks.length <= 0" type="info">
-                未开始
-              </el-link>
-              <template v-else>
-                <div @click="openTasks(scope.row.reviews.tasks,'审批任务',scope.row.unit)">
-                  <el-link v-if="scope.row.reviews.finishCount > 0" type="primary" style="margin-right: 5px;"
-                    icon="el-icon-check">
-                    {{ scope.row.reviews.finishCount }}
-                  </el-link>
-                  <el-link v-if="scope.row.reviews.runningCount > 0" type="warning" icon="el-icon-warning">
-                    {{ scope.row.reviews.runningCount }}
-                  </el-link>
-                </div>
-              </template>
-            </template>
-          </el-table-column>
-        </el-table>
-      </el-card>
-    </el-main>
-
-    <el-dialog v-if="tasksInfo.title" :visible.sync="showTasks" :title="tasksInfo.title" center append-to-body>
-      <div style="max-height: 600px; overflow-y: auto;">
-        <el-card v-if="tasksInfo.tasks" v-for="task in tasksInfo.tasks" :key="task.taskId" style="margin-bottom: 20px;">
-          <el-descriptions border :column="4" :title="task.assigneeName" size="mini" direction="vertical">
-            <el-descriptions-item label="任务状态">{{ task.state === 'completed' ? '已处理' : '待处理' }}</el-descriptions-item>
-            <el-descriptions-item v-if="task.score !== null" label="评分">
-              {{ task.score }}
-            </el-descriptions-item>
-            <el-descriptions-item v-if="task.result !== null" label="结果">
-              {{ tasksInfo.unit ? `${task.result} ${tasksInfo.unit}` : task.result }}
-            </el-descriptions-item>
-            <el-descriptions-item label="评论">
-              {{ task.comment }}
-            </el-descriptions-item>
-
-            <el-descriptions-item v-if="task.files && task.files.length > 0" label="附件列表">
-              <div class="files">
-                <div class="file-list">
-                  <div class="file-item" v-for="file in task.files" @click="onFilePreView(file)">
-                    {{ file | filterFileName }}
-                  </div>
-                </div>
-              </div>
-            </el-descriptions-item>
-
-          </el-descriptions>
-        </el-card>
-      </div>
-
-    </el-dialog>
-
-
-    <TargetListComp v-if="dialogVisible" :dialogVisible="dialogVisible" :ids="okrs" @close="closeTargetList">
-    </TargetListComp>
-  </el-container>
-</template>
-
-
-<script>
-import WaStstistics from "./tool/WaStstistics.vue";
-import moment from "moment";
-import Template from "../../examine/components/Template.vue";
-import Seal from "./tool/Seal.vue";
-import PerInterview from "./PerInterview.vue";
-import TargetListComp from "@/performance/views/assessManagement/TargetListComp.vue";
-
-export default {
-  name: "PerReviewDetail",
-  components: { PerInterview, Seal, Template, WaStstistics, TargetListComp },
-  props: {
-    reviewId:{
-      type: Number,
-      required: true
-    }
-  },
-  data(){
-    return {
-      userInfo:this.$userInfo(),
-      loading:false,
-      reviewInfo: null,
-      dialogVisible: false,
-      cycleMap:{
-        0:'未定义',
-        1:'年度',
-        2:'半年度',
-        3:'季度',
-        4:'月度',
-      },
-      statusMap:{
-        0:'考核中',
-        1:'已结束',
-        2:'面谈',
-      },
-      indicatorStatusMap:{
-        start:'进入考核',
-        target_confirm:'目标确认中',
-        result_input:'结果录入中',
-        score_self:'自评中',
-        score_each_other:'互评中',
-        score:'评分中',
-        review:'审批中',
-        cc:'抄送',
-        end:'已结束',
-      },
-      showNode:false,
-      showTasks:false,
-      tasks:[],
-      tasksInfo:{
-        title:'',
-        unit:'',
-        tasks:[]
-      },
-      okrs: []
-    }
-  },
-
-  filters: {
-
-    filterFileName(str) {
-      if (str) {
-        let lastIndex = str.lastIndexOf("/")
-        return str.substr(lastIndex + 1, str.length - 1);
-      }
-    }
-  },
-  computed:{
-    timeScope(){
-      if (!this.reviewInfo || !this.reviewInfo.startTime || !this.reviewInfo.endTime) return '--';
-      return moment(this.reviewInfo.startTime).format('YY/MM/DD') + ' ~ ' + moment(this.reviewInfo.endTime).format('YY/MM/DD');
-    },
-    indicatorEnd(){
-      if (!this.reviewInfo || this.reviewInfo.indicators.length <= 0) return '--';
-      return this.reviewInfo.indicators.filter(indicator => indicator.businessStatus === 'end').length;
-    },
-    indicators(){
-      return !this.reviewInfo ? [] : this.reviewInfo.indicators.map(item => {
-        const indicator = {
-          reviewIndicatorId:item.reviewIndicatorId,
-          reviewTitle:item.reviewTitle,
-          title:item.title,
-          content:item.content,
-          target:item.target,
-          result:item.result,
-          score:item.score,
-          unit:item.unit,
-          weight:item.weight,
-          businessStatus:item.businessStatus,
-          targetConfirms:null,
-          resultInput:null,
-          scoreSelf:null,
-          scoreEachOther:null,
-          scores:null,
-          reviews: null,
-          okrs: item.okrs,
-          cc:null,
-        };
-        item.flow.nodes.forEach(node => {
-          switch (node.type){
-            case 'targetConfirms':
-              const targetConfirms = {
-                enable:node.enable,
-                tasks:[],
-                runningCount:0,
-                finishCount:0,
-              }
-              if (node.children && node.children.length > 0){
-                node.children.forEach(child => {
-                  if (child.tasks && child.tasks.length > 0) {
-                    child.tasks.forEach(task => {
-                      targetConfirms.tasks.push(task);
-                      if (task.state === 'completed'){
-                        targetConfirms.finishCount ++;
-                      }else {
-                        targetConfirms.runningCount ++;
-                      }
-                    })
-                  }
-                })
-              }
-              indicator.targetConfirms = targetConfirms;
-              break;
-            case 'resultInput':
-              const resultInput = {
-                enable:node.enable,
-                tasks:[],
-                runningCount:0,
-                finishCount:0,
-              }
-
-              if (node.tasks && node.tasks.length > 0){
-                node.tasks.forEach(task => {
-                  resultInput.tasks.push(task);
-                  if (task.state === 'completed'){
-                    resultInput.finishCount ++;
-                  }else {
-                    resultInput.runningCount ++;
-                  }
-                })
-              }
-
-              indicator.resultInput = resultInput;
-              break;
-            case 'scoreSelf':
-              const scoreSelf = {
-                enable:node.enable,
-                tasks:[],
-                runningCount:0,
-                finishCount:0,
-              }
-
-              if (node.tasks && node.tasks.length > 0){
-                node.tasks.forEach(task => {
-                  scoreSelf.tasks.push(task);
-                  if (task.state === 'completed'){
-                    scoreSelf.finishCount ++;
-                  }else {
-                    scoreSelf.runningCount ++;
-                  }
-                })
-              }
-              indicator.scoreSelf = scoreSelf;
-              break;
-            case 'scoreEachOther':
-              const scoreEachOther = {
-                enable:node.enable,
-                tasks:[],
-                runningCount:0,
-                finishCount:0,
-              }
-
-              if (node.tasks && node.tasks.length > 0){
-                node.tasks.forEach(task => {
-                  scoreEachOther.tasks.push(task);
-                  if (task.state === 'completed'){
-                    scoreEachOther.finishCount ++;
-                  }else {
-                    scoreEachOther.runningCount ++;
-                  }
-                })
-              }
-              indicator.scoreEachOther = scoreEachOther;
-              break;
-            case 'scores':
-              const scores = {
-                enable:node.enable,
-                tasks:[],
-                runningCount:0,
-                finishCount:0,
-              }
-
-              if (node.children && node.children.length > 0){
-                node.children.forEach(child => {
-                  if (child.tasks && child.tasks.length > 0) {
-                    child.tasks.forEach(task => {
-                      scores.tasks.push(task);
-                      if (task.state === 'completed'){
-                        scores.finishCount ++;
-                      }else {
-                        scores.runningCount ++;
-                      }
-                    })
-                  }
-                })
-              }
-              indicator.scores = scores;
-              break;
-            case 'reviews':
-              const reviews = {
-                enable:node.enable,
-                tasks:[],
-                runningCount:0,
-                finishCount:0,
-              }
-
-              if (node.children && node.children.length > 0){
-                node.children.forEach(child => {
-                  if (child.tasks && child.tasks.length > 0) {
-                    child.tasks.forEach(task => {
-                      reviews.tasks.push(task);
-                      if (task.state === 'completed'){
-                        reviews.finishCount ++;
-                      }else {
-                        reviews.runningCount ++;
-                      }
-                    })
-                  }
-                })
-              }
-              indicator.reviews = reviews;
-              break;
-            case 'cc':
-              const cc = {
-                enable:node.enable,
-                tasks:[],
-                runningCount:0,
-                finishCount:0,
-              }
-              indicator.cc = cc;
-              break;
-          }
-        });
-
-        return indicator;
-      });
-
-    }
-  },
-  watch:{
-    reviewId(v){
-      if (v) this.initData();
-    }
-  },
-  methods:{
-    initData(){
-      if (this.loading || !this.reviewId) return;
-      this.loading = true;
-
-      this.showNode = false;
-      this.reviewInfo = null;
-
-      Promise.all([
-        this.$axiosUser('get',`/performance/statistics/review/info/${this.userInfo.site_id}/${this.reviewId}`)
-      ])
-        .then(([reviewRes]) =>{
-          if (reviewRes.data.code !== 1) throw new Error(reviewRes.data.message);
-
-          this.reviewInfo = reviewRes.data.data || null;
-        })
-        .catch(err => {
-          console.warn(err);
-        })
-        .finally(() => {
-          this.loading = false;
-        })
-    },
-    openTasks(tasks,title,unit){
-      if (!tasks || tasks.length <= 0) return;
-      this.tasksInfo.tasks = tasks;
-      this.tasksInfo.title = title || '任务信息';
-      this.tasksInfo.unit = unit || '';
-      this.showTasks = true;
-    },
-    openInterview(interviewId){
-      if (!interviewId || !this.reviewInfo) return;
-      window.open(`#/per/interview/${this.reviewId}/${interviewId}`);
-    },
-
-    closeTargetList() {
-      this.dialogVisible = false
-    },
-
-    openTargetList(okrs) {
-      if (okrs && okrs.length > 0) {
-        this.okrs = okrs
-        this.dialogVisible = true
-      }
-      else {
-        return this.$message.error("暂无关联okr")
-      }
-    },
-
-    onFilePreView(url) {
-      window.open(url, '_blank');
-    },
-  },
-  mounted() {
-    this.initData();
-  }
-
-}
-</script>
-
-<style scoped lang="scss">
-    .files {
-      display: flex;
-      flex-direction: column;
-      padding: 5px;
-      background: #f7f7f7;
-      border-radius: 6px;
-  
-      .title {
-        color: #999;
-      }
-  
-      .file-item {
-        color: #999;
-        transition: 0.2s;
-  
-        &:hover {
-          text-decoration: underline;
-          cursor: pointer;
-        }
-      }
-    }
-
-</style>

+ 0 - 272
src/newPerformance/components/PerformanceCoaching.vue

@@ -1,272 +0,0 @@
-<template>
-    <div class="coaching-container">
-
-        <div class="base-info-title flex-box-ce">
-            <div class="line"></div>
-            绩效辅导
-            <el-cascader ref="dept" v-model="selected_dept_ids" size="small" style="width: 300px; margin-left: 10px; "
-                :options="deptList" @change="deptChange" :props="{ checkStrictly: true, multiple: true }" filterable
-                change-on-select placeholder="请选择部门" clearable></el-cascader>
-        </div>
-
-        <el-table v-loading="loading" :data="tableData" style="width: 100%"  :header-cell-style="{ background: '#f5f7fa' }" border stripe>
-            <el-table-column prop="title" label="面谈标题" align="center">
-            </el-table-column>
-            <el-table-column prop="employeeName" label="员工姓名" align="center">
-            </el-table-column>
-
-            <!-- <el-table-column label="部门" align="center">
-            </el-table-column> -->
-
-            <el-table-column align="center" prop="createTime" label="面谈创建时间">
-            </el-table-column>
-
-            <el-table-column align="center" prop="businessStatus" label="状态">
-                <template slot-scope="scope">
-                    
-                    <div v-if="scope.row.businessStatus === 'start'">开始</div>
-                    <div v-if="scope.row.businessStatus === 'interview'">面谈中</div>
-                    <div v-if="scope.row.businessStatus === 'end'">结束</div>
-                </template>
-            </el-table-column>
-
-            <el-table-column align="center" label="操作">
-                <template slot-scope="scope">
-                    <el-button v-if="scope.row.businessStatus === 'interview'" type="text" @click="getDetails(scope.row)">查看面谈详情</el-button>
-                    <el-button v-if="scope.row.businessStatus === 'end'" type="text" @click="getDetails2()">查看归档记录</el-button>
-                </template>
-            </el-table-column>
-        </el-table>
-
-        <el-dialog :visible.sync="showReviewDetail" title="考核详情" center fullscreen>
-            <div style="height: 85vh;">
-                <PerReviewDetail v-if="currentReviewId" :review-id="currentReviewId" />
-            </div>
-        </el-dialog>
-
-        <el-dialog :visible.sync="dialogVisible" title="归档记录" center width="600px">
-            <div class="dialog-content" style="">
-                <el-descriptions title="" direction="vertical" :column="1" border style="height: 100%;">
-                    <el-descriptions-item label="主持人记录">
-                        <div class="label">存在问题:</div>
-                        <div class="value">暂无发现问题</div>
-                        <div class="label">评价及意见:</div>
-                        <div class="value">还有很大的提升空间</div>
-                        <div class="label">改进方案:</div>
-                        <div class="value">1.改进措施1</div>
-                        <div class="value">2.改进措施2</div>
-                        <div class="value">3.改进措施3</div>
-                        <div class="value">4.改进措施4</div>
-                    </el-descriptions-item>
-                    <el-descriptions-item label="被考核人记录">
-                        <div class="label">存在问题:</div>
-                        <div class="value">暂无发现问题</div>
-                        <div class="label">评价及意见:</div>
-                        <div class="value">还有很大的提升空间</div>
-                        <div class="label">改进方案:</div>
-                        <div class="value">1.改进措施1</div>
-                        <div class="value">2.改进措施2</div>
-                        <div class="value">3.改进措施3</div>
-                        <div class="value">4.改进措施4</div>
-                    </el-descriptions-item>
-                    <el-descriptions-item label="其他人发言记录">
-                        <div class="label">张三</div>
-                        <div class="value">暂无发现问题</div>
-                        <div class="label">李四</div>
-                        <div class="value">暂无发现问题</div>
-                        <div class="label">王五</div>
-                        <div class="value">暂无发现问题</div>
-                        <div class="label">赵六</div>
-                        <div class="value">暂无发现问题</div>
-                    </el-descriptions-item>
-                </el-descriptions>
-            </div>
-        </el-dialog>
-
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import PerReviewDetail from "./PerReviewDetail.vue";
-export default {
-    components: {
-        PerReviewDetail
-    },
-    data() {
-        return {
-            loading: false,
-            tableData: [],
-            total: 0,
-            params: {
-                reviewId: "",
-                keyword: "",
-                employeeId: "",
-                deptIds: "",
-                type: "",
-                page: 1,
-                pageSize: 10
-            },
-            dialogVisible: false,
-            showReviewDetail: false,
-            currentReviewId: '',
-            selected_dept_ids: [],
-            deptList: [], // 部门列表 - 树形结构
-            dept_list: [], // 部门列表
-        }
-    },
-
-    created() {
-        this.getInterviewList();
-        this.get_dept_list();
-    },
-
-    computed: {
-        ...mapGetters(['user_info'])
-    },
-    methods: {
-        getInterviewList() {
-            let url = `/performance/interview/list/${this.user_info.site_id}`
-            this.$axiosUser("get", url, this.params).then(res => {
-                this.tableData = res.data.data.list
-            })
-        },
-        //待办
-        getNewAgency() {
-            this.loading = true;
-            this.params.type = 7
-            this.$axiosUser("get", `/performance/review/job/${this.user_info.site_id}`, this.params).then(res => {
-                this.tableData = [];
-                let list = res.data.data.list
-                if (list && list.length > 0) {
-                    list.forEach(item => {
-                        if (item.jobNew) this.tableData.push(item.jobNew)
-                    })
-                    this.total = this.tableData.length || 0;
-                    console.log(this.tableData);
-                    this.tableData[0].status = 1
-                    this.tableData.push({
-                        reviewTitle: "2025-04-01 至 2025-04-30 月度考核",
-                        employeeName: "尹勇",
-                        timeRemark: "2025-04-24 09:00",
-                        status: 0
-                    })
-                    this.loading = false;
-                }
-                // this.editableTabs.forEach(item => {
-                //     if (item.name == this.activeName) item.num = res.data.data.total
-                // })
-                
-            })
-        },
-
-        deptChange(val) {
-        },
-
-        getDetails(row) {
-            this.currentReviewId = row.reviewId;
-            this.showReviewDetail = true;
-        },
-
-        getDetails2() {
-            this.dialogVisible = true
-        },
-        // 处理部门树状结构数据
-        getTreeData(data) {
-            for (var i = 0; i < data.length; i++) {
-                data[i].checked = false;
-                if (data[i].children.length < 1) {
-                    // children若为空数组,则将children设为undefined
-                    data[i].children = undefined;
-                } else {
-                    // children若不为空数组,则继续 递归调用 本方法
-                    this.getTreeData(data[i].children);
-                }
-            }
-            return data;
-        },
-
-        // 获取部门
-        get_dept_list() {
-            this.$axiosUser('get', '/api/pro/department/tree', '', 'v2').then(res => {
-                this.dept_list = res.data.data.list; // 用来回显选择的部门数据
-                this.deptList = this.getTreeData(this.dept_list); // 处理成树状结构
-            });
-        },
-    }
-    
-    }
-
-
-</script>
-
-<style scoped="scoped" lang="scss">
-
-.coaching-container {
-    width: 100%;
-    height: 100%;
-    background-color: #fff;
-    border-radius: 5px;
-    padding: 10px;
-    box-sizing: border-box;
-    .base-info-title {
-        width: 100%;
-        height: 50px;
-        font-size: 16px;
-        font-weight: 600;
-        margin-bottom: 10px;
-        .line {
-            width: 3px;
-            height: 18px;
-            background: #409eff;
-            margin: 0 10px;
-        }
-    }
-}
-
-
-
-.dialog-content {
-    width: 100%;
-    height: 500px;
-    overflow-y: auto;
-    padding-bottom: 20px;
-    box-sizing: border-box;
-    /* 设置滚动条的宽度和背景色 */
-    &::-webkit-scrollbar {
-        width: 6px;
-        height: 6px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    &::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    &::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    &::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-        }
-    .label {
-        font-size: 14px;
-        margin-bottom: 5px;
-        font-weight: 600;
-    }
-    
-    .value {
-        padding-left: 20px;
-        color: #888;
-        margin-bottom: 5px;
-    }
-    
-}
-</style>

+ 0 - 785
src/newPerformance/components/PerformanceInterview.vue

@@ -1,785 +0,0 @@
-<template>
-    <div class="all">
-        <div class="flex-box-ce header" style="">
-            <div class="btn-box">
-                <el-button v-if="businessStatus === 'interview' && !interviewConnect" type="primary" size="small"
-                    @click="initMeeting()">加入面谈</el-button>
-                <el-button v-if="interviewConnect" type="warning" size="small" @click="leaveInterview()">离开面谈</el-button>
-                <el-button v-if="interviewConnect" type="danger" size="small" @click="finishInterview()">结束面谈</el-button>
-            </div>
-            <div>
-                <el-rate v-model="value" @change="sendSatisfaction()" :disable="canSatisfaction"></el-rate>
-            </div>
-        </div>
-
-        <div class="examine-info">
-            <div class="flex-box-ce" style="justify-content: space-between; padding: 5px ; box-sizing: border-box;">
-                <div>考核信息</div>
-                <div @click="detailsDialog = true">查看更多</div>
-            </div>
-            <el-descriptions :column="3" border>
-                <el-descriptions-item>
-                    <template slot="label">
-                        姓名
-                    </template>
-                    <div class="flex-box-ce" v-if="interviewInfo && interviewInfo.employee">
-                        <userImage :id="interviewInfo.employee.id" :img_url="interviewInfo.employee.imgUrl"
-                            :user_name="interviewInfo.employee.employeeName" width="30px" height="30px"
-                            style="margin-right: 5px;"></userImage>
-                        {{ interviewInfo && interviewInfo.employee && interviewInfo.employee.name || '--' }}
-                    </div>
-
-                </el-descriptions-item>
-                <el-descriptions-item>
-                    <template slot="label">
-                        考核名称
-                    </template>
-                    {{ interviewInfo && interviewInfo.reviewInfo && interviewInfo.reviewInfo.title || '--'}}
-                </el-descriptions-item>
-                <el-descriptions-item>
-                    <template slot="label">
-                        考核周期
-                    </template>
-                    <el-tag size="small">{{ interviewInfo && interviewInfo.reviewInfo &&
-                        interviewInfo.reviewInfo.cycleType | formatCycleType }}</el-tag>
-                </el-descriptions-item>
-
-                <el-descriptions-item>
-                    <template slot="label">
-                        考核时间
-                    </template>
-                    {{ interviewInfo && interviewInfo.reviewInfo && interviewInfo.reviewInfo.startTime | formatDate }}
-                    至
-                    {{ interviewInfo && interviewInfo.reviewInfo && interviewInfo.reviewInfo.endTime | formatDate }}
-                </el-descriptions-item>
-                <el-descriptions-item>
-                    <template slot="label">
-                        评分
-                    </template>
-                    {{ interviewInfo && interviewInfo.reviewInfo && interviewInfo.reviewInfo.score }}
-                </el-descriptions-item>
-                <el-descriptions-item>
-                    <template slot="label">
-                        评级
-                    </template>
-                    {{ interviewInfo && interviewInfo.reviewInfo && interviewInfo.reviewInfo.levelName }}
-                </el-descriptions-item>
-
-            </el-descriptions>
-        </div>
-
-        <div class="flex-box-ce flex-1" style="height: 100%; ">
-            <div class="left-box">
-                <div class="flex-box-ce" style="margin-bottom: 10px;">
-                    <!-- 主持人记录 -->
-                    <div class="emcee-record">
-                        <div class="title">主持人记录</div>
-                        <div class="content" v-if="interviewInfo && interviewInfo.assigneeComment">
-                            <el-input type="textarea" v-model="interviewInfo.assigneeComment" placeholder="输入内容"
-                                rows="5" @keydown.native="sendAssigneeComment($event)"
-                                :disable="canAssigneeComment"></el-input>
-                        </div>
-                    </div>
-                    <!-- 考核人记录 -->
-                    <div class="examinee-record">
-                        <div class="title">考核人记录</div>
-                        <div class="content" v-if="interviewInfo && interviewInfo.employeeComment">
-                            <el-input type="textarea" v-model="interviewInfo.employeeComment" placeholder="输入内容"
-                                rows="5" @keyup.enter.native="sendEmployeeComment($event)"></el-input>
-                        </div>
-                    </div>
-                </div>
-                <div class="input-box flex-1">
-                    <el-input type="textarea" v-model="chatLog" placeholder="输入内容" rows="5"
-                        @keyup.enter.native="sendChatLog($event)"></el-input>
-                    <div class="flex-box-ce" style="margin-top: 10px;">
-                        <el-button type="primary" size="small" style="margin-left: auto;" @click="sendChatLog2()">
-                            发 送
-                        </el-button>
-                    </div>
-                </div>
-            </div>
-
-            <!-- 聊天记录 -->
-            <div class="chat-record">
-                <div class="chat-record-title">聊天记录</div>
-                <div class="scroll-bar"
-                    style="height: 500px; overflow-y: auto; padding-bottom: 50px; box-sizing: border-box;">
-                    <div class="chat-item" v-for="item in chatList" :key="item.logId">
-                        <div class="flex-box-ce" style="justify-content: space-between;">
-                            <div class="flex-box-ce">
-                                <userImage :id="item.employeeId" :img_url="item.imgUrl" :user_name="item.employeeName"
-                                    width="30px" height="30px" style="margin-right: 5px;"></userImage>
-                                {{ item.employeeName }}
-                            </div>
-                            <div class="fontColorC">
-                                {{ item.ct }}
-                            </div>
-                        </div>
-
-                        <div class="content fontColorC">
-                            {{ item.content }}
-                        </div>
-                    </div>
-                    <div ref="chatLogRef"></div>
-                </div>
-            </div>
-        </div>
-
-        <el-drawer title="考核信息" :visible.sync="detailsDialog" direction="rtl" :before-close="handleClose" size="70%">
-            <!-- <el-descriptions :column="1" border style="padding: 0 5px; box-sizing: border-box;">
-                <el-descriptions-item>
-                    <template slot="label">
-                        姓名
-                    </template>
-                </el-descriptions-item>
-            </el-descriptions> -->
-            <!-- <el-table :data="tableData" style="width: 100%">
-                <el-table-column prop="title" label="指标名称" width="width">
-                </el-table-column>
-            </el-table> -->
-            <el-table :class="isShow ? 'fadeInDown animated' : 'fadeInUp animated'" :data="tableData"
-                stripe style="width: 100%; margin-bottom: 20px;" :height="600" border
-                :header-cell-style="{ background: '#f5f7fa' }" >
-                <el-table-column prop="title" label="指标" align="center" min-width="200" fixed="left">
-                </el-table-column>
-                <el-table-column prop="content" label="规则" align="center" min-width="200">
-                    <template slot-scope="scope">
-                        <el-tooltip class="item" effect="dark" placement="top">
-                            <div v-html="scope.row.content" slot="content" style="max-width:300px"></div>
-                            <div class="oneLine">{{ scope.row.content }}</div>
-                        </el-tooltip>
-                    </template>
-                </el-table-column>
-                <el-table-column prop="target" label="目标" align="center" min-width="100">
-                </el-table-column>
-                <el-table-column prop="unit" label="单位" align="center" min-width="100">
-                </el-table-column>
-                <el-table-column prop="weight" label="权重" align="center" min-width="100">
-                </el-table-column>
-                <el-table-column prop="result" label="结果值" align="center" min-width="100">
-                </el-table-column>
-                <el-table-column prop="formulae" label="计算公式" align="center" min-width="140">
-                    <template slot-scope="scope">
-                        <el-button v-if="scope.row.expression && scope.row.expression.formulas.length > 0"
-                            @click="openFormula(scope.row, scope.$index)">
-                            {{ scope.row.expression && scope.row.expression.formulas.length > 0 ? `公式
-                            ${scope.row.expression.formulas.length} 条` : '公式' }}
-                        </el-button>
-                        <div v-else style="color: #999;">暂无公式</div>
-                    </template>
-                </el-table-column>
-
-
-                <el-table-column prop="businessStatus" label="指标考核状态" align="center" min-width="120">
-                    <template slot-scope="scope">
-                        <div v-if="scope.row.businessStatus == 'end'" class="green-color">已结束</div>
-                        <div v-else class="orange-color">考核中</div>
-                    </template>
-                </el-table-column>
-
-                <el-table-column prop="confirm_target" label="确认目标" align="center" width="80" fixed="right">
-                    <template slot-scope="scope">
-                        <el-switch v-if="!scope.row.flow.nodes[0].enable" v-model="scope.row.flow.nodes[0].enable"
-                            disabled></el-switch>
-                        <ShowHandlerComp v-else :show-data="scope.row.flow.nodes[0]" />
-                    </template>
-                </el-table-column>
-                <el-table-column prop="input_result" label="录入结果" align="center" width="80" fixed="right">
-                    <template slot-scope="scope">
-                        <el-switch v-if="!scope.row.flow.nodes[1].enable" v-model="scope.row.flow.nodes[1].enable"
-                            disabled></el-switch>
-                        <ShowHandlerComp v-else :show-data="scope.row.flow.nodes[1]" />
-                    </template>
-                </el-table-column>
-                <el-table-column prop="self_assessment" label="自评" align="center" width="80" fixed="right">
-                    <template slot-scope="scope">
-                        <el-switch v-if="!scope.row.flow.nodes[2].enable" v-model="scope.row.flow.nodes[2].enable"
-                            disabled></el-switch>
-                        <ShowHandlerComp v-else :show-data="scope.row.flow.nodes[2]" />
-                    </template>
-                </el-table-column>
-                <el-table-column prop="peer_assessmen" label="互评" align="center" width="80" fixed="right">
-                    <template slot-scope="scope">
-                        <el-switch v-if="!scope.row.flow.nodes[3].enable" v-model="scope.row.flow.nodes[3].enable"
-                            disabled></el-switch>
-                        <ShowHandlerComp v-else :show-data="scope.row.flow.nodes[3]" />
-                    </template>
-                </el-table-column>
-                <el-table-column prop="grade" label="评分" align="center" width="80" fixed="right">
-                    <template slot-scope="scope">
-                        <el-switch v-if="!scope.row.flow.nodes[4].enable" v-model="scope.row.flow.nodes[4].enable"
-                            disabled></el-switch>
-                        <ShowHandlerComp v-else :show-data="scope.row.flow.nodes[4]" />
-                    </template>
-                </el-table-column>
-                <el-table-column prop="approval" label="审批" align="center" width="80" fixed="right">
-                    <template slot-scope="scope">
-                        <el-switch v-if="!scope.row.flow.nodes[5].enable" v-model="scope.row.flow.nodes[5].enable"
-                            disabled></el-switch>
-                        <ShowHandlerComp v-else :show-data="scope.row.flow.nodes[5]" />
-                    </template>
-                </el-table-column>
-                <el-table-column prop="carbon_copy" label="抄送" align="center" width="80" fixed="right">
-                    <template slot-scope="scope">
-                        <el-switch v-if="!scope.row.flow.nodes[6].enable" v-model="scope.row.flow.nodes[6].enable"
-                            disabled></el-switch>
-                        <ShowHandlerComp v-else :show-data="scope.row.flow.nodes[6]" />
-                    </template>
-                </el-table-column>
-            </el-table>
-        </el-drawer>
-
-        <!-- 编辑计算公式 -->
-        <FormulaComp v-if="currentIndicator" v-model="showFormula"
-            :fixed-props="[{ key: 'target', name: '目标' }, { key: 'weight', name: '权重' }, { key: 'result', name: '结果值' }]"
-            :expressions-props="currentIndicator.expression.formulas || []" :is-edit="false"
-            @onConfirm="onFormulaConfirm" />
-
-    </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import moment from 'moment';
-import Stomp from 'stompjs'
-import ShowHandlerComp from '@/newPerformance/components/PublicComp/ShowHandler'; // 显示节点数据组件
-import FormulaComp from '@/newPerformance/components/TemplateDetails/FormulaComp'; // 计算公式弹框
-
-export default {
-    components: {
-        ShowHandlerComp,
-        // FormulaComp
-    },
-    data() {
-        return {
-            chatLog: '',
-            value: 0,
-            isShow: false,
-            chatList: [],
-            interviewInfo: {},
-            stompClient: null, // 实例
-            interviewConnect: false, // 面试是否连接
-            interviewId: 7,
-            hasJoinInterview: false, // 是否已加入面谈会议
-            users: [], // 当前面谈会议人员
-            detailsDialog: false,
-            showFormula: false,
-            currentIndicator: null
-        }
-    },
-
-    created() {
-        this.getChatList();
-        this.getInterviewDetails();
-    },
-    computed: {
-        ...mapGetters(['user_info']),
-        businessStatus() {
-            return this.interviewInfo && this.interviewInfo.businessStatus
-        },
-        tableData() {
-            return this.interviewInfo && this.interviewInfo.reviewInfo && this.interviewInfo.reviewInfo.indicators
-        },
-        canInterviewLog() {
-            return this.interviewConnect && this.hasJoinInterview;
-        },
-        //是否可以给予满意度,被考核人不管会议是否开始或者面谈状态是否已结束都可以
-        canSatisfaction() {
-            return this.interviewInfo && this.interviewInfo.assessor;
-        },
-
-        //是否可以填写主持人记录,主持人并且只有在进入面谈会议状态下可以填写
-        canAssigneeComment() {
-            return this.interviewInfo && this.interviewInfo.host && this.hasJoinInterview;
-        },
-
-        //是否可以填写被考核人记录,与填写满意度一样
-        canEmployeeComment() {
-            return this.canSatisfaction;
-        }
-    },
-    filters: {
-        formatCycleType(val) {
-            if (val == 0) return '未定义'
-            if (val == 1) return '年度'
-            if (val == 2) return '半年'
-            if (val == 3) return '季度'
-            if (val == 4) return '月度'
-            else return '--'
-        },
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        }
-    },
-    methods: {
-        handleClose() {
-            this.detailsDialog = false
-        },
-        // 打开计算公式弹框
-        openFormula(row, index) {
-            this.currentIndicator = row;
-            this.showFormula = true;
-        },
-
-        onFormulaConfirm() { },
-        initMeetingState() {
-            this.stompClient = null;
-            this.interviewConnect = false;
-            this.hasJoinInterview = false;
-            this.users = [];
-        },
-        // 聊天列表
-        getChatList() {
-            let url = `/performance/interview/chat/logs/${this.user_info.site_id}/${this.interviewId}`
-            this.$axiosUser('get', url).then(res => {
-                this.chatList = res.data.data.list;
-                this.$nextTick(() => {
-                    if (this.$refs.chatLogRef) this.$refs.chatLogRef.scrollIntoView(true);
-                })
-            });
-        },
-        // 面谈详情
-        getInterviewDetails() {
-            let url = `/performance/interview/info/${this.user_info.site_id}/${this.interviewId}`
-            this.$axiosUser('get', url).then(res => {
-                this.interviewInfo = res.data.data;
-                this.value = this.interviewInfo.satisfactionLevel
-            });
-        },
-
-        // 加入面谈
-        initMeeting() {
-            console.log("加入面谈");
-            if (this.stompClient && this.interviewConnect) return;
-            this.initMeetingState();
-            // 连接到 STOMP 服务器
-            this.stompClient = Stomp.client('ws://new.gdy.g107.com/performance/ws') // 创建stomp对象
-            this.stompClient.connect(
-                {
-                    at: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOm51bGwsImlhdCI6MTc0MTgyNjk5OCwiZXhwIjotMSwibmJmIjoxNzQxODI2OTk4LCJqdGkiOiJDWk1PQnVoa0lFV2RndzNvIiwic3ViIjoxOTc3LCJwcnYiOiJjYTY0ODlkNTBmMjQwN2E2NzgzMGU4MDkwZDAxNDg4MzU2ODU5NjJiIiwicm9sZSI6ImVtcGxveWVlIn0.GfSKlOCdSUDSPSebuT7CswEhJtmOFWLTfzeOU1-QcVk'
-                },
-                (res) => { // 连接成功,此时可以在network中看到建立了ws连接
-                    console.log("连接成功,此时可以在network中看到建立了ws连接")
-                    this.interviewConnect = true;
-                    // 在这里进行订阅 主题由后端提供
-                    // 发起订阅
-                    this.subscribe()
-
-                    // 加入面谈
-                    this.joinInterview()
-                },
-                (err) => { // 连接失败
-                    console.log(err)
-                }
-            )
-            this.stompClient.heartbeat.outgoing = 10000 // 10秒发一次
-            this.stompClient.heartbeat.incoming = 10000 // 10秒发一次
-            this.stompClient.debug = function (str) {
-                console.log(str)
-            };
-        },
-
-        subscribe() {
-            if (!this.stompClient || !this.interviewConnect) return;
-            //订阅参加面谈
-            this.stompClient.subscribe(`/topic/interview/join/${this.interviewId}`, (message) => {
-                console.log('received interview join message', message);
-                let user = JSON.parse(message.body);
-                if (!user) return;
-                if (this.user_info.id !== user.id) {
-                    // 别人进入面谈
-                    this.$notify({
-                        title: `${user.name}`,
-                        message: '加入了会议',
-                        type: 'success'
-                    });
-
-                } else {
-                    // 自己进入面谈
-                    this.getChatList();
-                    this.getInterviewDetails();
-                    this.getInterviewUsers();
-                    this.hasJoinInterview = true;
-                }
-            });
-            // 订阅离开面谈
-            this.stompClient.subscribe(`/topic/interview/leave/${this.interviewId}`, (message) => {
-                console.log('received interview leave message', message);
-                let user = JSON.parse(message.body);
-
-                if (this.user_info.id !== user.id) {
-
-                    //别人离开面谈
-
-                    this.$notify({
-                        title: `${user.name}`,
-                        message: '离开了会议',
-                        type: 'error'
-                    });
-                } else {
-                    //自己离开面谈
-                    this.disconnect();
-                }
-            });
-            // 订阅主持人记录更新
-            this.stompClient.subscribe(`/topic/interview/comment/assignee/${this.interviewId}`, (message) => {
-                console.log('received comment assignee message', message);
-                if (!this.interviewInfo) return;
-                this.interviewInfo.assigneeComment = message.body;
-                this.$message.success("操作成功")
-            });
-
-            //订阅被考核人记录更新
-            this.stompClient.subscribe(`/topic/interview/comment/employee/${this.interviewId}`, (message) => {
-                console.log('received comment employee message', message);
-                if (!this.interviewInfo) return;
-                this.interviewInfo.employeeComment = message.body;
-                this.$message.success("操作成功")
-            });
-
-            //订阅聊天记录更新
-            this.stompClient.subscribe(`/topic/interview/chat/log/${this.interviewId}`, (message) => {
-                console.log('received chat log message', message);
-                let log = JSON.parse(message.body);
-                if (log) this.chatList.push(log);
-                this.$nextTick(() => {
-                    if (this.$refs.chatLogRef) this.$refs.chatLogRef.scrollIntoView(false);
-                })
-            });
-
-            // 订阅面谈满意度更新
-            this.stompClient.subscribe(`/topic/interview/satisfaction/${this.interviewId}`, (message) => {
-                console.log('订阅面谈满意度更新', message);
-                let tmp = JSON.parse(message.body);
-                if (tmp) this.interviewInfo.satisfactionLevel = tmp.satisfactionLevel || this.interviewInfo.satisfactionLevel;
-                this.$message.success("操作成功")
-            })
-        },
-
-        // 加入会议
-        joinInterview() {
-            if (!this.stompClient || !this.interviewConnect) return;
-
-            this.stompClient.send(`/app/interview/join/${this.interviewId}`);
-            // 获取当前会议的人员列表
-            this.getInterviewUsers();
-        },
-
-        // 获取当前会议的人员列表
-        getInterviewUsers() {
-            let url = `/performance/interview/users/${this.user_info.site_id}/${this.interviewId}`
-            this.$axiosUser('get', url).then(res => {
-                if(res.data.code) this.users = res.data.data
-            });
-        },
-
-        // 离开会议
-        leaveInterview() {
-            if (!this.stompClient || !this.interviewConnect) return;
-
-            this.stompClient.send(`/app/interview/leave/${this.interviewId}`)
-        },
-
-        // 发送聊天记录
-        sendChatLog(event) {
-            // 去掉换行符
-            if (event.keyCode == 13) {
-                if (!event.ctrlKey) {
-                    event.preventDefault();
-                    if (!this.stompClient || !this.hasJoinInterview || !this.canInterviewLog || !this.chatLog) return;
-                    this.stompClient.send(`/app/interview/chat/log/${this.interviewId}`,
-                        {},
-                        this.chatLog
-                    );
-                    this.chatLog = '';
-                    // alt + enter换行
-                } else {
-                    message += "\n";
-                }
-            }
-
-        },
-
-        sendChatLog2() {
-            if (!this.stompClient || !this.hasJoinInterview || !this.canInterviewLog || !this.chatLog) return;
-            this.stompClient.send(`/app/interview/chat/log/${this.interviewId}`,
-                {},
-                this.chatLog
-            );
-            this.chatLog = '';
-        },
-
-        // 主持人发布记录
-        sendAssigneeComment(event) {
-            // 去掉换行符
-            if (event.keyCode == 13) {
-                if (!event.ctrlKey) {
-                    event.preventDefault();
-                    if (!this.stompClient || !this.hasJoinInterview || !this.interviewInfo.host) return;
-                    this.stompClient.send(`/app/interview/comment/assignee/${this.interviewId}`,
-                        {},
-                        this.interviewInfo.assigneeComment
-                    )
-                // alt + enter换行
-                } else {
-                    message += "\n";
-                }
-            }
-        },
-
-        // 被考核人发布记录
-        sendEmployeeComment(event) {
-            // 去掉换行符
-            if (event.keyCode == 13) {
-                if (!event.ctrlKey) {
-                    event.preventDefault();
-                    if (this.canEmployeeComment) return;
-                    if (!this.stompClient || !this.hasJoinInterview || !this.interviewInfo.assessor) {
-                        //普通面谈详情模式
-                        this.apiEmployeeComment();
-                    } else {
-                        //面谈会议模式
-                        stompClient.value.send(`/app/interview/comment/employee/${interviewId.value}`,
-                            {},
-                            interview.value.employeeComment)
-                    }
-                    // alt + enter换行
-                } else {
-                    message += "\n";
-                }
-            }
-
-        },
-
-        // 普通面谈详情模式 - 提交被考核人记录
-        apiEmployeeComment() {
-            if (!this.interviewInfo || !this.canEmployeeComment) return;
-            let url = `/performance/interview/comment/employee/${this.user_info.siteId}`
-            let data = {
-                interviewId: this.interviewId,
-                comment: this.interviewInfo.employeeComment
-            }
-            this.$http.post(url, data).then(res => {
-                if (res.data.code == 1) this.interviewInfo = res.data.data;
-                if (!this.interviewInfo) this.leaveInterview();
-            })
-        },
-
-        // 提交满意度
-        sendSatisfaction() {
-            if (!this.canSatisfaction) return;
-            if (!this.stompClient || !this.hasJoinInterview || !this.interviewInfo.assessor) {
-                //普通面谈详情模式
-                this.apiSatisfaction();
-            } else {
-                //面谈会议模式
-                this.stompClient.send(`/app/interview/satisfaction/${this.interviewId}`,
-                    {},
-                    this.interviewInfo.satisfactionLevel
-                )
-            }
-        },
-
-        apiSatisfaction() {
-            if (!this.interviewInfo || !this.canSatisfaction) return;
-            let url = `/performance/interview/satisfaction/${this.user_info.site_id}`
-            let data = {
-                interviewId: this.interviewId,
-                level: this.value
-            }
-            this.$http.post(url, data).then(res => {
-                if (res.data.code == 1) this.interviewInfo = res.data.data;
-                if (!this.interviewInfo) this.leaveInterview();
-            })
-        },
-
-        disconnect(){
-            if (!this.stompClient || !this.interviewConnect) return;
-            this.leaveInterview();
-            this.stompClient.disconnect();
-            this.initMeetingState();
-
-        },
-
-        // 结束面谈
-        finishInterview() {
-            if (this.stompClient || this.interviewConnect) return;
-            let url = `/performance/interview/close/${this.user_info.site_id}/${this.interviewId}`
-            this.$http.post(url, {}).then(res => {
-                if (res.data.code == 1) this.interviewInfo = res.data.data;
-                if (!this.interviewInfo) this.leaveInterview();
-            })
-        },
-
-
-        // onAssigneeFocused(focused) {
-        //     if (!focused) this.sendAssigneeComment();
-        // },
-
-        // onEmployeeFocused(focused) {
-        //     if (!focused) this.sendEmployeeComment();
-        // }
-    },
-    beforeDestroy() {
-        if(this.stompClient) this.stompClient.disconnect()
-    }
-}
-</script>
-
-<style lang="scss">
-.all {
-    .el-switch__core {
-        width: 30px !important;
-        height: 16px;
-    }
-
-    .el-switch__core::after {
-        width: 14px;
-        height: 14px;
-        margin-top: -1px;
-    }
-
-    .el-switch.is-checked .el-switch__core::after {
-        margin-left: -15px;
-    }
-}
-
-.oneLine {
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-}
-</style>
-
-<style scoped lang="scss">
-.all {
-    width: 100%;
-    height: 100%;
-    position: relative;
-    box-sizing: border-box;
-    background: #f0f4fa;
-    display: flex;
-    flex-direction: column;
-    .header {
-        background: #fff;
-        padding: 10px;
-        margin-bottom: 10px;
-        box-sizing: border-box;
-        justify-content: space-between;
-    }
-    .examine-info {
-        background: #fff;
-        padding: 10px;
-        margin-bottom: 10px;
-        box-sizing: border-box;
-    }
-
-
-    .left-box {
-        width: 76%;
-        height: 100%;
-        margin-right: 10px;
-        display: flex;
-        flex-direction: column;
-
-        .emcee-record, .examinee-record {
-            width: 100%;
-            height: 450px;
-            margin-right: 10px;
-            background-color: #fff;
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            justify-content: center;
-            .title {
-                width: 100%;
-                line-height: 40px;
-                font-size: 16px;
-                font-weight: 600;
-                padding: 0 10px;
-                box-sizing: border-box;
-                border-bottom: 1px solid #f7f7f7;
-            }
-            .content {
-                width: 95%;
-                height: 85%;
-                padding: 10px;
-                box-sizing: border-box;
-                background: #F7F8FA;
-                margin-top: 10px;
-            }
-        }
-
-        .examinee-record {
-            margin-right: 0;
-        }
-
-        .input-box {
-            width: 100%;
-            background-color: #fff;
-            padding: 10px;
-            box-sizing: border-box;
-            margin-right: 10px;
-        }
-    }
-
-
-    .chat-record {
-        width: 24%;
-        height: 100%;
-        background-color: #fff;
-        // overflow-y: auto;
-        .chat-record-title {
-            width: 100%;
-            line-height: 50px;
-            font-size: 16px;
-            font-weight: 600;
-            padding: 0 10px;
-            box-sizing: border-box;
-            border-bottom: 1px solid #f7f7f7;
-        }
-        .chat-item {
-            margin-bottom: 10px;
-            border-radius: 4px;
-            padding: 5px;
-            box-sizing: border-box;
-            margin-top: 10px;
-            .content {
-                padding: 5px;
-                box-sizing: border-box;
-                background: #F7F8FA;
-                margin: 5px 0 0 20px;
-            }
-        }
-    }
-
-    /* 设置滚动条的宽度和背景色 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
-        width: 10px;
-        height: 10px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-    }
-
-
-}
-</style>

+ 0 - 449
src/newPerformance/components/PersonalExamine.vue

@@ -1,449 +0,0 @@
-<template>
-    <div class="boxMinHeight">
-
-        <!-- <div class="left-container">
-            <el-row :gutter="10" style="height: 100%;">
-                <el-col :span="12"
-                    style="height: 100%; display: flex; flex-direction: column; border-bottom: 1px solid #f1f1f1;">
-                    <div class="info-title">
-                        部门选择
-                        <el-input class="flex-1" placeholder="输入关键字进行过滤" v-model="filterText" size="mini"
-                            style="margin-left: 10px;" />
-                    </div>
-                    <div class="flex-1 dept-list department_box" style="overflow-x: auto;">
-                        <el-tree ref="tree" accordion :data="treeData" :props="defaultProps"
-                            :filter-node-method="filterNode" :default-checked-keys="checkedKeys"
-                            :check-strictly="singleSelection" :default-expanded-keys="checkedKeys"
-                            @node-click="handleNodeClick" node-key="id">
-                            <div content="tree" class="custom-tree-node" slot-scope="{ node, data }"
-                                style="font-size: 14px;color: #606266; width:100%; text-align: left;">
-                                <img src="static/images/one.png" />
-                                <span class="name">{{ data.name }}</span>
-                            </div>
-                        </el-tree>
-                    </div>
-                </el-col>
-                <el-col :span="12" style="height: 100%; display: flex; flex-direction: column;">
-                    <div class="info-title">
-                        员工选择
-                        <el-input class="flex-1" placeholder="输入关键字进行过滤" v-model="keyword" size="mini"
-                            style="margin-left: 10px;" />
-                    </div>
-
-
-                    <div class="flex-1 user-list scroll-bar" style="min-height: 100%; overflow-y: auto;">
-                        <template v-if="userList && userList.length > 0">
-                            <div class=" user-item flex-box-ce" v-for="user in userList" :key="user.id"
-                                @click="chooseUser(user)">
-                                <span class="radio" :class="radioValue == user.id ? 'isCheck' : ''">
-                                    <span v-show="radioValue == user.id" class="white-dot"></span>
-                                </span>
-                                <userImage :id="user.id" :img_url="user.img_url" :user_name="user.name" width="24px"
-                                    height="24px"></userImage>
-                                <span class="username">{{ user.name }}</span>
-                            </div>
-
-                            <div style="height: 100px;"></div>
-                        </template>
-
-<template v-else>
-                            <noData content="暂无内容" imgW="100px" imgH="100px"></noData>
-                        </template>
-</div>
-</el-col>
-</el-row>
-</div> -->
-
-        <!-- <div class="right-container">
-            <ExamineDetails v-if="tableData && tableData.length > 0" :table-data="tableData" :cycle-list="cycleOptions"
-                :cate-list="cateList" :examine-status="examineStatus" :gradeLevels="gradeLevels" :userInfo="userInfo" />
-            <template v-else>
-                <div class="flex-box-ce" style="width: 100%; height: 100%; justify-content: center;">
-                    <noData content="暂无内容" imgW="120px" imgH="120px"></noData>
-                </div>
-            </template>
-        </div> -->
-
-
-
-    </div>
-</template>
-
-<script>
-
-import { mapGetters } from 'vuex';
-import _ from "lodash"
-import EmployeeSelector from '@/components/EmployeeSelector';
-import SelectExamineComp from '@/newPerformance/components/MyPerformance/SelectExamine'; // 选择考核列表弹框
-import PieChart1 from '@/newPerformance/components/PersonalExamine/PieChart1'; // 考核状态分布 - 饼图
-import PieChart2 from '@/newPerformance/components/PersonalExamine/PieChart2'; // 考核等级分布 - 饼图
-import PieChart3 from '@/newPerformance/components/PersonalExamine/PieChart3'; // 考核周期类型分布 - 饼图
-import PieChart4 from '@/newPerformance/components/PersonalExamine/PieChart4'; // 考核分类分布 - 饼图
-import ExamineDetails from '@/newPerformance/components/PersonalExamine/ExamineDetails'; // 考核详情
-import OrganizationSelect from "@/newPerformance/components/PublicComp/OrganizationSelect" // 组织架构
-export default {
-    components: {
-        EmployeeSelector,
-        SelectExamineComp,
-        PieChart1,
-        PieChart2,
-        PieChart3,
-        PieChart4,
-        ExamineDetails,
-        OrganizationSelect
-    },
-
-    data() {
-        return {
-            filterText: '',
-            treeData: [],
-            singleSelection: true, // 是否单选
-            checkedKeys: [],
-            defaultProps: {
-                children: 'children',
-                label: 'label'
-            },
-            dept_select_id: '',
-            keyword: '',
-            userList: [],
-            radioValue: '',
-            selected_employee_ids: '',
-            selected_dept_ids: [],
-            deptList: [], // 部门列表 - 树形结构
-            dept_list: [], // 部门列表
-            employeeMap: this.$getEmployeeMap(), // 员工列表
-            cateId: '',
-            cateList: [],
-            loading: false,
-            total: 0,
-            tableData: [],
-            tableIndex: -1,
-            // 添加指标
-            selected: { employee: [], dept: [] },//已经选择人员
-            choosePerson: false,
-            // 周期类型 0-未定义 1-年度 2-半年度 3-季度 4-月度
-            cycleType: '-1',
-            cycleOptions: [
-                { label: "全部", value: '-1' },
-                { label: "未定义", value: '0' },
-                { label: "年度", value: '1' },
-                { label: "半年度", value: '2' },
-                { label: "季度", value: '3' },
-                { label: "月度", value: '4' },
-            ],
-            params: {
-                cycleType: '',
-                cateId: '',
-            },
-            multipleSelection: [],
-            alertTilte: "默认显示每个人的最新考核数据,可选择人员添加考核数据,也可以移除某个人员的考核数据,或点击人员姓名替换某条考核数据",
-            dialogVisible: false,
-            organSelectDialog: false,
-            gradeLevels: [],
-            examineStatus: [
-                { label: "考核中", value: "0" },
-                { label: "已结束", value: "1" },
-                { label: "面谈", value: "2" }
-            ],
-            userInfo: null
-        }
-    },
-
-    watch: {
-        filterText(val) {
-            this.$refs.tree.filter(val);
-        },
-        keyword(val) {
-            if (val) this.userList = this.userList.filter(user => user.name.includes(val))
-        },
-        radioValue(val) {
-            this.selected_employee_ids = val
-            this.getList(val);
-
-        }
-    },
-
-
-    created() {
-        this.selected_employee_ids = this.user_info.id
-        this.userInfo = this.user_info
-        this.getAllSet();
-        this.getList();
-        this.get_dept_list();
-        // this.get_cate_list();
-    },
-
-    computed: {
-        ...mapGetters(['user_info']),
-    },
-
-    methods: {
-
-        get_dept_list() {
-            this.$axiosUser('get', '/api/pro/department/tree', '', 'v2').then(res => {
-                console.log(res)
-                this.treeData = res.data.data.list
-            })
-        },
-
-        get_user_list() {
-            this.$axiosUser('get', '/api/pro/employee/index',
-                { dept_id: this.dept_select_id, keywords: this.keyword, page: 1, page_size: 2000, child: '1' }, 'v2')
-                .then(res => {
-                    this.userList = res.data.data.list;
-                    console.log(this.userList)
-                })
-        },
-
-        filterNode(value, data) {
-            if (!value) return true;
-            return data.label.indexOf(value) !== -1;
-        },
-        handleNodeClick(node) {
-            console.log(node)
-            this.dept_select_id = node.id
-            this.get_user_list();
-        },
-
-        chooseUser(user) {
-            this.radioValue = user.id
-            this.userInfo = user;
-        },
-
-        // 表格数据 - 最新考核数据
-        getList(employeeId = '') {
-            let that = this
-            that.loading = true;
-            let url
-            if (employeeId) url = `/performance/statistics/reviews/${that.user_info.site_id}/${employeeId}`
-            else url = `/performance/statistics/reviews/${that.user_info.site_id}/${that.user_info.id}`
-            let requestdata;
-            if (that.cycleType == '-1') requestdata = { ...that.params }
-            else requestdata = { ...that.params, cycleType: that.cycleType }
-            that.$axiosUser('get', url, requestdata).then(res => {
-                let { data: { data: { list, total }, code } } = res;
-                if (code == 1) {
-                    that.tableData = [];
-                    that.tableData = list;
-                }
-            });
-        },
-
-        // 获取全局等级设置
-        async getAllSet() {
-            let res = await this.$axiosUser('get', 'api/pro/per/user/base_config')
-            let data = res.data.data;
-            let levels = data.level_scope.levels;
-            let gradeLevels = [];
-            let max = 0;//最大值
-            if (levels && levels.length > 0) {
-                levels.forEach((item, index) => {
-                    var obj;
-                    if (index == 0) {
-                        obj = { name: item.name, max: Number(item.value), min: 0 };
-                    } else {
-                        obj = { name: item.name, max: Number(item.value), min: max };//当不是第一个等级时,最小值为上一个的最大值
-                    }
-                    max = item.value;
-                    gradeLevels.push(obj);
-                })
-                this.gradeLevels = gradeLevels
-            }
-        },
-
-        // 考核分类列表
-        get_cate_list() {
-            let url = `/performance/cate/list/${this.user_info.site_id}`;
-            // this.loading = true
-            this.$axiosUser('get', url, {}).then(res => {
-                let { data: { code, data: { list, total } } } = res
-                if (code == 1) {
-                    this.cateList = list
-                }
-
-            })
-        },
-    }
-}
-</script>
-
-<style scoped="scoped" lang="scss">
-.department_box /deep/ .el-tree-node {
-    display: block;
-    text-align: center;
-
-}
-
-.department_box /deep/ .el-tree-node__content {
-    height: auto !important;
-}
-
-.department_box /deep/ .el-tree-node .el-icon-caret-right {
-    display: inline-block;
-    color: #909399;
-    font-size: 16px;
-    padding: 6px 8px;
-}
-
-.department_box /deep/ .el-tree-node .el-icon-caret-right.is-leaf {
-    color: transparent;
-    cursor: default;
-}
-
-.department_box /deep/ .el-tree-node .custom-tree-node {
-    display: flex;
-    align-items: center;
-}
-
-.department_box /deep/ .el-tree-node .custom-tree-node img {
-    margin: 0px 5px 0 0;
-    width: 20px;
-}
-
-.department_box /deep/ .el-tree-node .custom-tree-node span {}
-
-.department_box /deep/ .el-tree-node__content {
-    padding: 12px 0;
-    border-bottom: 1px #f8f8f8 solid;
-    display: flex;
-    align-items: center;
-}
-
-.department_box /deep/ .el-tree-node__content:hover {
-    background: #ecf5ff;
-    border-radius: 4px;
-}
-
-.department_box /deep/ .is-focusable .is-current {
-    border-radius: 4px;
-}
-
-.department_box /deep/ .is-focusable .is-current .name {
-    color: #409EFF;
-    font-weight: normal;
-    transition: 0.35s ease-in-out;
-}
-
-
-.boxMinHeight {
-    width: 100%;
-    height: 100%;
-    display: flex;
-    overflow: hidden;
-
-    .left-container {
-        width: calc(35% - 10px);
-        height: 100%;
-        margin-right: 10px;
-        background-color: #fff;
-        border-radius: 5px;
-        display: flex;
-        flex-direction: column;
-
-        .info-title {
-            font-size: 16px;
-            font-weight: 600;
-            line-height: 40px;
-            display: flex;
-            margin-bottom: 10px;
-            padding: 0 10px;
-
-        }
-
-        .dept-list,
-        .user-list {
-            width: 100%;
-            flex: 1;
-            padding-bottom: 30px;
-            box-sizing: border-box;
-            overflow-y: auto;
-            border-top: 1px solid #f1f1f1;
-
-            /* 设置滚动条的宽度和背景色 */
-            &::-webkit-scrollbar {
-                width: 6px;
-                height: 6px;
-                background-color: #f9f9f9;
-            }
-
-            /* 设置滚动条滑块的样式 */
-            &::-webkit-scrollbar-thumb {
-                border-radius: 6px;
-                background-color: #c1c1c1;
-            }
-
-            /* 设置滚动条滑块hover样式 */
-            &::-webkit-scrollbar-thumb:hover {
-                background-color: #a8a8a8;
-            }
-
-            /* 设置滚动条轨道的样式 */
-            &::-webkit-scrollbar-track {
-                box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-                border-radius: 6px;
-                background: #ededed;
-            }
-
-        }
-
-
-        .user-list {
-            border-left: 1px solid #f1f1f1;
-
-            .user-item {
-                width: 100%;
-                display: flex;
-                align-items: center;
-                padding: 0 10px;
-                box-sizing: border-box;
-                height: 40px;
-
-                .radio {
-                    border: 1px solid #DCDFE6;
-                    border-radius: 100%;
-                    width: 14px;
-                    height: 14px;
-                    background-color: #FFF;
-                    cursor: pointer;
-                    margin-right: 6px !important;
-                    position: relative;
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-
-                    .white-dot {
-                        display: block;
-                        width: 6px;
-                        height: 6px;
-                        background-color: #fff;
-                        border-radius: 50%;
-                    }
-                }
-
-                .isCheck {
-                    border-color: #409EFF;
-                    background: #409EFF;
-                }
-
-                .username {
-                    margin-left: 10px;
-                }
-
-                &:hover {
-                    cursor: pointer;
-                    background: #F5F7FA;
-                }
-            }
-        }
-    }
-
-    .right-container {
-        width: 100%;
-        height: 100%;
-        background-color: #fff;
-        border-radius: 5px;
-    }
-
-
-}
-</style>

+ 0 - 328
src/newPerformance/components/PersonalExamine/ExamineDetails copy.vue

@@ -1,328 +0,0 @@
-<template>
-    <el-dialog :visible.sync="dialogVisible" width="1000px" :before-close="dialogBeforeClose">
-        <div>
-            <div class="search-box">
-                <div class="flex-box">
-                    <el-select v-model="filters.cycleType" placeholder="请选择周期" size="small">
-                        <el-option v-for="item in cycleList" multiple :key="item.value" :label="item.label"
-                            :value="item.value">
-                        </el-option>
-                    </el-select>
-
-                    <el-select v-model="filters.cateType" placeholder="请选择分类" size="small" style="margin: 0 10px;">
-                        <el-option v-for="item in cateList" multiple :key="item.cateId" :label="item.name"
-                            :value="item.cateId">
-                        </el-option>
-                    </el-select>
-
-                    <el-select v-model="filters.gradeLevels" placeholder="请选择等级" size="small">
-                        <el-option v-for="item in gradeLevels" :key="item.label" :label="item.label"
-                            :value="item.value">
-                        </el-option>
-                    </el-select>
-                </div>
-
-                <div class="flex-box">
-                    <el-button type="primary" @click="applyFilters" size="small">筛选</el-button>
-                    <el-button @click="clearFilters" size="small">清空</el-button>
-                </div>
-
-            </div>
-
-            <!-- 考核模板列表 -->
-            <div class="perform-list scroll-bar" style="margin: 10px 0; height: 450px; overflow-y: auto;">
-                <el-table ref="multipleTable" v-loading="loading"
-                    :data="filteredData.slice(params.page - 1, params.page * params.pageSize)"
-                    style="width: 100%; margin-top: 10px;" :height="450" :header-cell-style="{ background: '#f5f7fa' }"
-                    border stripe size="small">
-                    <el-table-column prop="title" label="考核名称" min-width="160" align="center">
-                    </el-table-column>
-                    <el-table-column prop="startTime" label="考核时间" min-width="160" align="center">
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.startTime | formatDate }} 至 {{ scope.row.endTime | formatDate }}
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="cycleType" label="周期类型" min-width="80" align="center">
-                        <template slot-scope="scope">
-                            <el-tag type="primary">{{ scope.row.cycleType | formatCycleType }}</el-tag>
-                        </template>
-                    </el-table-column>
-
-
-                    <el-table-column prop="cateId" label="考核分类" min-width="100" align="center">
-                        <template slot-scope="scope">
-                            <div v-if="scope.row.cateIds && scope.row.cateIds">
-                                <template v-for="item in cateList">
-                                    <el-tag :key="item.cateId" v-if="scope.row.cateIds.includes(item.cateId)"
-                                        style="margin-bottom: 5px;">
-                                        {{ item.name}}
-                                    </el-tag>
-                                </template>
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="levelName" label="得分" min-width="100" align="center">
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.score || '--' }}
-                                {{ scope.row.levelName ? "(" + scope.row.levelName + ")" : '--' }}
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="packageOkrs" label="关联OKR" min-width="100" align="center">
-                        <template slot-scope="scope">
-                            <el-link v-if="scope.row.okrs && scope.row.okrs.length > 0" type="primary"
-                                @click="openTargetList(scope.row.okrs)">
-                                考核表OKR
-                            </el-link>
-                            <span v-else class="fontColorC">暂无关联</span>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="status" label="考核状态" min-width="100" align="center">
-                        <template slot-scope="scope">
-                            <div v-if="scope.row.status == 0" class="orange-color">
-                                {{ scope.row.status | formatStatus }}
-                            </div>
-                            <div v-if="scope.row.status == 1" class="green-color">
-                                {{ scope.row.status | formatStatus }}
-                            </div>
-                            <div v-if="scope.row.status == 2" class="blue-color">
-                                {{ scope.row.status | formatStatus }}
-                            </div>
-                        </template>
-                    </el-table-column>
-                </el-table>
-            </div>
-            <div class="flex-box-ce" style="justify-content: center; margin-top: 10px;">
-                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
-                    :current-page="params.page" :page-sizes="[15, 30, 45, 60]" :page-size="params.pageSize"
-                    layout="total, sizes, prev, pager, next" :total="total">
-                </el-pagination>
-            </div>
-        </div>
-
-        <!-- 关联okr -->
-        <TargetListComp v-if="targetDialogVisible" :dialogVisible="targetDialogVisible" :ids="okrs" @close="closeTargetList">
-        </TargetListComp>
-    </el-dialog>
-
-</template>
-
-<script>
-import moment from 'moment';
-import TargetListComp from "@/performance/views/assessManagement/TargetListComp.vue"; // 关联OKR弹框
-
-export default {
-    components: {
-        TargetListComp
-    },
-    model: {
-        prop: 'dialogVisible',
-        event: 'close-dialog'
-    },
-    props: {
-        dialogVisible: {
-            type: Boolean,
-            default: false
-        },
-        tableData: {
-            type: Array,
-            default: () => []
-        },
-        cycleList: {
-            type: Array,
-            default: () => []
-        },
-        cateList: {
-            type: Array,
-            default: () => []
-        },
-        examineStatus: {
-            type: Array,
-            default: () => []
-        },
-    },
-
-
-    data() {
-        return {
-            loading: false,
-            visible: false,
-            value: '',
-            iconColor: false,
-            params: {
-                page: 1,
-                pageSize: 15
-            },
-            gradeLevels: [],
-            // 筛选条件
-            filters: {
-                cycleType: [],
-                cateType: [],
-                gradeLevels: [],
-            },
-            // 筛选后的数据
-            filteredData: [],
-            okrs: [],
-            targetDialogVisible: false
-        }
-    },
-    filters: {
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        },
-        formatCycleType(val) {
-            if (val == 0) return '未定义'
-            if (val == 1) return '年度'
-            if (val == 2) return '半年'
-            if (val == 3) return '季度'
-            if (val == 4) return '月度'
-            else return '--'
-        },
-        formatStatus(val) {
-            if (val == 0) return '考核中'
-            if (val == 1) return '已结束'
-            if (val == 2) return '面谈'
-            else return '--'
-        }
-    },
-    computed: {
-        total() {
-            return this.tableData && this.tableData.length
-        }
-    },
-
-    mounted() {
-        this.filteredData = this.tableData
-        this.gradeLevels = this.tableData.map(item => {
-            return {
-                label: item.levelName || '--',
-                value: item.levelName || '--',
-            }
-
-        })
-        // 数组去重
-        this.gradeLevels = Array.from(new Set(this.gradeLevels.map(JSON.stringify))).map(JSON.parse);
-    },
-
-    methods: {
-
-        dialogBeforeClose() {
-            this.$emit('close-dialog', false)
-        },
-        
-        handleSizeChange(v) {
-            this.params.pageSize = v
-        },
-        handleCurrentChange(v) {
-            this.params.page = v
-        },
-
-
-        // 应用筛选条件
-        applyFilters() {
-            this.filteredData = this.tableData.filter((item) => {
-                // 周期筛选
-                if (this.filters.cycleType && this.filters.cycleType !== '-1' && !this.filters.cycleType.includes(item.cycleType)) {
-                    return false;
-                }
-
-                // 分类筛选
-                if (this.filters.cateType && !item.cateIds.includes(this.filters.cateType)) {
-                    return false;
-                }
-                // 周期筛选
-                if (
-                    this.filters.gradeLevels && this.filters.gradeLevels.length > 0 &&
-                    !this.filters.gradeLevels.includes(item.levelName)
-                ) {
-                    return false;
-                }
-                
-                return true;
-            });
-        },
-        // 清空筛选条件
-        clearFilters() {
-            this.filters.cycleType = [];
-            this.filters.cateType = [];
-            this.filters.gradeLevels = [];
-            this.applyFilters(); // 重新应用筛选条件
-        },
-        
-        closeTargetList() {
-            this.targetDialogVisible = false
-        },
-        
-        openTargetList(okrs) {
-            if (okrs && okrs.length > 0) {
-                this.okrs = okrs
-                this.targetDialogVisible = true
-            } else return this.$message.error("暂无关联okr")
-        }
-    }
-}
-</script>
-
-
-<style scoped lang="scss">
-
-        
-.search-box {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-}
-.perform-list {
-    width: 100%;
-    padding: 0 20px;
-    box-sizing: border-box;
-    display: flex;
-    flex-direction: column;
-    position: relative;
-    background-color: #fff;
-    .green-color {
-        color: #67c23a;
-    }
-
-    .orange-color {
-        color: #e6a23c;
-    }
-
-    .blue-color {
-        color: #409eff;
-    }
-    
-    /* 设置滚动条的宽度和背景色 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
-        width: 10px;
-        height: 10px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-    }
-}
-</style>

+ 0 - 446
src/newPerformance/components/PersonalExamine/ExamineDetails.vue

@@ -1,446 +0,0 @@
-<template>
-    <div class="examine-details" v-loading="loading">
-        <div class="info-title flex-box-ce" style="margin-top: 10px;">
-            考核人员
-            <div class="flex-box-ce fontColorC">
-                <userImage :id="userInfo.id" :img_url="userInfo.img_url" :user_name="userInfo.name" width="36px"
-                    height="36px" style="margin:0 10px;"></userImage>
-                {{ userInfo.name }}
-            </div>
-        </div>
-        <div style="border: 1px solid #eee; border-radius: 5px; padding: 10px; box-sizing: border-box; ">
-            <div class="info-title">
-                考核统计
-            </div>
-            <div class="flex-box-ce flex-d-wrap" style="justify-content: center;">
-                <div v-for="(item, index) in generalizeList" :key="index" class="generalize-item cursor"
-                    @click="composite_state = item.id">
-                    <div class="fontColorC">{{ item.name }}</div>
-                    <div style="font-size: 36px; font-weight: 600;margin: 5px 0;">{{ item.val }}</div>
-                    <div style="width: 60px;height: 2px;" :style="{ backgroundColor: item.color }"></div>
-                </div>
-            </div>
-        </div>
-
-
-        <div class="flex-1" style="display: flex; flex-direction: column;">
-            <div class="info-title">
-                考核列表
-            </div>
-            <div class="search-box">
-                <div class="flex-box">
-                    <el-select v-model="filters.cycleType" placeholder="请选择周期" size="small">
-                        <el-option v-for="item in cycleList" multiple :key="item.value" :label="item.label"
-                            :value="item.value">
-                        </el-option>
-                    </el-select>
-
-                    <el-select v-model="filters.cateType" placeholder="请选择分类" size="small" style="margin: 0 10px;">
-                        <el-option v-for="item in cateList" multiple :key="item.cateId" :label="item.name"
-                            :value="item.cateId">
-                        </el-option>
-                    </el-select>
-
-                    <el-select v-model="filters.gradeLevels" placeholder="请选择等级" size="small">
-                        <el-option v-for="item in gradeLevels" :key="item.label" :label="item.label"
-                            :value="item.value">
-                        </el-option>
-                    </el-select>
-                </div>
-
-                <div class="flex-box">
-                    <el-button type="primary" @click="applyFilters" size="small">筛选</el-button>
-                    <el-button @click="clearFilters" size="small">清空</el-button>
-                </div>
-
-            </div>
-
-            <div class="flex-1">
-                <el-table v-loading="loading" :data="filteredData.slice(params.page - 1, params.page * params.pageSize)"
-                    style="width: 100%; margin: 10px 0;" :header-cell-style="{ background: '#f5f7fa' }" border stripe
-                    size="small" height="490">
-                    <el-table-column prop="title" label="考核名称" min-width="160" align="center">
-                    </el-table-column>
-                    <el-table-column prop="startTime" label="考核时间" min-width="150" align="center">
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.startTime | formatDate }} 至 {{ scope.row.endTime | formatDate }}
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="cycleType" label="周期类型" min-width="80" align="center">
-                        <template slot-scope="scope">
-                            <el-tag type="primary">{{ scope.row.cycleType | formatCycleType }}</el-tag>
-                        </template>
-                    </el-table-column>
-
-
-                    <el-table-column prop="cateId" label="考核分类" min-width="120" align="center">
-                        <template slot-scope="scope">
-                            <div v-if="scope.row.cateIds && scope.row.cateIds">
-                                <template v-for="item in cateList">
-                                    <el-tag :key="item.cateId" v-if="scope.row.cateIds.includes(item.cateId)"
-                                        style="margin-bottom: 5px;">
-                                        {{ item.name }}
-                                    </el-tag>
-                                </template>
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="levelName" label="得分" min-width="100" align="center">
-                        <template slot-scope="scope">
-                            <div>
-                                {{ scope.row.score || '--' }}
-                                {{ scope.row.levelName ? "(" + scope.row.levelName + ")" : '--' }}
-                            </div>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="packageOkrs" label="关联OKR" min-width="100" align="center">
-                        <template slot-scope="scope">
-                            <el-link v-if="scope.row.okrs && scope.row.okrs.length > 0" type="primary"
-                                @click="openTargetList(scope.row.okrs)">
-                                考核表OKR
-                            </el-link>
-                            <span v-else class="fontColorC">暂无关联</span>
-                        </template>
-                    </el-table-column>
-
-                    <el-table-column prop="status" label="考核状态" min-width="100" align="center">
-                        <template slot-scope="scope">
-                            <div v-if="scope.row.status == 0" class="orange-color">
-                                {{ scope.row.status | formatStatus }}
-                            </div>
-                            <div v-if="scope.row.status == 1" class="green-color">
-                                {{ scope.row.status | formatStatus }}
-                            </div>
-                            <div v-if="scope.row.status == 2" class="blue-color">
-                                {{ scope.row.status | formatStatus }}
-                            </div>
-                        </template>
-                    </el-table-column>
-                </el-table>
-            </div>
-
-
-
-            <div class="flex-box-ce" style="justify-content: center;">
-                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
-                    :current-page="params.page" :page-sizes="[15, 30, 45, 60]" :page-size="params.pageSize"
-                    layout="total, sizes, prev, pager, next" :total="total">
-                </el-pagination>
-            </div>
-
-            <!-- 考核模板列表 -->
-            <!-- <div class="perform-list scroll-bar" style="margin: 10px 0;  overflow-y: auto;">
-                
-            </div>
-
-             -->
-        </div>
-
-        <div style="height: 20px;"></div>
-        <!-- 关联okr -->
-        <TargetListComp v-if="targetDialogVisible" :dialogVisible="targetDialogVisible" :ids="okrs"
-            @close="closeTargetList">
-        </TargetListComp>
-    </div>
-
-</template>
-
-<script>
-import { mapGetters } from 'vuex';
-import moment from 'moment';
-import TargetListComp from "@/performance/views/assessManagement/TargetListComp.vue"; // 关联OKR弹框
-
-export default {
-    components: {
-        TargetListComp
-    },
-    model: {
-        prop: 'dialogVisible',
-        event: 'close-dialog'
-    },
-    props: {
-        dialogVisible: {
-            type: Boolean,
-            default: false
-        },
-        tableData: {
-            type: Array,
-            default: () => []
-        },
-        cycleList: {
-            type: Array,
-            default: () => []
-        },
-        cateList: {
-            type: Array,
-            default: () => []
-        },
-        examineStatus: {
-            type: Array,
-            default: () => []
-        },
-        userInfo: {
-            type: Object,
-            default: () => {}
-        },
-    },
-
-
-    data() {
-        return {
-            loading: false,
-            visible: false,
-            value: '',
-            iconColor: false,
-            params: {
-                page: 1,
-                pageSize: 15
-            },
-            gradeLevels: [],
-            // 筛选条件
-            filters: {
-                cycleType: [],
-                cateType: [],
-                gradeLevels: [],
-            },
-            // 筛选后的数据
-            filteredData: [],
-            okrs: [],
-            targetDialogVisible: false,
-            generalizeList: [
-                { name: '考核总数', val: 10, color: '#FF9600' },
-                { name: '已结束', val: 10, color: '#409EFF' },
-                { name: '进行中', val: 10, color: '#67c23a' },
-                { name: '面谈中', val: 10, color: '#f56c6c' },
-                { name: '已取消', val: 10, color: '#5F7294' },
-                { name: '未开始', val: 10, color: '#5F7294' },
-                { name: '暂停中', val: 10, color: '#f56c6c' }
-            ],
-        }
-    },
-
-    watch: {
-        tableData(v) {
-            this.loading = true;
-            setTimeout(() => { 
-                this.loading = false;
-            },500)
-        }
-    },
-    filters: {
-        formatDate(val) {
-            if (val) return moment(val).format('YYYY-MM-DD')
-            else return "--"
-        },
-        formatCycleType(val) {
-            if (val == 0) return '未定义'
-            if (val == 1) return '年度'
-            if (val == 2) return '半年'
-            if (val == 3) return '季度'
-            if (val == 4) return '月度'
-            else return '--'
-        },
-        formatStatus(val) {
-            if (val == 0) return '考核中'
-            if (val == 1) return '已结束'
-            if (val == 2) return '面谈'
-            else return '--'
-        }
-    },
-    computed: {
-        total() {
-            return this.tableData && this.tableData.length
-        },
-        ...mapGetters(['user_info']),
-    },
-
-    mounted() {
-        this.filteredData = this.tableData;
-        this.gradeLevels = this.tableData.map(item => {
-            return {
-                label: item.levelName || '--',
-                value: item.levelName || '--',
-            }
-        })
-
-
-        // 数组去重
-        this.gradeLevels = Array.from(new Set(this.gradeLevels.map(JSON.stringify))).map(JSON.parse);
-        console.log(this.gradeLevels);
-        this.initData();
-
-    },
-
-    methods: {
-        initData() {
-            if (this.tableData && this.tableData.length > 0) {
-                this.generalizeList[0].val = this.tableData.length;
-                this.generalizeList[2].val = this.tableData.filter(item => item.status === 0).length;
-                this.generalizeList[1].val = this.tableData.filter(item => item.status === 1).length;
-                this.generalizeList[3].val = this.tableData.filter(item => item.status === 2).length;
-            }
-        },        
-        handleSizeChange(v) {
-            this.params.pageSize = v
-        },
-        handleCurrentChange(v) {
-            this.params.page = v
-        },
-
-
-        // 应用筛选条件
-        applyFilters() {
-            this.filteredData = this.tableData.filter((item) => {
-                // 周期筛选
-                if (this.filters.cycleType && this.filters.cycleType !== '-1' && !this.filters.cycleType.includes(item.cycleType)) {
-                    return false;
-                }
-
-                // 分类筛选
-                if (this.filters.cateType && !item.cateIds.includes(this.filters.cateType)) {
-                    return false;
-                }
-                // 周期筛选
-                if (
-                    this.filters.gradeLevels && this.filters.gradeLevels.length > 0 &&
-                    !this.filters.gradeLevels.includes(item.levelName)
-                ) {
-                    return false;
-                }
-                
-                return true;
-            });
-        },
-        
-        // 清空筛选条件
-        clearFilters() {
-            this.filters.cycleType = [];
-            this.filters.cateType = [];
-            this.filters.gradeLevels = [];
-            this.applyFilters(); // 重新应用筛选条件
-        },
-        
-        closeTargetList() {
-            this.targetDialogVisible = false
-        },
-        
-        openTargetList(okrs) {
-            if (okrs && okrs.length > 0) {
-                this.okrs = okrs
-                this.targetDialogVisible = true
-            } else return this.$message.error("暂无关联okr")
-        },
-        
-    }
-}
-</script>
-
-
-<style scoped lang="scss">
-
-.examine-details {
-    width: 100%;
-    height: 100%;
-    border-radius: 6px;
-    background: #fff;
-    padding: 0 10px;
-    box-sizing: border-box;
-    display: flex;
-    flex-direction: column;
-
-    /* 设置滚动条的宽度和背景色 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
-        width: 6px;
-        height: 6px;
-        background-color: #f9f9f9;
-    }
-
-    /* 设置滚动条滑块的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
-        border-radius: 6px;
-        background-color: #c1c1c1;
-    }
-
-    /* 设置滚动条滑块hover样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-        background-color: #a8a8a8;
-    }
-
-    /* 设置滚动条轨道的样式 */
-    ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-        box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-        border-radius: 6px;
-        background: #ededed;
-    }
-    .info-title {
-        font-size: 16px;
-        font-weight: 600;
-        line-height: 40px;
-    }
-    .generalize-item {
-        width: 140px;
-        margin-bottom: 20px;
-    }
-
-    .search-box {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-    }
-
-    .perform-list {
-        width: 100%;
-        box-sizing: border-box;
-        display: flex;
-        flex-direction: column;
-        position: relative;
-        background-color: #fff;
-
-        .green-color {
-            color: #67c23a;
-        }
-
-        .orange-color {
-            color: #e6a23c;
-        }
-
-        .blue-color {
-            color: #409eff;
-        }
-
-        /* 设置滚动条的宽度和背景色 */
-        ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
-            width: 10px;
-            height: 10px;
-            background-color: #f9f9f9;
-        }
-
-        /* 设置滚动条滑块的样式 */
-        ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
-            border-radius: 6px;
-            background-color: #c1c1c1;
-        }
-
-        /* 设置滚动条滑块hover样式 */
-        ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
-            background-color: #a8a8a8;
-        }
-
-        /* 设置滚动条轨道的样式 */
-        ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
-            box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
-            border-radius: 6px;
-            background: #ededed;
-        }
-    }
-}
-
-
-        
-
-</style>

+ 0 - 108
src/newPerformance/components/PersonalExamine/PieChart1.vue

@@ -1,108 +0,0 @@
-<template>
-    <!-- 按考核状态分布 -->
-    <div ref="chart1" :style="myChartStyle"></div>
-</template>
-
-<script>
-
-import echarts from 'echarts';
-
-export default {
-    props: {
-        tableData: {
-            type: Array,
-            default: () => []
-        }
-    },
-    data() {
-        return {
-            myChart: null,
-            myChartStyle: { width: "100%", height: "300px" },
-            colorList: [
-                { c1: ' #40d3ff', c2: '#409EFF' }, { c1: ' #ede737', c2: '#FF9600' }, { c1: '#89e398', c2: '#67c23a' },
-                { c1: ' #85E9C7', c2: '#00C4CB' }, { c1: ' #f393a9', c2: '#f56c6c' }, { c1: '#e69cf3', c2: '#de43f9' },
-            ],
-        }
-    },
-    
-    computed: {
-        // 考核表状态
-        examineStatus() {
-            let examineStatus = [
-                { name: "进行中", value: 0 },
-                { name: "已结束", value: 0 },
-                { name: "面谈中", value: 0 },
-            ]
-            examineStatus[0].value = this.tableData.filter(item => item.status === 0).length;
-            examineStatus[1].value = this.tableData.filter(item => item.status === 1).length;
-            examineStatus[2].value = this.tableData.filter(item => item.status === 2).length;
-            return examineStatus
-        },
-    },
-
-    watch: {  //此处为关键,监听tableData值的变化,进行echarts渲染
-        tableData(v){
-            this.initEcharts1(); //值发生改变则渲染一次echarts
-        }
-    },
-
-    mounted() {
-        this.initEcharts1();
-    },
-    beforeDestroy() {
-        if (this.myChart) {
-            this.myChart.clear();//清空当前实例,会移除实例中所有的组件和图表
-            this.myChart.dispose();//销毁实例,实例销毁后无法再被使用
-        }
-    },
-    methods: {
-        initEcharts1() {
-            const colorList = this.colorList;
-            const option = {
-                tooltip: {//悬浮提示组件
-                    trigger: 'item',
-                },
-                legend: {
-                    show: true,
-                    icon: "circle",
-                    itemWidth: 10,  // 设置宽度
-                    itemHeight: 10, // 设置高度
-                    x: 'center',
-                    y: 'bottom',
-                    itemGap: 30
-                },
-
-                series: [
-                    {
-                        type: "pie",
-                        radius: ['40%', '65%'],//小的是内径,大的是外径
-                        data: this.examineStatus,
-                        itemStyle: {
-                            emphasis: {
-                                shadowBlur: 9,
-                                shadowOffsetX: 0,
-                                shadowColor: 'rgba(0, 0, 0, 0.5)'
-                            },
-                            normal: {
-                                label: {
-                                    show: true,
-                                    formatter: '{b} : {c}'
-                                },
-                                labelLine: { show: true },
-                                color: function (params) {//颜色渐变函数 前四个参数分别表示四个位置依次为左、下、右、上
-                                    return new echarts.graphic.LinearGradient(0, 1, 0, 0, [{ offset: 0, color: colorList[params.dataIndex].c1 }, { offset: 1, color: colorList[params.dataIndex].c2 }])
-                                }
-                            }
-                        }
-                    }
-                ]
-            };
-            this.myChart = this.$echarts.init(this.$refs.chart1);
-            this.myChart.setOption(option);
-            window.addEventListener("resize", () => {
-                this.myChart.resize();
-            });
-        },
-    }
-}
-</script>

+ 0 - 109
src/newPerformance/components/PersonalExamine/PieChart2.vue

@@ -1,109 +0,0 @@
-<template>
-    <!-- 按等级分布 -->
-    <div ref="chart2" :style="myChartStyle"></div>
-</template>
-
-<script>
-
-import echarts from 'echarts';
-
-export default {
-    props: {
-        tableData: {
-            type: Array,
-            default: () => []
-        },
-        gradeLevels: {
-            type: Array,
-            default: () => []
-        },
-    },
-    data() {
-        return {
-            myChart: null,
-            myChartStyle: { width: "100%", height: "300px" },
-            colorList: [
-                { c1: ' #40d3ff', c2: '#409EFF' }, { c1: ' #ede737', c2: '#FF9600' }, { c1: '#89e398', c2: '#67c23a' },
-                { c1: ' #85E9C7', c2: '#00C4CB' }, { c1: ' #f393a9', c2: '#f56c6c' }, { c1: '#e69cf3', c2: '#de43f9' },
-            ],
-        }
-    },
-
-    watch: {  //此处为关键,监听tableData值的变化,进行echarts渲染
-        levelStatus(v) {
-            this.initEcharts2(); //值发生改变则渲染一次echarts
-        }
-    },
-    
-    computed: {
-        // 考核等级
-        levelStatus() {
-            let levelStatus = []
-            levelStatus = this.gradeLevels.map(item => ({
-                name: item.name, value: this.tableData.filter(data => data.levelName === item.name).length,
-            }))
-            levelStatus.unshift({ name: "未评分", value: this.tableData.filter(data => !data.levelName).length })
-            
-            return levelStatus
-        },
-    },
-    mounted() {
-        this.initEcharts2();
-    },
-    beforeDestroy() {
-        if (this.myChart) {
-            this.myChart.clear();//清空当前实例,会移除实例中所有的组件和图表
-            this.myChart.dispose();//销毁实例,实例销毁后无法再被使用
-        }
-    },
-    methods: {
-        initEcharts2() {
-            const colorList = this.colorList;
-            const option = {
-                tooltip: {//悬浮提示组件
-                    trigger: 'item',
-                },
-                legend: {
-                    show: true,
-                    x: 'center',
-                    y: 'bottom',
-                    icon: "circle",
-                    itemWidth: 10,  // 设置宽度
-                    itemHeight: 10, // 设置高度
-                    itemGap: 30
-                },
-
-                series: [
-                    {
-                        type: "pie",
-                        radius: ['40%', '65%'],//小的是内径,大的是外径
-                        data: this.levelStatus,
-                        itemStyle: {
-                            emphasis: {
-                                shadowBlur: 9,
-                                shadowOffsetX: 0,
-                                shadowColor: 'rgba(0, 0, 0, 0.5)'
-                            },
-                            normal: {
-                                label: {
-                                    show: true,
-                                    formatter: '{b} : {c}'
-                                },
-                                labelLine: { show: true },
-                                color: function (params) {//颜色渐变函数 前四个参数分别表示四个位置依次为左、下、右、上
-                                    return new echarts.graphic.LinearGradient(0, 1, 0, 0, [{ offset: 0, color: colorList[params.dataIndex].c1 }, { offset: 1, color: colorList[params.dataIndex].c2 }])
-                                }
-                            }
-                        }
-                    }
-                ]
-            };
-            this.myChart = this.$echarts.init(this.$refs.chart2);
-            this.myChart.setOption(option);
-            window.addEventListener("resize", () => {
-                this.myChart.resize();
-            });
-        },
-    }
-}
-</script>

+ 0 - 111
src/newPerformance/components/PersonalExamine/PieChart3.vue

@@ -1,111 +0,0 @@
-<template>
-    <!-- 按考核周期分布 -->
-    <div ref="chart3" :style="myChartStyle"></div>
-</template>
-
-<script>
-
-import echarts from 'echarts';
-import _ from "lodash"
-export default {
-    props: {
-        tableData: {
-            type: Array,
-            default: () => []
-        },
-        cycleOptions: {
-            type: Array,
-            default: () => []
-        },
-    },
-    data() {
-        return {
-            myChart: null,
-            myChartStyle: { width: "100%", height: "300px" },
-            colorList: [
-                { c1: '#40d3ff', c2: '#409EFF' }, { c1: '#ede737', c2: '#FF9600' }, { c1: '#89e398', c2: '#67c23a' },
-                { c1: '#85E9C7', c2: '#00C4CB' }, { c1: '#f393a9', c2: '#f56c6c' }, { c1: '#e69cf3', c2: '#de43f9' },
-                { c1: '#ede737', c2: '#FF9600' },
-            ],
-        }
-    },
-
-    watch: {  //此处为关键,监听tableData值的变化,进行echarts渲染
-        tableData(v) {
-            this.initEcharts3(); //值发生改变则渲染一次echarts
-        }
-    },
-    
-    computed: {
-        // 考核周期分布
-        cycleTypeList() {
-            let cycleTypeList = _.cloneDeep(this.cycleOptions)
-            cycleTypeList = cycleTypeList.filter(item => item.label !== "全部");
-            cycleTypeList = cycleTypeList.map(item => ({
-                    name: item.label,
-                    value: this.tableData.filter(data => data.cycleType == item.value).length,
-                })
-            )
-            return cycleTypeList
-        }
-    },
-    mounted() {
-        this.initEcharts3();
-    },
-    beforeDestroy() {
-        if (this.myChart) {
-            this.myChart.clear();//清空当前实例,会移除实例中所有的组件和图表
-            this.myChart.dispose();//销毁实例,实例销毁后无法再被使用
-        }
-    },
-    methods: {
-        initEcharts3() {
-            const colorList = this.colorList;
-            const option = {
-                tooltip: {//悬浮提示组件
-                    trigger: 'item',
-                },
-                legend: {
-                    show: true,
-                    x: 'center',
-                    y: 'bottom',
-                    icon: "circle",
-                    itemWidth: 10,  // 设置宽度
-                    itemHeight: 10, // 设置高度
-                    itemGap: 30
-                },
-
-                series: [
-                    {
-                        type: "pie",
-                        radius: ['40%', '65%'],//小的是内径,大的是外径
-                        data: this.cycleTypeList,
-                        itemStyle: {
-                            emphasis: {
-                                shadowBlur: 9,
-                                shadowOffsetX: 0,
-                                shadowColor: 'rgba(0, 0, 0, 0.5)'
-                            },
-                            normal: {
-                                label: {
-                                    show: true,
-                                    formatter: '{b} : {c}'
-                                },
-                                labelLine: { show: true },
-                                color: function (params) {//颜色渐变函数 前四个参数分别表示四个位置依次为左、下、右、上
-                                    return new echarts.graphic.LinearGradient(0, 1, 0, 0, [{ offset: 0, color: colorList[params.dataIndex].c1 }, { offset: 1, color: colorList[params.dataIndex].c2 }])
-                                }
-                            }
-                        }
-                    }
-                ]
-            };
-            this.myChart = this.$echarts.init(this.$refs.chart3);
-            this.myChart.setOption(option);
-            window.addEventListener("resize", () => {
-                this.myChart.resize();
-            });
-        },
-    }
-}
-</script>

+ 0 - 111
src/newPerformance/components/PersonalExamine/PieChart4.vue

@@ -1,111 +0,0 @@
-<template>
-    <!-- 按考核分类分布 -->
-    <div ref="chart4" :style="myChartStyle"></div>
-</template>
-
-<script>
-
-import echarts from 'echarts';
-
-export default {
-    props: {
-        tableData: {
-            type: Array,
-            default: () => []
-        },
-        cateList: {
-            type: Array,
-            default: () => []
-        },
-    },
-    data() {
-        return {
-            myChart: null,
-            myChartStyle: { width: "100%", height: "300px" },
-            colorList: [
-                { c1: '#40d3ff', c2: '#409EFF' }, { c1: '#ede737', c2: '#FF9600' }, { c1: '#89e398', c2: '#67c23a' },
-                { c1: '#85E9C7', c2: '#00C4CB' }, { c1: '#f393a9', c2: '#f56c6c' }, { c1: '#e69cf3', c2: '#de43f9' },
-                { c1: '#ede737', c2: '#FF9600' }, { c1: '#ede737', c2: '#FF9600' }, { c1: '#ede737', c2: '#FF9600' },
-                { c1: '#ede737', c2: '#FF9600' }, { c1: '#ede737', c2: '#FF9600' }, { c1: '#ede737', c2: '#FF9600' },
-                { c1: '#ede737', c2: '#FF9600' }, { c1: '#ede737', c2: '#FF9600' }, { c1: '#ede737', c2: '#FF9600' },
-            ],
-        }
-    },
-    
-    computed: {
-        // 考核周期分布
-        chartCateList() {
-            let cateList = []
-            cateList = this.cateList.map(item => ({
-                name: item.name, value: this.tableData.filter(data => data.cateIds.length > 0 && data.cateIds.includes(item.cateId)).length,
-            }))
-            return cateList
-        }
-    },
-    mounted() {
-        this.initEcharts4();
-    },
-    
-    watch: {
-        chartCateList(v) {
-            this.initEcharts4()
-        }
-    },
-
-    beforeDestroy() {
-        if (this.myChart) {
-            this.myChart.clear();//清空当前实例,会移除实例中所有的组件和图表
-            this.myChart.dispose();//销毁实例,实例销毁后无法再被使用
-        }
-    },
-    methods: {
-        initEcharts4() {
-            const colorList = this.colorList;
-            const option = {
-                tooltip: {//悬浮提示组件
-                    trigger: 'item',
-                },
-                legend: {
-                    show: true,
-                    x: 'center',
-                    y: 'bottom',
-                    icon: "circle",
-                    itemWidth: 10,  // 设置宽度
-                    itemHeight: 10, // 设置高度
-                    itemGap: 30
-                },
-
-                series: [
-                    {
-                        type: "pie",
-                        radius: ['40%', '65%'],//小的是内径,大的是外径
-                        data: this.chartCateList,
-                        itemStyle: {
-                            emphasis: {
-                                shadowBlur: 9,
-                                shadowOffsetX: 0,
-                                shadowColor: 'rgba(0, 0, 0, 0.5)'
-                            },
-                            normal: {
-                                label: {
-                                    show: true,
-                                    formatter: '{b} : {c}'
-                                },
-                                labelLine: { show: true },
-                                color: function (params) {//颜色渐变函数 前四个参数分别表示四个位置依次为左、下、右、上
-                                    return new echarts.graphic.LinearGradient(0, 1, 0, 0, [{ offset: 0, color: colorList[params.dataIndex].c1 }, { offset: 1, color: colorList[params.dataIndex].c2 }])
-                                }
-                            }
-                        }
-                    }
-                ]
-            };
-            this.myChart = this.$echarts.init(this.$refs.chart4);
-            this.myChart.setOption(option);
-            window.addEventListener("resize", () => {
-                this.myChart.resize();
-            });
-        },
-    }
-}
-</script>

+ 0 - 138
src/newPerformance/components/PersonalExamine/TableHeaderRender.vue

@@ -1,138 +0,0 @@
-<template>
-    <el-popover placement="bottom" width="200" trigger="manual" v-model="visible" @show="showPopover"
-        popper-class="table-header-popover">
-        <div class="table-header-popover-template">
-            <el-input placeholder="请输入内容" v-model="value" size="small" clearable @keyup.enter.native="confirm"
-                ref="sInput"></el-input>
-            <!-- <el-select >
-                    <el-option v-for="item in options" :label="item.label" :value="item.value"></el-option>
-                </el-select> -->
-            <el-checkbox-group v-model="selectedOptions">
-                <el-checkbox v-for="item in filteredOptions" :key="item.value" :label="item.value">
-                    {{ item.label }}
-                </el-checkbox>
-            </el-checkbox-group>
-        </div>
-        <div class="el-table-filter__bottom">
-            <button @click="confirm">筛选</button>
-            <button @click="resetData">重置</button>
-        </div>
-        <span slot="reference" style="margin-left: 5px" @click.stop="popClick" v-click-outside="closeOver">
-            <i class="filter-icon el-icon-search" :style="{ color: iconColor ? '#9a4b9b' : '#909399' }"></i>
-        </span>
-    </el-popover>
-</template>
-
-<script>
-export default {
-    name: "tableHeaderRender",
-    data() {
-        return {
-            value: "",
-            visible: false,
-            iconColor: false,
-        };
-    },
-    props: {
-        tableColumn: {
-            type: Object,
-            default: () => { },
-        },
-        columnProp: {
-            type: String,
-            default: "",
-        },
-        defaultValue: {
-            type: String,
-            default: "",
-        },
-        inputFilteredMap: {
-            type: Object,
-            default: () => { },
-        },
-        filteredOptions: {
-            type: Array,
-            default: () => [],
-        }
-    },
-    created() {
-        this.value = this.defaultValue;
-        this.iconColor = this.value.trim() ? true : false;
-    },
-    methods: {
-        showPopover() {
-            this.$nextTick(() => {
-                this.$refs.sInput.focus();
-            });
-        },
-        resetData() {
-            this.value = "";
-            this.visible = false;
-            this.iconColor = false;
-            const self = this;
-            if (this.inputFilteredMap[self.columnProp]) {
-                delete this.inputFilteredMap[self.columnProp];
-            }
-            self.$emit("resetChangeMethod", this.tableColumn, self.columnProp);
-        },
-        closeOver() {
-            this.visible = false;
-        },
-        popClick(e) {
-            this.visible = !this.visible;
-        },
-        confirm() {
-            this.visible = false;
-            if (this.value.trim()) {
-                this.iconColor = true;
-                this.inputFilteredMap[this.columnProp] = this.value;
-                this.$emit(
-                    "filterInputMethod",
-                    this.tableColumn,
-                    this.inputFilteredMap
-                );
-            } else {
-                this.resetData();
-            }
-        },
-    },
-    directives: {
-        clickOutside: {
-            bind(el, binding, vnode) {
-                function clickHandler(e) {
-                    if (el.contains(e.target)) {
-                        return false;
-                    }
-                    if (binding.expression) {
-                        binding.value(e);
-                    }
-                }
-                el.__vueClickOutside__ = clickHandler;
-                document.addEventListener("click", clickHandler);
-            },
-            update() { },
-            unbind(el, binding) {
-                document.removeEventListener("click", el.__vueClickOutside__);
-                delete el.__vueClickOutside__;
-            },
-        },
-    },
-};
-</script>
-
-<style scoped>
-.filter-icon {
-    font-size: 14px;
-    color: #909399;
-    cursor: pointer;
-    font-weight: 400;
-}
-
-.table-header-popover {
-    padding: 0;
-}
-
-.table-header-popover .table-header-popover-template {
-    margin: 10px;
-}
-</style>

+ 69 - 25
src/newPerformance/components/ProcessTracking.vue

@@ -92,8 +92,9 @@
 
                 </div>
 
+                <!-- 导出按钮 -->
                 <div class="flex-box-ce">
-                    <el-button type="primary" @click="exportToExcel('过程分析', '#myTable')" size="small"
+                    <el-button type="primary" @click="exportToExcel('过程跟踪', '#myTable')" size="small"
                         :loading="downloadLoading">导出明细</el-button>
                 </div>
             </div>
@@ -112,12 +113,13 @@
                     class="generalize-item">
                     <div class="fontColorC">{{ item.name }}</div>
                     <div style="font-size: 36px; font-weight: 600;margin: 5px 0;">
-                        {{tableData.filter(user => user.levelName === item.name).length}}
+                        {{ tableData.filter(user => user.levelName === item.name).length }}
                     </div>
                     <div style="width: 60px;height: 2px;" :style="{ backgroundColor: item.color }"></div>
                 </div>
             </div>
 
+
             <div class="table-box">
                 <el-table id="myTable" :data="filteredData" style="width: 100%; height: auto;"
                     :header-cell-style="{ background: '#f5f7fa' }" border stripe>
@@ -179,13 +181,13 @@
             :dept_children="false" :selected="dept_selected" :visible.sync="show_dept_selector"
             @confirm="dept_confirm" />
 
-        <el-dialog title="员工绩效详情" :visible.sync="detailDialogVisible" @close="handleClose" :close-on-click-modal="false"
-            :close-on-press-escape="true" center fullscreen :show-close="false">
+        <el-dialog title="员工绩效详情" :visible.sync="detailDialogVisible" @close="handleClose()" :close-on-click-modal="false"
+            :close-on-press-escape="true" center fullscreen :show-close="false" @open="onDialogOpen()">
             <div style=" width: 100%; height: 100%; position: relative;">
                 <el-button round style="position: absolute; top: -65px; left: 0px; z-index: 99;"
                     @click="detailDialogVisible = false">返回</el-button>
                 <!-- 我的考核 -->
-                <MyPerformance v-if="detailDialogVisible" :reviewId="reviewId" :sendEmployeeId='sendEmployeeId' />
+                <MyPerformance v-if="detailDialogVisible" :reviewId="reviewId" :sendEmployeeId='sendEmployeeId' @hasDeleteExamine="handleClose()"/>
             </div>
         </el-dialog>
     </div>
@@ -209,6 +211,7 @@ export default {
         MyPerformance
     },
     data() {
+        
         return {
             employees: [], // 员工列表
             isLeftShow: true,
@@ -262,7 +265,7 @@ export default {
                 { name: '考核人数', val: 0, color: '#FF9600' },
                 { name: '已结束', val: 0, color: '#409EFF' },
                 { name: '进行中', val: 0, color: '#67c23a' },
-                { name: '面谈中', val: 0, color: '#f56c6c' },
+                // { name: '面谈中', val: 0, color: '#f56c6c' },
                 // { name: '已取消', val: 0, color: '#5F7294' },
                 // { name: '未开始', val: 0, color: '#08EEA1' },
                 // { name: '暂停中', val: 0, color: '#f56c6c' }
@@ -347,6 +350,10 @@ export default {
         this.initDefaultParams();
     },
 
+    beforeDestroy() {
+        this.detailDialogVisible = false
+    },
+
     // 
     computed: {
         ...mapGetters(['user_info']),
@@ -382,6 +389,37 @@ export default {
 
     methods: {
 
+        /* 开启 dialog 时:禁用返回键 */
+        onDialogOpen() {
+            // 立即往 history 里插一条空记录,拦截返回
+            history.pushState(null, null, location.href);
+            // 监听 popstate
+            window.addEventListener('popstate', this.blockPopstate, false);
+        },
+
+        /* 关闭 dialog 时:恢复返回键 */
+        onDialogClose() {
+            // 移除监听
+            window.removeEventListener('popstate', this.blockPopstate, false);
+            // 可选:回退一次 history(去掉刚才插入的空记录)
+            if (history.state === null) {
+
+                history.back();
+            }
+        },
+        
+
+        /* 拦截浏览器返回键 */
+        blockPopstate(e) {
+            // 阻止默认返回行为
+            e.preventDefault();
+            // 可以选择关闭 dialog
+            this.detailDialogVisible = false;
+            // 重新插入一条记录,防止再次返回
+            history.pushState(null, null, location.href);
+        },
+        
+
         initDefaultParams() {
             const year = new Date().getFullYear();
             this.currentYear = year + ''
@@ -589,11 +627,11 @@ export default {
             // this.params.year = this.currentYear + ''
             this.params.cycleValue = this.currentMonth + ''
             this.month = this.currentMonth + ''
-            this.getRecords();
+            this.getRecords(true);
         },
         
         // 获取表格数据
-        getRecords() {
+        getRecords(isInit = false) {
             this.loading = true;
             this.filteredData = [];
             this.tableData = [];
@@ -630,25 +668,30 @@ export default {
                 this.generalizeList[0].val = this.tableData.length // 总人数
                 this.generalizeList[1].val = this.tableData.filter(item => item.status == 1).length // 已结束人数
                 this.generalizeList[2].val = this.tableData.filter(item => item.status == 0).length // 进行中人数
-                this.generalizeList[3].val = this.tableData.filter(item => item.status == 2).length // 面谈中人数
+                // this.generalizeList[3].val = this.tableData.filter(item => item.status == 2).length // 面谈中人数
                 this.applyFilters();
-                this.filteredData.forEach(item => {
-                    this.employees.push({ id: item.employeeId, name: item.employeeName })
-                    if (item.department && item.department.length > 0) {
-                        item.department.forEach(dep => {
-                            this.deptList.push(
-                                {
-                                    id: dep.dept_id,
-                                    name: dep.dept_name
-                                }
-                            )
-                        })
-                       
-                    }
-                })
 
-                // 数组去重
-                this.deptList = Array.from(new Set(this.deptList.map(JSON.stringify))).map(JSON.parse);
+                //初始化部门
+                // if (isInit) {
+                    this.filteredData.forEach(item => {
+                        this.employees.push({ id: item.employeeId, name: item.employeeName })
+                        if (item.department && item.department.length > 0) {
+                            item.department.forEach(dep => {
+                                this.deptList.push(
+                                    {
+                                        id: dep.dept_id,
+                                        name: dep.dept_name
+                                    }
+                                )
+                            })
+
+                        }
+                    })
+
+                    // 数组去重
+                    this.deptList = Array.from(new Set(this.deptList.map(JSON.stringify))).map(JSON.parse);
+                // }
+                
                 this.loading = false;
             })
         },
@@ -798,6 +841,7 @@ export default {
 
         // 关闭绩效弹框回调事件
         handleClose() {
+            this.detailDialogVisible = false
             this.getRecords();
         }
     }

+ 13 - 8
src/newPerformance/components/PublicComp/AIAssistant.vue

@@ -12,7 +12,7 @@
             <div v-if="isChatOpen" class="chat-popup">
                 <div class="chat-header">
                     <h3 class="flex-box-ce">
-                        <img src="@/assets/robot.png" alt="AI助理" style="width: 36px; height: 36px; margin-right: 10px;">
+                        <img src="@/assets/robot.png" alt="AI助理">
                         <div>AI助理</div>
                     </h3>
                     <button @click="toggleChat" class="close-button">关闭</button>
@@ -214,20 +214,20 @@ export default {
 /* 悬浮按钮样式 */
 .chat-button {
     position: fixed;
-    bottom: 20px;
-    right: 20px;
-    padding: 10px 20px;
+    bottom: 0px;
+    left: 0px;
+    padding: 10px 14px;
     background-color: #007bff;
     color: white;
     border: none;
     border-radius: 5px;
     cursor: pointer;
-    font-size: 16px;
+    font-size: 14px;
     box-sizing: border-box;
     z-index: 999;
     img {
-        width: 50px;
-        height: 50px;
+        width: 36px;
+        height: 36px;
     }
 }
 
@@ -235,7 +235,7 @@ export default {
 .chat-popup {
     position: fixed;
     bottom: 0;
-    right: 0;
+    left: 0;
     width: 600px;
     height: 700px;
     background-color: white;
@@ -252,6 +252,11 @@ export default {
     padding: 10px;
     border-bottom: 1px solid #eee;
     box-sizing: border-box;
+    img {
+        width: 36px;
+        height: 36px;
+        margin-right: 10px;
+    }
 }
 
 .close-button {

+ 0 - 0
src/newPerformance/components/PublicComp/BindingOKR/ChooseKR.vue


+ 0 - 0
src/newPerformance/components/PublicComp/PerformanceWorkflow.vue


+ 2 - 1
src/newPerformance/components/PublicComp/ShowHanderDialog2.vue

@@ -348,7 +348,7 @@
                                                 </div>
                                             </template>
 
-
+                                            
                                         </div>
                                         <div v-else>
                                             未开始
@@ -614,6 +614,7 @@ export default {
         color: #999;
         transition: 0.2s;
         padding-left: 10px;
+        box-sizing: border-box;
         &:hover {
             text-decoration: underline;
             cursor: pointer;

+ 622 - 0
src/newPerformance/components/PublicComp/TargetPlanComp.vue

@@ -0,0 +1,622 @@
+<template>
+    <el-dialog title="关联OKR" :visible="dialogVisible" :fullscreen="true" center @close="close" append-to-body
+        custom-class="full-dialog">
+
+        <div class="dialog-box">
+            <div class="table-box">
+                <div class="tabs">
+                    <div class="tab-item" @click="activeName = 'first'" :class="activeName === 'first' ? 'active' : ''">
+                        任务数据
+                    </div>
+                    <div class="tab-item" @click="activeName = 'second'"
+                        :class="activeName === 'second' ? 'active' : ''">历史进展</div>
+                    <div class="tab-item" @click="activeName = 'third'" :class="activeName === 'third' ? 'active' : ''">
+                        显示图表</div>
+                </div>
+
+                <div style="width: 100%; height: calc(100% - 50px); margin-top: 10px;"
+                    v-if="sourceData && sourceData.plans && sourceData.plans.length">
+                    <template v-if="activeName === 'first'">
+                        <vxe-table :data="sourceData.plans" border style="width: 100%;" height="auto">
+                            <vxe-column field="name" title="任务标题" show-overflow :width="300" />
+                            <vxe-column field="ownerName" title="负责人" width="100" />
+                            <vxe-column field="startTime" title="任务时间" width="200">
+                                <template #default="{ row }">
+                                    <div v-if="row.startTime && row.endTime" class="flex-box-ce">{{ `${row.startTime} 至
+                                        ${row.endTime}` }}</div>
+                                    <span v-else>--</span>
+                                </template>
+                            </vxe-column>
+
+                            <vxe-column field="process" title="进度" width="300">
+                                <template #default="{ row }">
+                                    <div class="flex-box-ce">
+                                        <el-tag size="mini" v-if="row.processLast !== null"
+                                            :type="row.process > row.processLast ? 'success' : (row.process < row.processLast ? 'danger' : 'warning')">
+                                            <i v-if="row.process > row.processLast" class="el-icon-top"></i>
+                                            <i v-else-if="row.process < row.processLast" class="el-icon-bottom"></i>
+                                            {{ row.process }}%
+                                        </el-tag>
+                                        <el-tag size="mini" style="margin: 0 10px;"
+                                            :type="compositeStates[row.compositeState].color || 'info'">
+                                            {{ compositeStates[row.compositeState].title || '--' }}
+                                        </el-tag>
+                                        <el-tag v-if="row.workHour !== null" type="info" size="mini">{{ `耗时
+                                            ${row.workHour} 小时`
+                                            }}</el-tag>
+                                    </div>
+
+                                </template>
+                            </vxe-column>
+
+
+                            <vxe-column field="parent" title="对齐">
+                                <template #default="{ row }">
+                                    <template v-if="row.mainParent">
+                                        <div>
+                                            <el-link type="info" style="margin-bottom: 10px;">
+                                                所属KR/项目&nbsp;:&nbsp;
+                                            </el-link>
+                                            <div class="flex-box-ce" style="padding: 0; margin: 0 0 10px 0;">
+                                                <el-tag size="mini" v-if="row.mainParent.processLast !== null"
+                                                    :type="row.mainParent.process > row.mainParent.processLast ? 'success' : (row.mainParent.process < row.mainParent.processLast ? 'danger' : 'warning')">
+                                                    <i v-if="row.mainParent.process > row.mainParent.processLast"
+                                                        class="el-icon-top"></i>
+                                                    <i v-else-if="row.mainParent.process < row.mainParent.processLast"
+                                                        class="el-icon-bottom"></i>
+                                                    {{ row.mainParent.process }}%
+                                                </el-tag>
+                                                <el-tag size="mini" type="primary" class="text-hidden"
+                                                    style="max-width: 300px; margin: 0 10px;">
+                                                    {{ row.mainParent.name }}
+                                                </el-tag>
+                                                <span style="margin-right: 10px;">--</span>
+
+                                                <template v-if="row.mainParent.children">
+                                                    <el-tag size="mini"
+                                                        v-if="row.mainParent.children.processLast !== null"
+                                                        :type="row.mainParent.children.process > row.mainParent.children.processLast ? 'success' : (row.mainParent.children.process < row.mainParent.children.processLast ? 'danger' : 'warning')">
+                                                        <i v-if="row.mainParent.children.process > row.mainParent.children.processLast"
+                                                            class="el-icon-top"></i>
+                                                        <i v-else-if="row.mainParent.children.process < row.mainParent.children.processLast"
+                                                            class="el-icon-bottom"></i>
+                                                        {{ row.mainParent.children.process }}%
+                                                    </el-tag>
+                                                    <el-tag size="mini" type="success" class="text-hidden"
+                                                        style="max-width: 300px; margin: 0 10px;">
+                                                        {{ row.mainParent.children.name }}
+                                                    </el-tag>
+
+                                                </template>
+                                            </div>
+
+                                        </div>
+                                    </template>
+
+                                    <template v-if="row.otherParent && row.otherParent.length > 0">
+                                        <el-link type="info" style="margin-bottom: 10px;">
+                                            关联其他&nbsp;:&nbsp;
+                                        </el-link>
+                                        <div v-for="parent in row.otherParent" :key="parent.id" class="flex-box-ce"
+                                            style="padding: 0; margin: 0 0 10px 0;">
+                                            <el-tag size="mini" v-if="parent.processLast !== null"
+                                                :type="parent.process > parent.processLast ? 'success' : (parent.process < parent.processLast ? 'danger' : 'warning')">
+                                                <i v-if="parent.process > parent.processLast" class="el-icon-top"></i>
+                                                <i v-else-if="parent.process < parent.processLast"
+                                                    class="el-icon-bottom"></i>
+                                                {{ parent.process }}%
+                                            </el-tag>
+                                            <el-tag size="mini" type="primary" class="text-hidden"
+                                                style="max-width: 300px; margin: 0 10px;">
+                                                {{ parent.name }}
+                                            </el-tag>
+                                            <span style="margin-right: 10px;">--</span>
+                                            <template v-if="parent.children">
+                                                <el-tag size="mini" v-if="parent.children.processLast !== null"
+                                                    :type="parent.children.process > parent.children.processLast ? 'success' : (parent.children.process < parent.children.processLast ? 'danger' : 'warning')">
+                                                    <i v-if="parent.children.process > parent.children.processLast"
+                                                        class="el-icon-top"></i>
+                                                    <i v-else-if="parent.children.process < parent.children.processLast"
+                                                        class="el-icon-bottom"></i>
+                                                    {{ parent.children.process }}%
+                                                </el-tag>
+                                                <el-tag size="mini" type="success" class="text-hidden"
+                                                    style="max-width: 300px; margin: 0 10px;">
+                                                    {{ parent.children.name }}
+                                                </el-tag>
+                                            </template>
+                                        </div>
+                                    </template>
+                                </template>
+                            </vxe-column>
+                        </vxe-table>
+
+
+                    </template>
+
+                    <template v-if="activeName === 'second'">
+
+                        <vxe-table border :data="processHistory" :column-config="{ resizable: true }"
+                            :row-config="{ isHover: true, isCurrent: true }" height="auto" resizable show-overflow auto-resize>
+                            <vxe-column field="name" title="任务标题" show-overflow width="300" fixed="left" />
+                            <vxe-column field="ownerName" title="负责人" width="100" fixed="left" />
+                            <vxe-column field="process" title="最新进度" width="300">
+                                <template #default="{ row }">
+                                    <div class="flex-box-ce">
+                                        <el-tag size="mini" v-if="row.processLast !== null"
+                                            :type="row.process > row.processLast ? 'success' : (row.process < row.processLast ? 'danger' : 'warning')">
+                                            <i v-if="row.process > row.processLast" class="el-icon-top"></i>
+                                            <i v-else-if="row.process < row.processLast" class="el-icon-bottom"></i>
+                                            {{ row.process }}%
+                                        </el-tag>
+                                        <el-tag size="mini" :type="compositeStates[row.compositeState].color || 'info'"
+                                            style="margin: 0 10px;">
+                                            {{ compositeStates[row.compositeState].title || '--' }}
+                                        </el-tag>
+                                        <el-tag v-if="row.workHour !== null" size="mini" type="info">{{ `耗时
+                                            ${row.workHour} 小时`
+                                            }}</el-tag>
+
+                                    </div>
+                                </template>
+                            </vxe-column>
+
+                            <vxe-column v-for="header in processHeader" :key="header" :title="header" min-width="120">
+                                <template #default="{ row }">
+                                    <div>{{ !row[header.replaceAll('-', '')] ? '--' : `${row[header.replaceAll('-',
+                                        '')].process} %` }}</div>
+                                </template>
+                            </vxe-column>
+                            
+                        </vxe-table>
+                    </template>
+
+                    <template v-if="activeName === 'third'">
+                        <div class="chart-box">
+                            <div class="chart" style="width: 98%; height: 100%; margin-right: 10px;">
+                                <div ref="chart1" style="width: 100%; height: 100%;"></div>
+                            </div>
+                            <div class="chart" style="width: 98%; height: 100%;">
+                                <div ref="chart2" style="width: 100%; height: 100%;"></div>
+                            </div>
+                        </div>
+                    </template>
+                </div>
+
+
+            </div>
+        </div>
+    </el-dialog>
+</template>
+
+
+<script>
+import { mapGetters } from 'vuex';
+import moment from "moment";
+
+
+const compositeStates = {
+    1:{ title: '未开始', color: 'info' },
+    2: { title: '运行中', color: 'primary' },
+    3: { title: '已延期', color: 'danger' },
+    4: { title: '暂停', color: 'warning' },
+    5: { title: '审批中', color: 'primary' },
+    6: { title: '已完成', color: 'success' },
+    7: { title: '取消', color: 'warning' },
+    8: { title: '已达标', color: 'primary' },
+    9: { title: '已审批通过', color: 'primary' }
+}
+
+
+
+export default {
+    name: "TargetPlanComp",
+    data() {
+        return {
+            activeName: "first",
+            chartToggle: false,
+            sourceData: null, // OKR数据源
+            processHeader: [], // 历史进度表头
+            processHistory: [], // 历史进度数据
+            baseColor: {
+                background: 'background',
+                surface: 'surface',
+                primary: 'primary',
+                secondary: 'secondary',
+                success: 'success',
+                warning: 'warning',
+                error: 'error',
+                info: 'info',
+                white: 'white'
+            },
+            myChart1: null,
+            myChart2: null,
+        }
+    },
+
+    
+    props: {
+        dialogVisible: {
+            type: Boolean,
+            default: false
+        },
+        // 关联的指标ID
+        reviewIndicatorId: {
+            type: String | Number,
+            default: ''
+        }
+    },
+
+    watch: {
+        activeName(newVal) {
+            if (newVal === 'third') {
+                console.log('切换到显示图表');
+                this.renderChart();
+            }
+        }
+    },
+
+    computed: {
+        ...mapGetters(['user_info']),
+
+        compositeStates() {
+            return ({
+                1: { title: '未开始', color: 'info' },
+                2: { title: '运行中', color: 'primary' },
+                3: { title: '已延期', color: 'danger' },
+                4: { title: '暂停', color: 'warning'},
+                5: { title: '审批中', color: 'primary' },
+                6: { title: '已完成', color: 'success' },
+                7: { title: '取消', color: 'warning' },
+                8: { title: '已达标', color: 'primary'},
+                9: { title: '已审批通过', color: 'primary'}
+            })
+        },
+
+        statusData() {
+            if (this.sourceData && this.sourceData.plans && this.sourceData.plans.length > 0) {
+                const statusMap = {}
+                this.sourceData.plans.forEach(plan => {
+                    if (!statusMap[plan.compositeState]) statusMap[plan.compositeState] = { compositeState: plan.compositeState, value: 0, name: compositeStates[plan.compositeState] && compositeStates[plan.compositeState].title || '未定义' }
+
+                    statusMap[plan.compositeState].value++;
+                })
+                return Object.values(statusMap);
+            }
+            else return [];
+        },
+
+        chartStatusOption() {
+            let that = this
+
+            // 10 组固定配色(可换成任何渐变)
+            const COLOR_LIST = [
+                '#5470c6', '#91cc75', '#fac858',
+                '#ee6666', '#73c0de', '#3ba272',
+                '#fc8452', '#9a60b4', '#ea7ccc'
+            ];
+            const statusOption = {
+                legend: {
+                    left: 'center',
+                    top: '30'
+                },
+                title: {
+                    text: 'OKR状态分布',
+                    left: 'center',
+                    textStyle: {
+                        fontSize: 16   // ← 这里改大小
+                    }
+                },
+                color: COLOR_LIST,
+                tooltip: {
+                    trigger: 'item'
+                },
+                
+                series: [
+                    {
+                        type: 'pie',
+                        radius: ['40%', '60%'],//在此处控制环的大小,第一个数据为内环,第二个为外环
+                        center: ['50%', '60%'],
+                        data: [],
+                        itemStyle: {
+                            shadowBlur: 10,
+                            shadowOffsetX: 0,
+                            shadowColor: 'rgba(0, 0, 0, 0.5)',
+                            fontColor: "#000",
+                            normal: {
+                                label: {
+                                    show: true,
+                                    formatter: '{b} : {c}'
+                                },
+                                
+                            }
+                        }
+                    }
+                ]
+            };
+
+            if (this.statusData && this.statusData.length > 0) {
+                this.statusData.forEach(status => {
+                    statusOption.series[0].data.push({ value: status.value, name: status.name });
+                })
+            }
+
+            return statusOption;
+        },
+
+
+        chartUserOption() {
+            const COLOR_LIST = [
+                '#5470c6', '#91cc75', '#fac858',
+                '#ee6666', '#73c0de', '#3ba272',
+                '#fc8452', '#9a60b4', '#ea7ccc'
+            ];
+            const userOption = {
+                legend: {
+                    left: 'center',
+                    top: '30'
+                },
+                color: COLOR_LIST,
+                tooltip: {},
+                xAxis: { type: 'category' },
+                yAxis: {},
+                grid: {
+                    left: '10%',      // 左侧与容器的距离(百分比或像素)
+                    right: '10%',     // 右侧与容器的距离
+                    top: 60,          // 顶部与容器的距离(像素)
+                    bottom: 60,       // 底部与容器的距离
+                    containLabel: true // 是否包含坐标轴标签(默认false,可能导致标签溢出)
+                },
+                title: {
+                    text: '用户分布',
+                    left: 'center',
+                    textStyle: {
+                        fontSize: 16   // ← 这里改大小
+                    }
+                },
+                dataset: {
+                    source: [
+                        ['status']
+                    ],
+                },
+                series: [],
+                dataZoom: [
+                    {
+                        type: 'slider',
+                        xAxisIndex: 0,
+                        start: 0,  // 初始显示范围(0-100%)
+                        end: 100    // 例如只显示前30%的数据
+                    },
+                    {
+                        type: 'inside',  // 支持鼠标滚轮缩放
+                        xAxisIndex: 0
+                    }
+                ]
+            }
+
+            if (this.statusData && this.statusData.length > 0) {
+                this.statusData.forEach(status => {
+                    userOption.dataset.source[0].push(status.name || '未定义');
+                    userOption.series.push({ type: 'bar', barWidth: 20 });
+                })
+            }
+            
+            if (this.statusData && this.statusData.length > 0) {
+                const keyMap = {
+                    1: 'waitingCount',
+                    2: 'runningCount',
+                    3: 'delayCount',
+                    4: 'stopCount',
+                    5: 'reviewingCount',
+                    6: 'finishCount',
+                    7: 'cancelCount',
+                    8: 'standardCount',
+                    9: 'reviewCompleteCount',
+                }
+
+                this.sourceData.employees.forEach(employee => {
+                    const data = [employee.name];
+                    this.statusData.forEach(status => {
+                        if (keyMap[status.compositeState]) {
+                            data.push(employee.compositeState[keyMap[status.compositeState]] ? employee.compositeState[keyMap[status.compositeState]] : 0);
+                        } else {
+                            data.push(0);
+                        }
+
+                        userOption.dataset.source.push(data);
+                    })
+                })
+                
+            }
+
+            return userOption;
+        }
+    },
+
+    beforeDestroy() {
+        this.myChart1 && this.myChart1.dispose()
+        this.myChart2 && this.myChart2.dispose()
+    },
+
+    mounted() {
+        this.getOkrData();
+    },
+
+    methods: {
+
+        renderChart() {
+            // 等 DOM 渲染完再 init
+            this.$nextTick(() => {
+                this.myChart1 = this.$refs.chart1 && this.$echarts.init(this.$refs.chart1);
+                this.myChart1 && this.myChart1.setOption(this.chartStatusOption);
+                this.myChart2 = this.$refs.chart2 && this.$echarts.init(this.$refs.chart2);
+                this.myChart2 && this.myChart2.setOption(this.chartUserOption);
+                window.addEventListener("resize", () => {
+                    this.myChart1 && this.myChart1.resize();
+                    this.myChart2 && this.myChart2.resize();
+                });
+            })
+        },
+
+        
+        close() {
+            this.$emit("close")
+        },
+
+        getOkrData() {
+            // 这里可以添加获取OKR数据的逻辑
+            let url = `/performance/statistics/okrs/indicator/${this.user_info.site_id}/${this.reviewIndicatorId}`;
+            this.$axiosUser('get', url).then(res => {
+                // console.log(res)
+                //封装历史进度数据
+                this.processHeader = [];
+                this.processHistory = [];
+                let header = new Set();
+                this.sourceData = res.data.data;
+                if (this.sourceData.plans && this.sourceData.plans.length > 0) {
+                    this.sourceData.plans.forEach(item => {
+                        let data = {
+                            id: item.id,
+                            name: item.name,
+                            ownerName: item.ownerName,
+                            process: item.process,
+                            processLast: item.processLast,
+                            workHour: item.workHour,
+                            compositeState: item.compositeState,
+                        };
+
+                        if (item.processHistory) {
+                            header = new Set([...header, ...Object.keys(item.processHistory)])
+                            data = {
+                                ...data,
+                                ...item.processHistory,
+                            }
+                        }
+                        this.processHistory.push(data)
+                    })
+                    this.processHeader = [...header].sort();
+                    if (this.processHeader.length > 0) {
+                        this.processHeader.forEach((item, index) => {
+                            this.processHeader[index] = moment(item).format('YYYY-MM-DD');
+                        });
+                    }
+
+                    this.renderChart();
+                }
+            })
+        },
+
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+
+.more-btn {
+    border-radius: 6px;
+    padding: 0 5px;
+    width: 80px;
+    text-align: center;
+    box-sizing: border-box;
+    height: 24px;
+    font-size: 14px;
+    line-height: 24px;
+    color: #409EFF;
+    border-width: 1px;
+    border-style: solid;
+    background-color: #ecf5ff;
+    border-color: #d9ecff;
+    position: absolute;
+    top: 15px;
+    left: 10px;
+    &:hover {
+        cursor: pointer;
+    }
+}
+
+.chart-box {
+    width: 98%;
+    margin: 0 auto;
+    display: flex;
+    justify-content: space-between;
+    height: 400px;
+    .chart {
+        box-sizing: border-box;
+        background-color: #fff;
+        border-radius: 6px;
+        padding: 10px;
+        box-sizing: border-box;
+        border: 1px solid #ebeef5;
+        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
+    }
+}
+
+    .full-dialog {
+        position: fixed;
+        top: 0;
+        left: 0;
+        width: 100vw;
+        height: 100vh;
+        margin: 0;
+        padding: 0;
+        border-radius: 0;
+        /* 防止滚动条 */
+    }
+
+    .text-hidden {
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        overflow: hidden;
+    }
+    /deep/ .el-dialog__body {
+        width: 100%;
+        height: calc(100% - 60px);
+        padding: 10px;
+        box-sizing: border-box;
+        overflow: hidden;
+        background-color: #f7f7f7;
+    }
+    .dialog-box {
+        width: 100%;
+        height: 100%;
+        box-sizing: border-box;
+        display: flex;
+        flex-direction: column;
+        position: relative;
+
+        .table-box {
+            width: 100% !important;
+            flex: 1;
+            margin-top: 10px;
+            border-radius: 6px;
+            border: 1px solid #ebeef5;
+            overflow-y: auto;
+            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
+            background-color: #fff;
+            .tabs {
+                width: 100%;
+                height: 40px;
+                padding: 0 10px 10px 10px;
+                box-sizing: border-box;
+                display: flex;
+                .tab-item {
+                    width: 100px;
+                    height: 40px;
+                    line-height: 40px;
+                    font-size: 14px;
+                    text-align: center;
+                    &:hover {
+                        cursor: pointer;
+                    }
+                    &.active {
+                        color: #409EFF;
+                        font-weight: 600;
+                        border-bottom: 2px solid #409EFF;
+                    }
+                    
+                }
+            }
+        }
+    }
+
+</style>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.