瀏覽代碼

新绩效8.02.23

manywhy 1 月之前
父節點
當前提交
53c6eb8390
共有 100 個文件被更改,包括 35299 次插入901 次删除
  1. 1 1
      config/dev.env.js
  2. 2 0
      config/prod.env.js
  3. 二進制
      dist.rar
  4. 4 4
      index.html
  5. 1 1
      src/App.vue
  6. 3 4
      src/attendance/components/TimeSelectSwitch.vue
  7. 1 1
      src/attendance/view/AttendanceNew/ApplyRecord.vue
  8. 7 7
      src/attendance/view/AttendanceNew/ApproveRecord.vue
  9. 42 6
      src/attendance/view/AttendanceNew/AskForLeave.vue
  10. 26 14
      src/attendance/view/AttendanceNew/Rank.vue
  11. 1 1
      src/attendance/view/AttendanceNew/RecordDetail.vue
  12. 1 0
      src/attendance/view/AttendanceStatistic/SwitchDate.vue
  13. 4 3
      src/attendance/view/AttendanceStatistic/index.vue
  14. 1 1
      src/components/DeptSelectorDropdown.vue
  15. 3 1
      src/components/EmployeeSelector.vue
  16. 8 4
      src/components/OssUploader.vue
  17. 1 1
      src/components/vue-img-cropper.vue
  18. 1 0
      src/main.js
  19. 1525 0
      src/newPerformance/components/performanceDetails.vue
  20. 499 0
      src/newPerformance/components/public/More.vue
  21. 203 0
      src/newPerformance/components/public/OperateLog.vue
  22. 40 0
      src/newPerformance/components/public/VanSkeleton.vue
  23. 377 0
      src/newPerformance/components/workbenchcontent/backlog.vue
  24. 199 0
      src/newPerformance/utils/auth.js
  25. 34 0
      src/newPerformance/utils/observer-store.js
  26. 606 0
      src/newPerformance/view/handleDetails.vue
  27. 104 0
      src/newPerformance/view/inits.vue
  28. 863 0
      src/newPerformance/view/myTarget/krDetail.vue
  29. 244 160
      src/newPerformance/view/myTarget/myTarget.vue
  30. 945 0
      src/newPerformance/view/myTarget/targetDetail.vue
  31. 467 0
      src/newPerformance/view/navhome/me.vue
  32. 494 0
      src/newPerformance/view/navhome/more.vue
  33. 644 0
      src/newPerformance/view/navhome/organizationExamine.vue
  34. 195 0
      src/newPerformance/view/navhome/perAttentionList.vue
  35. 1177 0
      src/newPerformance/view/navhome/resultAnalysis.vue
  36. 963 0
      src/newPerformance/view/navhome/statement.vue
  37. 782 0
      src/newPerformance/view/navhome/workbench.vue
  38. 173 0
      src/newPerformance/view/navigation.vue
  39. 495 0
      src/newPerformance/view/performanceHome.vue
  40. 571 0
      src/newPerformance/view/performanceHome2.vue
  41. 11 4
      src/okr/components/public/Evolve.vue
  42. 1 1
      src/okr/view/project/projectDetail.vue
  43. 2 2
      src/okr/view/project/projectList.vue
  44. 3 3
      src/okr/view/target/attentionList.vue
  45. 10 5
      src/okr/view/target/communication.vue
  46. 23 16
      src/okr/view/target/target.vue
  47. 10 10
      src/okr/view/target/targetDetail.vue
  48. 104 70
      src/okr/view/task/taskDetail.vue
  49. 522 0
      src/performance-07-19/components/actionplan/actionplanDetails.vue
  50. 173 0
      src/performance-07-19/components/actionplan/actionplanList.vue
  51. 449 0
      src/performance-07-19/components/actionplan/addthePlan.vue
  52. 552 0
      src/performance-07-19/components/actionplan/resultValueEntry.vue
  53. 472 0
      src/performance-07-19/components/actionplan/resultValueEntryAll.vue
  54. 1175 0
      src/performance-07-19/components/actionplan/resultValueEntryMb.vue
  55. 2616 0
      src/performance-07-19/components/performanceDetails - 副本.vue
  56. 782 0
      src/performance-07-19/components/performanceDetails.vue
  57. 133 0
      src/performance-07-19/components/public/OperateLog.vue
  58. 40 0
      src/performance-07-19/components/public/VanSkeleton.vue
  59. 289 0
      src/performance-07-19/components/statementcontent/statement_details.vue
  60. 308 0
      src/performance-07-19/components/workbenchcontent/affirm.vue
  61. 232 0
      src/performance-07-19/components/workbenchcontent/backlog - 副本 (2).vue
  62. 410 0
      src/performance-07-19/components/workbenchcontent/backlog-副本.vue
  63. 359 0
      src/performance-07-19/components/workbenchcontent/backlog.vue
  64. 229 0
      src/performance-07-19/components/workbenchcontent/messageInform.vue
  65. 322 0
      src/performance-07-19/components/workbenchcontent/workList_details.vue
  66. 199 0
      src/performance-07-19/utils/auth.js
  67. 216 0
      src/performance-07-19/view/handleDetails - 副本.vue
  68. 612 0
      src/performance-07-19/view/handleDetails.vue
  69. 104 0
      src/performance-07-19/view/inits.vue
  70. 863 0
      src/performance-07-19/view/myTarget/krDetail.vue
  71. 606 0
      src/performance-07-19/view/myTarget/myTarget.vue
  72. 945 0
      src/performance-07-19/view/myTarget/targetDetail.vue
  73. 126 0
      src/performance-07-19/view/navhome/me - 副本.vue
  74. 453 0
      src/performance-07-19/view/navhome/me.vue
  75. 483 0
      src/performance-07-19/view/navhome/more.vue
  76. 610 0
      src/performance-07-19/view/navhome/organizationExamine.vue
  77. 429 0
      src/performance-07-19/view/navhome/perAttentionList.vue
  78. 1094 0
      src/performance-07-19/view/navhome/resultAnalysis.vue
  79. 961 0
      src/performance-07-19/view/navhome/statement - 副本.vue
  80. 816 0
      src/performance-07-19/view/navhome/statement.vue
  81. 782 0
      src/performance-07-19/view/navhome/workbench.vue
  82. 173 0
      src/performance-07-19/view/navigation.vue
  83. 363 0
      src/performance-07-19/view/performanceHome - 副本 (2).vue
  84. 781 0
      src/performance-07-19/view/performanceHome - 副本.vue
  85. 1 0
      src/performance-07-19/view/performanceHome.vue
  86. 1 1
      src/performance/components/actionplan/actionplanDetails.vue
  87. 150 41
      src/performance/components/actionplan/resultValueEntry.vue
  88. 1100 526
      src/performance/components/actionplan/resultValueEntryMb.vue
  89. 35 6
      src/performance/components/performanceDetails.vue
  90. 2 1
      src/performance/components/workbenchcontent/backlog.vue
  91. 1 1
      src/performance/utils/auth.js
  92. 863 0
      src/performance/view/myTarget/krDetail.vue
  93. 606 0
      src/performance/view/myTarget/myTarget.vue
  94. 945 0
      src/performance/view/myTarget/targetDetail.vue
  95. 37 2
      src/performance/view/performanceHome.vue
  96. 1 1
      src/point/view/body/add_common_menu.vue
  97. 1 1
      src/point/view/integral/appealList.vue
  98. 3 0
      src/point/view/integral/deptRank.vue
  99. 1 1
      src/point/view/integral/event_list.vue
  100. 2 0
      src/point/view/integral/integral_entry_n.vue

+ 1 - 1
config/dev.env.js

@@ -14,7 +14,7 @@ module.exports = merge(prodEnv, {
   VUE_APP_WEBSCOKET:'"wss://new.gdy.g107.com/ws_v2/"',
   VUE_APP_WEBSCOKET_TOW:'"wss://new.gdy.g107.com/ws2/"',
 
-  // NODE_ENV: '"production"',
+  // NODE_ENV: '"development"',
   // BASE_API: '"https://oa.g107.com"',
   // BASE_API_KQ: '"https://ad.g107.com"',
   // VUE_APP_WXURL:'"https://oa.g107.com/wx/mp/auth/wx65f4dde5ec7c31e7"',

+ 2 - 0
config/prod.env.js

@@ -11,3 +11,5 @@ module.exports = {
   VUE_APP_WEBSCOKET:'"wss://oa.g107.com/ws_v2/"',
   VUE_APP_WEBSCOKET_TOW:'"wss://oa.g107.com/ws2/"'
 }
+
+

二進制
dist.rar


+ 4 - 4
index.html

@@ -28,7 +28,7 @@
       // }
       // function get_item(key){
       //   if(window.plus){
-      //     return plus.storage.getItem(key)
+      //     return plus.storage.getItem(key)发发发方法  人飞刚返岗
       //   }else{
       //     return localStorage.getItem(key)
       //   }
@@ -72,9 +72,9 @@
       //setInterval(function () {
 		  var wv_current = plus.webview.currentWebview().nativeInstanceObject()
 		  if (plus.os.name != 'Android') {
-			wv_current.plusCallMethod({
-			  'setKeyboardDisplayRequiresUserAction': false
-			})
+        wv_current.plusCallMethod({
+          'setKeyboardDisplayRequiresUserAction': false
+        })
 		  }
 		  var webview = plus.webview.all();
 		  webview = webview[webview.length - 1]

+ 1 - 1
src/App.vue

@@ -1,7 +1,7 @@
 <template>
   <div style="width:100%; height: 100%; position: relative;">
      <vc-keep-alive :ignorePaths="ignorePaths" :ignoreParams="ignoreParams">
-        <router-view style="width:100%;height:100%"></router-view>
+        <router-view style="width: 100%; height:100%"></router-view>
      </vc-keep-alive>
   </div>
 </template>

+ 3 - 4
src/attendance/components/TimeSelectSwitch.vue

@@ -214,6 +214,7 @@ export default {
     }
   }
   .time-switch-btn {
+    width: 2.2rem;
     margin: 0.6rem 0 0.8rem 0.24rem;
     padding-left: 0.2rem;
     text-align: center;
@@ -222,11 +223,9 @@ export default {
     background-color: #fff;
     border: 0.02rem solid #26a2ff;
     border-radius: 0.08rem;
-    // width: 2rem;
     color: #26a2ff;
-    // display: flex;
-    display: inline-block;
-    // align-items: center;
+    display: flex;
+    align-items: center;
   }
   .month-wrapper {
     text-align: center;

+ 1 - 1
src/attendance/view/AttendanceNew/ApplyRecord.vue

@@ -421,7 +421,7 @@ export default {
   color: #909399;
 }
 .leftkep {
-  padding: 0.2rem 0.12rem 0.2rem 0.32rem;
+  padding: 0.2rem 0.32rem ;
   box-sizing: border-box;
 }
 .headAll {

+ 7 - 7
src/attendance/view/AttendanceNew/ApproveRecord.vue

@@ -4,9 +4,9 @@
     <van-nav-bar title="考勤审批" left-text="返回" left-arrow @click-left="$route_back" />
     <div class="approveRecord">
       <van-tabs v-model="status" @change="handleClick">
-        <van-tab name="waiting" :title="'待审批(' + reviewTotal + ')'"></van-tab>
-        <van-tab name="dealed" title="已审批"></van-tab>
-        <van-tab name="all" title="抄送给我"></van-tab>
+        <van-tab name="waiting" :title="'待审批(' + reviewTotal + ')'"></van-tab>
+        <van-tab name="dealed" title="已审批"></van-tab>
+        <van-tab name="all" title="抄送"></van-tab>
       </van-tabs>
       <div class="head-Nav">
         <van-row>
@@ -20,7 +20,7 @@
               <div class="content">
                 <div class="title">
                   <div class="detail">{{ item.employee_name }}提交的{{ filterType(item.type) }}申请</div>
-                  <div :class="{ wait: item.status == 0, refuse: item.status == -1 }" class="status">{{ filterStatus(item.status) }}</div>
+                  <div :class="{ wait: item.review_status == 0, refuse: item.review_status == -1 }" class="status">{{ filterStatus(item.review_status) }}</div>
                 </div>
                 <div v-if="item.type == 5" class="desc">申请类型:{{ item.holiday_name }}</div>
                 <div class="desc">申请时间:{{ formatTime(item.create_time) }}</div>
@@ -146,13 +146,13 @@ export default {
     },
     filterStatus(status) {
       if (status === 0) {
-        return '待审批';
+        return '待处理';
       }
       if (status === 1) {
-        return '审批通过';
+        return '通过';
       }
       if (status === -1) {
-        return '审批驳回';
+        return '驳回';
       }
     },
     filterType(type) {

+ 42 - 6
src/attendance/view/AttendanceNew/AskForLeave.vue

@@ -2,13 +2,12 @@
   <div class="AskForLeave">
     <van-nav-bar title="请假" left-text="返回" left-arrow @click-left="$route_back" />
     <div class="headAll">
-      <div style="position:relative;margin-bottom: 0.24rem;" @click="isEmptyType">
-        <van-cell :title="'请假类型'" :is-link="!vacationText" :class="{ select: vacationText }" :value="vacationText ? vacationText : '请选择'">
-          <em v-show="!vacationText" style="color:rgb(244,107,107);position:absolute;top:0.4rem;left:0.14rem;" slot="icon">*</em>
+      <div style="position:relative; margin-bottom: 0.24rem;">
+        <van-cell required :title="'请假类型'" :value="vacationText ? vacationText : '请选择'" @click="popupShow = true">
         </van-cell>
-        <select  v-model="formData.rule_id" class="vacationSelect">
+        <!-- <select  v-model="formData.rule_id" class="vacationSelect">
           <option v-for="item in vacationType" :key="item.id" :value="item.id">{{ item.name }}</option>
-        </select>
+        </select> -->
       </div>
       <div class="restTiem" v-if="remainTime >= 0 && balance_enabled == 1">假期余额:{{ remainTime }}(小时)</div>
       <TimeSelector
@@ -45,6 +44,19 @@
       </van-cell>
       <AddReviewer :numbers="1" :value.sync="formData.reviewers"></AddReviewer>
       <AddReviewer :numbers="5" addType="copyTo" :value.sync="formData.notices"></AddReviewer>
+      <van-popup
+        v-model="popupShow"
+        position="bottom" :get-container="getContainer"
+      >
+        <van-picker
+          title="请假类型"
+          show-toolbar
+          :columns="vacationType"
+          @confirm="onConfirm"
+          @cancel="onCancel"
+          @change="onChange"
+        />
+      </van-popup>
       <div class="submitBtn" @click="submitAskForLeave">确定</div>
       <div style="padding-bottom: .65rem;"></div>
     </div>
@@ -62,6 +74,7 @@ export default {
   },
   data() {
     return {
+      popupShow: false,
       balance_enabled: -1,
       remainTime: -1,
       vacationText: '',
@@ -90,7 +103,7 @@ export default {
   },
   watch:{
     'formData.rule_id'(val){
-      let holiday = this.vacationType.filter(v => v.id ===val)[0];
+      let holiday = this.vacationType.filter(v => v.id === val)[0];
       this.vacationText = holiday.name;
       this.balance_enabled = holiday.balance_enabled;//是否启用余额(0不启用,1启用)
       this.getDate();
@@ -102,6 +115,21 @@ export default {
     },
   },
   methods: {
+    getContainer() {
+      return document.body
+    },
+    onConfirm(value, index) {
+      // console.log(value, index)
+      this.vacationText = value.name;
+      this.formData.rule_id = value.id;
+      this.popupShow = false;
+    },
+    onChange(picker, value, index) {
+      console.log(`当前值:${value}, 当前索引:${index}`);
+    },
+    onCancel() {
+      this.popupShow = false;
+    },
     getDate(){
       this.$axiosKq('get', '/ad/review/my_balance', {
         rule_id: this.formData.rule_id,
@@ -133,7 +161,12 @@ export default {
                   this.vacationText = element.name;
                   this.formData.rule_id = element.id;
                 }
+                // 处理成picker组件可用的数据
+                element.text = element.name;
+                element.value = element.id;
               });
+              console.log("请假类型")
+              console.log(this.vacationType)
             }
           } else {
             this.$toast(res.data.msg);
@@ -358,5 +391,8 @@ export default {
   height: calc(100% - 0.92rem) !important;
   position:relative;
   overflow-y: scroll;
+  .required {
+    color:rgb(244,107,107); position:absolute; top: 50%; left:0.14rem; transform: translateY(-50%);
+  }
 }
 </style>

+ 26 - 14
src/attendance/view/AttendanceNew/Rank.vue

@@ -34,7 +34,12 @@
         </div>
         <div class="rankWrapper">
           <div class="title">
-            <div class="flex-box-ce groupBox" @click="isGroup = true"><span class="font-flex-word">{{selectGlText}}</span> <van-icon name="arrow-down" /></div>
+            <div class="flex-box-ce groupBox" @click="isGroup = true">
+              <span class="font-flex-word">
+                {{selectGlText}}
+              </span>
+              <van-icon name="arrow-down" />
+            </div>
             <span class="date" @click="selecteTimeRangeVisible = true">{{ timeValue }}</span>
           </div>
         </div>
@@ -71,15 +76,22 @@
       </div>
     </scroller>
     <!-- 管理记录筛选 -->
-    <van-dialog v-model="isGroup" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
-      <van-radio-group v-model="group_id">
-        <div v-for="(item, index) in groupList" :key="index">
-          <van-radio :name="item.id" @click="clickGlConfirm(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
-            <span style="margin-left:.3rem">{{ item.name }}</span>
-          </van-radio>
+    <van-dialog v-model="isGroup" title="考勤组" :show-confirm-button="false" close-on-click-overlay>
+      <template slot="default">
+        <div style="height: 8rem;overflow: auto; " class="scroll-bar">
+          <van-radio-group v-model="group_id">
+            <div v-for="(item, index) in groupList" :key="index">
+              <van-radio :name="item.id" @click="clickGlConfirm(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+                <span style="margin-left:.3rem">{{ item.name }}</span>
+              </van-radio>
+            </div>
+          </van-radio-group>
+          <div style="height: 0.5rem;"></div>
         </div>
-      </van-radio-group>
+      </template>
+
     </van-dialog>
+
     <time-select-switch @success="timeSelectSuccess" :show.sync="selecteTimeRangeVisible" :dataType="Number(formParams.date_type)"></time-select-switch>
   </div>
 </template>
@@ -217,7 +229,7 @@ export default {
         if (res.data.code == 1 && res.data.data.length > 0) {
           this.groupList= res.data.data;
           this.selectGlText=res.data.data[0].name;
-          this.group_id = res.data.data[0].id; 
+          this.group_id = res.data.data[0].id;
           this.groupList.map(item=>{
             if(item.employee_ids.length>0){
               item.employee_ids.some(item2=>{
@@ -379,11 +391,13 @@ export default {
       border: 0.02rem solid #26a2ff;
       border-radius: 0.08rem;
       color: #26a2ff;
+      position: relative;
       &::after {
         content: '';
-        position: relative;
-        right: -0.2rem;
-        top: 0.2rem;
+        position: absolute;
+        right: 0.1rem;
+        top: 50%;
+        transform: translateY(-50%);
         width: 0;
         height: 0;
         border-width: 0.08rem;
@@ -462,7 +476,6 @@ export default {
       border-bottom: 0.02rem solid #f5f7fa;
       .date {
         margin-left: auto;
-        // width: 1.82rem;
         height: 0.56rem;
         text-align: center;
         line-height: 0.56rem;
@@ -471,7 +484,6 @@ export default {
         color: #26a2ff;
         font-size: 0.28rem;
         position: relative;
-        // padding-right: 0.14rem;
         padding: 0 0.24rem 0 0.14rem;
         &::after {
           content: '';

+ 1 - 1
src/attendance/view/AttendanceNew/RecordDetail.vue

@@ -376,7 +376,7 @@ export default {
           if (this.animateType) {
             setTimeout(() => {
               this.showAnimate = true;
-            }, 500);
+            }, 1000);
           }
         });
     }

+ 1 - 0
src/attendance/view/AttendanceStatistic/SwitchDate.vue

@@ -205,6 +205,7 @@ export default {
     position: absolute;
     // width: 100%;
     // width: 0.98rem;
+    font-size: 0.32rem;
   }
   span {
     height: 0.96rem;

+ 4 - 3
src/attendance/view/AttendanceStatistic/index.vue

@@ -378,7 +378,7 @@ export default {
       font-size: 0.24rem;
       align-items: center;
       .item-name {
-        flex: 0 0 0.9rem;
+        flex: 0 0 1.4rem;
         overflow: hidden;
         white-space: nowrap;
         text-overflow: ellipsis;
@@ -411,15 +411,16 @@ export default {
       font-size: 0.24rem;
       height: 0.4rem;
       .item-date {
-        flex: 0 0 1.2rem;
+        flex: 0 0 1.4rem;
       }
       .item-attendance {
         flex: 1;
         text-align: right;
-        padding-right: 0.32rem;
+        padding-right: 0.2rem;
         box-sizing: border-box;
       }
       .item-time {
+        text-align: center;
         flex: 0 0 1.5rem;
       }
     }

+ 1 - 1
src/components/DeptSelectorDropdown.vue

@@ -11,7 +11,7 @@
     </div>
     <div class="select-dropdown__content" :style="contentStyle">
       <scroller class="selector-left _v-container">
-        <van-cell-group style="margin-top:0;">
+        <van-cell-group style="margin-top: 0;">
           <van-cell
             :class="{ on: item.id === selectedLeftDeptId }"
             v-for="(item, index) in deptData"

+ 3 - 1
src/components/EmployeeSelector.vue

@@ -83,7 +83,7 @@
       <div class="selected_btn" ref="selected_btn">
         <van-button ref="selected_button" style="height: 0.7rem; line-height: 0.7rem;" type="info" @click="confirm">
           确定
-          <template v-if="multi && max * 1 > 0&&can_select_employee">
+          <template v-if="multi && max * 1 > 0 && can_select_employee">
             ({{ employee_selected_list.length }}/{{ max }})
           </template>
         </van-button>
@@ -118,10 +118,12 @@ export default {
       type: Boolean,
       default: true
     },
+
     can_select_employee: {// 指定是否能选择员工
       type: Boolean,
       default: true
     },
+
     employee_not_select: {// 排除员工的ID,包含ID时不出现在选择列表中
       type: Array,
       default: () => {

+ 8 - 4
src/components/OssUploader.vue

@@ -1,13 +1,13 @@
 <template>
   <div style="position:relative;">
-    <div v-if="!isUploader&&w_plus" style="position: absolute;z-index: 2;left: 0;top: 0;bottom: 0;width: 1.8rem;" @click="openText"></div>
+    <div v-if="!isUploader && w_plus" style="position: absolute;z-index: 2;left: 0;top: 0;bottom: 0;width: 1.8rem;" @click="openText"></div>
     <template v-if="!isCamera">
       <van-uploader
         :disabled="disabled"
         :uploadText="uploadText"
         :beforeRead="beforeRead"
         :beforeDelete="image_del"
-         :after-read="_afterRead"
+        :after-read="_afterRead"
         :name="name"
         :accept="accept"
         v-model="oss_fileList"
@@ -151,6 +151,7 @@ export default {
         this.isUploader=true
       })
     },
+
     show_imgae (index, files) {
       ImagePreview({
         images: files,
@@ -164,6 +165,7 @@ export default {
       this.oss_fileList.splice(index, 1);
       this.$emit('fileupdate', this.filelist);
     },
+
     showPics(url, name) {
       //根据路径读取到文件
       let self = this;
@@ -178,6 +180,7 @@ export default {
         });
       });
     },
+
     //压缩图片
     compressImage(url, filename) {
       var name = '_doc/upload/' + filename;
@@ -198,6 +201,7 @@ export default {
         }
       );
     },
+
     captureImage() {
       var cmr = plus.camera.getCamera();
       var res = cmr.supportedImageResolutions[0];
@@ -226,6 +230,7 @@ export default {
       this.files.type = file.file.type; // 获取类型
       this.imgPreview(file.file);
     },
+
     // 处理图片
     imgPreview(file) {
       let self = this;
@@ -249,10 +254,8 @@ export default {
           // 判断图片是否小于2M,是就直接上传,反之压缩图片
           if (this.result.length <= 2000 * 1024) {
             // 上传图片
-            console.log("1")
             self.postImg(this.result);
           } else {
-            console.log("2")
             img.onload = function() {
               let data = self.compress(img, Orientation);
               // 上传图片
@@ -498,6 +501,7 @@ export default {
         this.$toast.clear();
       });
     },
+
     getSign(file) {
       this.$toast.loading({
         message: '上传中...',

+ 1 - 1
src/components/vue-img-cropper.vue

@@ -239,7 +239,7 @@ export default {
             let context = canvas.getContext('2d');
             // 判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
             let brand = self.judgeBrand(navigator.userAgent.toLowerCase());
-            if((brand=='xiaomi'||brand=='samsung')&&orientation){
+            if((brand == 'xiaomi' || brand == 'samsung') && orientation){
               switch (orientation) {
                 // iphone横屏拍摄,此时home键在左侧
                 // case 1:

+ 1 - 0
src/main.js

@@ -65,6 +65,7 @@ import {
 import 'element-ui/lib/theme-chalk/index.css';
 
 
+
 import {
   getWxToken,
   setWxToken,

+ 1525 - 0
src/newPerformance/components/performanceDetails.vue

@@ -0,0 +1,1525 @@
+<template>
+  <div class="all" :class="[{ bg_fff: skeletonLoad }]">
+    <van-nav-bar :title="pageTitle" left-arrow @click-left="routerBak">
+      <div
+        v-if="type === 'entering' && handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType !== 'review'"
+        slot="right"
+        @click="confirmCommentDialog(2)"
+        style="color: #fff;"
+      >提交</div>
+      <div
+        v-if="type === 'entering' && handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'review'"
+        slot="right"
+        @click="showReviewStatus = true"
+        style="color: #fff;"
+      >审批</div>
+    </van-nav-bar>
+
+    <div class="scroller">
+      <scroller ref="scroller_com" :on-refresh="refresh">
+        <div v-if="detailInfo">
+          <div class="title flex-box-ce" style="justify-content: space-between;">
+            <div>考核信息</div>
+            <div class="blue" @click="goDetails()">处理详情</div>
+          </div>
+
+          <div class="user-info-box">
+            <div class="flex-box-ce" style="margin-bottom: 0.2rem; justify-content: space-between;">
+              <div class="flex-box-ce">
+                <userImage :id="detailInfo.userInfo.id" :img_url="detailInfo.userInfo.img_url"  :user_name="detailInfo.userInfo.name"  fontSize="0.28"  width="0.6rem"  height="0.6rem" ></userImage>
+                <div style="color: #000; margin-left: 0.14rem; ">{{ detailInfo.userInfo.name }}</div>
+              </div>
+              <div class="info-item-value flex-box-ce" style="font-size: 0.28rem; color: #89919F;">
+                <van-icon name="clock-o" size="14" style="margin-right: 0.1rem;"/>
+                {{ detailInfo.startTime | formatDate }}至{{ detailInfo.endTime | formatDate }}
+              </div>
+            </div>
+            <div v-if="detailInfo.deptList && detailInfo.deptList.length > 0" class="user-info">
+              <template >
+                <span v-for="item in detailInfo.deptList" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
+              </template>
+            </div>
+
+            <div class="flex-box-ce" style="font-size: 0.28rem; margin-bottom: 0.2rem; justify-content: space-between;">
+              <div>
+                <van-icon name="calendar-o" style="margin-right: 0.1rem;"/>
+                考核周期: &nbsp;&nbsp;
+              </div>
+
+              <div class="cycle-type">
+                {{ detailInfo.cycleType | formatCycleType }}
+              </div>
+            </div>
+
+
+            <div class="info-item flex-box-ce" style="justify-content: space-between; margin-bottom: 0.2rem;">
+              <div class="info-item-title flex-box-ce">
+                <img src="static/images/review-status.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                审批阶段:
+              </div>
+              <div v-if="detailInfo.businessStatus !== 'end'" class="review-node">
+                {{ detailInfo.businessStatus | filterNodeStatus }}
+              </div>
+              <div v-else class="review-node" style="background-color: #FF9600;">
+                {{ detailInfo.businessStatus | filterNodeStatus }}
+              </div>
+            </div>
+          </div>
+
+          <div class="title" v-if="detailInfo.task && type === 'noEntering'">任务信息</div>
+
+          <div class="user-info-box" v-if="detailInfo.task && type === 'noEntering'">
+
+            <div class="info-item" style="margin-bottom: 0.2rem;">
+              <div class="info-item-label">
+                <span>任务节点:</span>
+              </div>
+              <div class="cycle-type" style="width: 1.6rem;">{{ dialogTitle }}</div>
+            </div>
+
+            <div class="info-item" style="margin-bottom: 0.2rem;">
+              <div class="info-item-label">
+                <span>处理人:</span>
+              </div>
+              <div class="info-item-value">{{ detailInfo.task.assigneeName }}</div>
+            </div>
+
+            <div class="info-item" v-if="detailInfo.task.nodeType === 'resultInput' && detailInfo.task.result !== null" style="margin-bottom: 0.2rem;">
+              <div class="info-item-label">
+                <span>录入结果:</span>
+              </div>
+              <div class="info-item-value">{{ detailInfo.task.result}}</div>
+            </div>
+
+            <div class="info-item" v-if="detailInfo.task.nodeType === 'scoreSelf' && detailInfo.task.score !== null" style="margin-bottom: 0.2rem;">
+              <div class="info-item-label">
+                <span>自评:</span>
+              </div>
+              <div class="info-item-value">{{ detailInfo.task.score }}</div>
+            </div>
+
+            <div class="info-item" v-if="detailInfo.task.nodeType === 'scoreEachOther' && detailInfo.task.score !== null" style="margin-bottom: 0.2rem;">
+              <div class="info-item-label">
+                <span>互评:</span>
+              </div>
+              <div class="info-item-value">{{ detailInfo.task.score }}</div>
+            </div>
+
+            <div class="info-item" v-if="detailInfo.task.nodeType === 'score' && detailInfo.task.score !== null" style="margin-bottom: 0.2rem;">
+              <div class="info-item-label">
+                <span>评分:</span>
+              </div>
+              <div class="info-item-value">{{ detailInfo.task.score }}</div>
+            </div>
+
+
+
+            <div class="info-item column" style="margin-bottom: 0.2rem;" v-if="detailInfo.task.files && detailInfo.task.files.length > 0">
+              <div class="info-item-label" style="margin-bottom: 0.2rem;">
+                <span>附件:</span>
+              </div>
+
+              <div class="flex-box-ce">
+                <div class="file-item" v-for="(item, index) in detailInfo.task.files" :key="index">
+                  <img :src="item" alt="" srcset="" style="width: 0.8rem; height: 0.8rem; margin-right: 0.1rem;" @click="openImg(detailInfo.task.files, index)"/>
+                </div>
+              </div>
+            </div>
+
+
+
+            <div v-if="detailInfo.task.comment" class="info-item column" style="margin-bottom: 0.2rem;">
+              <div class="info-item-label">
+                <span>意见:</span>
+              </div>
+              <div class="info-item-value comment-box">
+                {{ detailInfo.task.comment }}
+              </div>
+            </div>
+
+          </div>
+
+
+         <div class="title" >
+           指标信息
+         </div>
+
+
+         <div class="user-info-box">
+           <div class="box-title">确认目标</div>
+           <div class="info-item">
+            <div class="info-item-label">
+              <van-icon name="flag-o" style="margin-right: 0.1rem;"/>
+              <span>指标:</span>
+            </div>
+
+            <div class="info-item-value blue" v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm' && isEdit && type === 'entering'"  @click="handleEdit('title')">{{ detailInfo.title }}</div>
+            <div class="info-item-value" v-else>{{ detailInfo.title }}</div>
+          </div>
+
+           <div class="info-item">
+             <div class="info-item-label">
+              <van-icon name="aim" style="margin-right: 0.1rem;"/>
+              <span>目标值:</span>
+             </div>
+
+              <div class="info-item-value blue" v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm' && isEdit && type === 'entering'" @click="handleEdit('target')">{{ detailInfo.target || '-' }}</div>
+              <div class="info-item-value" v-else >{{ detailInfo.target || '-' }}</div>
+           </div>
+
+
+
+           <div class="info-item">
+             <div class="info-item-label">
+               <img src="static/images/weight.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+               <span>
+                权重(%):
+               </span>
+             </div>
+
+             <div class="info-item-value">{{ detailInfo.weight  || '-' }}</div>
+           </div>
+
+           <div class="info-item">
+             <div class="info-item-label">
+               <img src="static/images/unit.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                <span>单位:</span>
+             </div>
+
+              <div class="info-item-value blue" v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm' && isEdit && type === 'entering'"  @click="handleEdit('unit')">{{ detailInfo.unit || '-'}}</div>
+              <div class="info-item-value" v-else>{{ detailInfo.unit  || '-' }}</div>
+            </div>
+
+           <div class="info-item column">
+             <div class="info-item-label">
+               <img src="static/images/rules.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+               <span>指标规则:</span>
+             </div>
+
+             <div
+             v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm' && isEdit && type === 'entering'"
+              @click="handleEdit('content')"
+              style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: #26A2FF !important; background: #F5F5F5; border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+              >{{ detailInfo.content || '-' }}</div>
+
+              <div
+                v-else
+               style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: rgb(137, 145, 159); background: #F5F5F5;  border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+              >{{ detailInfo.content || '-' }}</div>
+
+           </div>
+
+           <div class="info-item column"  v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm'" >
+             <div class="info-item-label">
+               <img src="static/images/comment.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+               <span>意见:</span>
+             </div>
+
+             <div
+               v-if="type === 'entering'"
+               @click="handleEdit('comment')"
+              style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: #26A2FF !important; background: #F5F5F5; border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+              >{{ detailInfo.task.comment || '-' }}</div>
+
+              <div
+                v-else
+               style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: rgb(137, 145, 159); background: #F5F5F5;  border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+              >{{ detailInfo.task.comment || '-' }}</div>
+
+           </div>
+
+           <div class="line"></div>
+
+          <div class="box-title">录入结果</div>
+
+           <div class="info-item">
+             <div class="info-item-label">
+               <img src="static/images/result.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+               <span>结果值:</span>
+             </div>
+
+             <div class="info-item-value blue" v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'resultInput' && type === 'entering'" @click="handleEdit('result')">{{ detailInfo.result || '-' }}</div>
+             <div class="info-item-value" v-else>{{ detailInfo.result || '-' }}</div>
+           </div>
+
+           <div class="info-item column"  v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'resultInput'" >
+             <div class="info-item-label">
+               <img src="static/images/comment.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+               <span>意见:</span>
+             </div>
+
+
+             <div
+               v-if="type === 'entering'"
+               @click="handleEdit('comment')"
+              style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: #26A2FF !important; background: #F5F5F5; border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+              >{{ detailInfo.task.comment || '-' }}</div>
+
+              <div
+                v-else
+               style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: rgb(137, 145, 159); background: #F5F5F5;  border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+              >{{ detailInfo.task.comment || '-' }}</div>
+
+
+           </div>
+
+           <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'resultInput' && type === 'entering'">
+             <div class="info-item "  @click="handleEdit('files')">
+               <div class="info-item-label">
+                 <img src="static/images/append.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                 <span>附件:</span>
+               </div>
+               <div class="flex-1 blue text-right">编辑</div>
+             </div>
+             <template v-if="detailInfo.task.files && detailInfo.task.files.length > 0" >
+               <div class="flex-box-ce">
+                 <div class="file-item" v-for="(item, index) in detailInfo.task.files" :key="index">
+                   <img :src="item" alt="" srcset="" style="width: 0.8rem; height: 0.8rem; margin-right: 0.1rem;" @click="openImg(detailInfo.task.files, index)"/>
+                 </div>
+               </div>
+             </template>
+             <span v-else class="blue">{{ '-' }}</span>
+           </template>
+
+           <div class="line"></div>
+
+           <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreSelf'">
+             <div class="box-title">自评</div>
+             <div class="info-item" >
+               <div class="info-item-label">
+                 <img src="static/images/score.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                 <span>自评:</span>
+               </div>
+
+                <div class="info-item-value blue" v-if="type === 'entering'" @click="handleEdit('score')">{{ detailInfo.task.score || '-' }}</div>
+                <div class="info-item-value" v-else>{{ detailInfo.task.score }}</div>
+              </div>
+
+
+              <div class="info-item column"  v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreSelf'" >
+                <div class="info-item-label">
+                  <img src="static/images/comment.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                  <span>意见:</span>
+                </div>
+
+                <div
+                  v-if="type === 'entering'"
+                  @click="handleEdit('comment')"
+                 style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: #26A2FF !important; background: #F5F5F5; border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+                 >{{ detailInfo.task.comment || '-' }}</div>
+
+                 <div
+                   v-else
+                  style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: rgb(137, 145, 159); background: #F5F5F5;  border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+                 >{{ detailInfo.task.comment || '-' }}</div>
+
+              </div>
+
+              <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreSelf' && type === 'entering'">
+                <div class="info-item"  @click="handleEdit('files')">
+                  <div class="info-item-label">
+                    <img src="static/images/append.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                    <span>附件:</span>
+                  </div>
+                  <div class="flex-1 blue text-right">编辑</div>
+                </div>
+                <template v-if="detailInfo.task.files && detailInfo.task.files.length > 0" >
+                  <div class="flex-1 flex-box-ce">
+                    <div class="file-item" v-for="(item, index) in detailInfo.task.files" :key="index">
+                      <img :src="item" alt="" srcset="" style="width: 0.8rem; height: 0.8rem; margin-right: 0.1rem;" @click="openImg(detailInfo.task.files, index)"/>
+                    </div>
+                  </div>
+                </template>
+                <span v-else class="blue">{{ '-' }}</span>
+              </template>
+
+             <div class="line"></div>
+           </template>
+
+
+
+          <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreEachOther'">
+            <div class="box-title">互评</div>
+            <div class="info-item">
+              <div class="info-item-label">
+                <img src="static/images/score.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                <span>互评:</span>
+              </div>
+
+              <div class="info-item-value blue" v-if="type === 'entering'" @click="handleEdit('score')">{{ detailInfo.task.score || '-' }}</div>
+              <div class="info-item-value" v-else>{{ detailInfo.task.score }}</div>
+            </div>
+
+            <div class="info-item column"  v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreEachOther'" >
+              <div class="info-item-label">
+                <img src="static/images/comment.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                <span>意见:</span>
+              </div>
+
+              <div
+                v-if="type === 'entering'"
+                @click="handleEdit('comment')"
+               style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: #26A2FF !important; background: #F5F5F5; border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+               >{{ detailInfo.task.comment || '-' }}</div>
+
+               <div
+                 v-else
+                style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: rgb(137, 145, 159); background: #F5F5F5;  border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+               >{{ detailInfo.task.comment || '-' }}</div>
+
+            </div>
+
+
+            <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreEachOther' && type === 'entering'">
+              <div class="info-item"  @click="handleEdit('files')">
+                <div class="info-item-label">
+                  <img src="static/images/append.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                  <span>附件:</span>
+                </div>
+                <div class="flex-1 blue text-right">编辑</div>
+              </div>
+              <template v-if="detailInfo.task.files && detailInfo.task.files.length > 0" >
+                <div class="flex-box-ce">
+                  <div class="file-item" v-for="(item, index) in detailInfo.task.files" :key="index">
+                    <img :src="item" alt="" srcset="" style="width: 0.8rem; height: 0.8rem; margin-right: 0.2rem;" @click="openImg(detailInfo.task.files, index)"/>
+                  </div>
+                </div>
+              </template>
+              <span v-else class="blue">{{ '-' }}</span>
+            </template>
+
+            <div class="line"></div>
+          </template>
+
+
+          <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'score'">
+            <div class="box-title">评分</div>
+            <div class="info-item">
+              <div class="info-item-label">
+                <img src="static/images/score.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.2rem;"/>
+                <span>评分:</span>
+              </div>
+
+              <div class="info-item-value blue" v-if="type === 'entering'"  @click="handleEdit('score')">{{ detailInfo.task.score || '-' }}</div>
+              <div class="info-item-value" v-else>{{ detailInfo.task.score }}</div>
+            </div>
+
+            <div class="info-item column"  v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'score'" >
+              <div class="info-item-label">
+                <img src="static/images/comment.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                <span>意见:</span>
+              </div>
+
+              <div
+                v-if="type === 'entering'"
+                @click="handleEdit('comment')"
+               style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: #26A2FF !important; background: #F5F5F5; border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+               >{{ detailInfo.task.comment || '-' }}</div>
+
+               <div
+                 v-else
+                style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: rgb(137, 145, 159); background: #F5F5F5;  border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+               >{{ detailInfo.task.comment || '-' }}</div>
+
+            </div>
+
+            <template  v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'score' && type === 'entering'">
+              <div class="info-item"  @click="handleEdit('files')">
+                <div class="info-item-label">
+                  <img src="static/images/append.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                  <span>附件:</span>
+                </div>
+                <div class="flex-1 blue text-right">编辑</div>
+              </div>
+
+              <template v-if="detailInfo.task.files && detailInfo.task.files.length > 0" >
+                <div class="flex-box-ce">
+                  <div class="file-item" v-for="(item, index) in detailInfo.task.files" :key="index">
+                    <img :src="item" alt="" srcset="" style="width: 0.8rem; height: 0.8rem; margin-right: 0.2rem;" @click="openImg(detailInfo.task.files, index)"/>
+                  </div>
+                </div>
+              </template>
+              <span v-else class="blue">{{ '-' }}</span>
+            </template>
+
+            <div class="line"></div>
+          </template>
+
+
+          <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'review'">
+            <div class="box-title">审批</div>
+            <div class="info-item">
+              <div class="info-item-label">
+                <img src="static/images/score.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.2rem;"/>
+                <span>最终评分:</span>
+                <span>{{ detailInfo.score || '-' }}</span>
+              </div>
+
+            </div>
+
+
+            <div class="info-item column"  v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'review'" >
+              <div class="info-item-label">
+                <img src="static/images/comment.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                <span>意见:</span>
+              </div>
+
+
+
+              <div
+                v-if="type === 'entering'"
+                @click="handleEdit('comment')"
+               style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: #26A2FF !important; background: #F5F5F5; border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+               >{{ detailInfo.task.comment || '-' }}</div>
+
+               <div
+                 v-else
+                style="width: 100%; white-space: pre-wrap; border: none; font-size: 0.28rem; margin-top: 0.1rem; color: rgb(137, 145, 159); background: #F5F5F5;  border-radius: 6px; padding: 0.1rem; box-sizing: border-box;"
+               >{{ detailInfo.task.comment || '-' }}</div>
+
+            </div>
+
+            <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'review' && type === 'entering'">
+              <div class="info-item"  @click="handleEdit('files')">
+                <div class="info-item-label">
+                  <img src="static/images/append.png" alt="" srcset="" style="width: 14px; height: 14px; margin-right: 0.1rem;"/>
+                  <span>附件:</span>
+                </div>
+                <div class="flex-1 blue text-right">编辑</div>
+              </div>
+
+              <template v-if="detailInfo.task.files && detailInfo.task.files.length > 0" >
+                <div class="flex-box-ce">
+                  <div class="file-item" v-for="(item, index) in detailInfo.task.files" :key="index">
+                    <img :src="item" alt="" srcset="" style="width: 0.8rem; height: 0.8rem; margin-right: 0.2rem;" @click="openImg(detailInfo.task.files, index)"/>
+                  </div>
+                </div>
+              </template>
+              <span v-else class="blue">{{ '-' }}</span>
+            </template>
+          </template>
+
+         </div>
+
+        </div>
+
+        <!-- 操作日志 -->
+        <OperateLogVue v-if="reviewId" :reviewId="reviewId" :reviewIndicatorId="reviewIndicatorId"/>
+
+        <div style="width: 100%; height: 1rem;">
+
+        </div>
+
+      </scroller>
+    </div>
+
+    <!-- 编辑指标弹框 -->
+
+    <van-dialog :title="editInfoTitle" v-model="isShowHandle"  width="300" confirm-button-text="暂存" @confirm="onFieldBlur($event, formData[handleEditProp], handleEditProp)" @cancel="handleCancel" @close="handleClose" :show-confirm-button="isShowConfirm" closeOnClickOverlay>
+
+      <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType !== 'targetConfirm' && handleEditProp === 'files'">
+
+        <div style="padding: 0.2rem; box-sizing: border-box;">
+          <div class="fontColorC" style="margin: 0.2rem 0;">上传附件</div>
+          <Uploader
+            v-model="img_fileList"
+            :max-count="5"
+            :beforeRead="beforeRead"
+            :accept="accept"
+            @fileupdate="fileUpdate"
+          />
+
+        </div>
+
+      </template>
+
+
+
+      <van-field
+        v-if="handleEditProp === 'comment'"
+        v-model="comment"
+        rows="2"
+        border
+        autosize
+        maxlength="100"
+        show-word-limit
+        clearable
+        type="textarea"
+        placeholder="请输入意见"
+        @focus="onFocus"
+        >
+      </van-field>
+
+      <!-- 确认目标 -->
+      <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm'" >
+        <van-field
+          v-if="handleEditProp === 'title'"
+          v-model="formData.title"
+          border
+          clearable
+          autosize
+          maxlength="20"
+          show-word-limit
+          placeholder="指标"
+          :disabled="!isEdit"
+          input-align="center"
+          @focus="onFocus"
+        >
+        </van-field>
+
+
+        <van-field
+          v-if="handleEditProp === 'target'"
+          v-model="formData.target"
+          border
+          clearable
+          type="number"
+          placeholder="目标值"
+          :disabled="!isEdit"
+          input-align="center"
+          @focus="onFocus"
+        >
+        </van-field>
+
+        <van-field
+          v-if="handleEditProp === 'weight'"
+          v-model="formData.weight"
+          border
+          type="number"
+          input-align="center"
+          clearable
+          placeholder="权重(请输入数字)"
+          :disabled="!isEdit"
+          @focus="onFocus"
+        >
+        </van-field>
+
+        <van-field
+          v-if="handleEditProp === 'unit'"
+          v-model="formData.unit"
+          border
+          clearable
+          placeholder="单位"
+          :disabled="!isEdit"
+          input-align="center"
+          @focus="onFocus"
+        >
+        </van-field>
+
+        <van-field
+          v-if="handleEditProp === 'content'"
+          v-model="formData.content"
+          rows="2"
+          border
+          autosize
+          maxlength="100"
+          show-word-limit
+          clearable
+          type="textarea"
+          placeholder="规则"
+          :disabled="!isEdit"
+          @focus="onFocus"
+        >
+        </van-field>
+
+
+      </template>
+
+
+      <!-- 录入结果 -->
+      <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'resultInput'">
+
+        <van-field
+          v-if="handleEditProp === 'result'"
+          v-model="formData.result"
+          type="number"
+          input-align="center"
+          border
+          clearable
+          placeholder="结果值"
+          @focus="onFocus"
+        >
+        </van-field>
+
+      </template>
+
+
+      <!-- 自评 -->
+      <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreSelf'">
+        <van-field
+          v-if="handleEditProp === 'score'"
+          v-model="formData.score"
+          border
+          type="number"
+          clearable
+          input-align="center"
+          placeholder="评分(请输入数字)"
+          @focus="onFocus"
+        >
+        </van-field>
+      </template>
+
+      <!-- 互评 -->
+      <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreEachOther'">
+        <van-field
+          v-if="handleEditProp === 'score'"
+          v-model="formData.score"
+          border
+          type="number"
+          clearable
+          input-align="center"
+          placeholder="评分(请输入数字)"
+          @focus="onFocus"
+        >
+        </van-field>
+      </template>
+
+
+      <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'score'">
+        <div
+          v-if="handleEditProp === 'score' && formData.scoreExpression"
+          @click="inputScore()"
+          class="van-cell blue"
+        >
+          {{ '系统评分: ' + formData.scoreExpression }}
+        </div>
+
+        <van-field
+          v-if="handleEditProp === 'score'"
+          v-model="formData.score"
+          border
+          clearable
+          input-align="center"
+          type="number"
+          placeholder="评分(请输入数字)"
+          @focus="onFocus"
+          clearable
+        >
+        </van-field>
+      </template>
+
+
+      <template v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'review'">
+        <van-field
+          v-if="handleEditProp === 'score'"
+          label="最终评分"
+          v-model="formData.score"
+          border type="number"
+          disabled
+        />
+      </template>
+
+
+    </van-dialog>
+
+
+
+    <!-- 审批,通过、驳回 -->
+    <van-action-sheet v-model="showReviewStatus" :actions="reviewStatusList" @select="onReviewConfirm" cancel-text="取消" close-on-click-action/>
+
+  </div>
+</template>
+<script>
+import Vue from 'vue';
+import moment from 'moment';
+import Uploader from '@/components/OssUploader';
+import { Checkbox, CheckboxGroup, ActionSheet, ImagePreview } from 'vant';
+Vue.use(Checkbox).use(CheckboxGroup).use(ActionSheet).use(ImagePreview);
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import resultValueEntryMb from '@/performance/components/actionplan/resultValueEntryMb';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import {getExpressionStr} from '@/performance/utils/auth'
+import OperateLogVue from '@/newPerformance/components/public/OperateLog.vue'
+
+export default {
+  data() {
+    return {
+      type: "entering",
+      skeletonLoad: false, // 过度骨架屏
+      isDetails:true,
+      reviewIndicatorId: '',
+      reviewId: '',
+      taskId: '',
+      isFocus: false,
+      day: moment().format('YYYY-MM-DD'),
+      isNeed: !this.$getCache('isAndroid'),
+      detailInfo: null,
+      handleDetailInfo: null, // 弹窗中用来操作的数据
+      isShowHandle: false,
+      isInit: false,
+      result: '',
+      pageTitle: '',
+      dialogTitle: '',
+      editInfoTitle: '',
+      comment: '',
+      img_fileList: [],
+      emtags: [],
+      accept:'image/jpeg,image/png,image/jpg,image/bmp',
+      handleEditProp: '',
+      isShowConfirm: true,
+      reject: false, // 驳回标识
+      showReviewStatus: false,
+      reviewStatus: 0,
+
+      reviewStatusList: [
+        {value: 1, name:'通过', disabled: false },
+        {value: 0, name:'驳回', color: '#f56c6c', disabled: false},
+      ],
+      formData: {
+        title: '',
+        weight: '',
+        unit: '',
+        target: '',
+        content: '',
+        result: '',
+        comment: '',
+        files: [],
+        scoreExpression: '', // 系统评分
+        score: ''
+      }
+    };
+  },
+
+  components: {
+    EmployeeSelector,
+    VanSkeleton,
+    OperateLogVue,
+    Uploader,
+  },
+
+  watch: {
+    handleEditProp(val) {
+      if(val === 'files') this.isShowConfirm = false
+      else this.isShowConfirm = true
+    },
+
+  },
+
+  computed: {
+
+    // 确认目标节点是否可以编辑
+    isEdit() {
+      let children = [], employeeIds = [];
+      let user_id = this.$userInfo().id.toString() // 当前用户ID
+      const { nodes = [] } = this.detailInfo && this.detailInfo.flow || {};
+      if (nodes && nodes.length > 0)
+        children = nodes.find(node => node.type === 'targetConfirms').children
+        children.forEach(child => {
+          // 是否允许编辑
+          if (child.allows.includes('edit')) {
+            if (['leader', 'deptLeader', 'post', 'user'].includes(child.assigneeType)) {
+              if (child.tasks && child.tasks.length > 0) {
+                child.tasks.forEach(task => {
+                    employeeIds.push(task.assignee)
+                })
+              }
+            }
+            else {
+              employeeIds = [user_id]
+            }
+          }
+        })
+      return employeeIds && employeeIds.length > 0 && employeeIds.includes(user_id) ? true : false
+    },
+
+    selfScoreNode() {
+      if(this.handleDetailInfo && this.handleDetailInfo.flow && this.handleDetailInfo.flow.nodes && this.handleDetailInfo.flow.nodes[2] && this.handleDetailInfo.flow.nodes[2].enable) {
+        return ({
+          enable: true,
+          tasks: this.handleDetailInfo.flow.nodes[2].tasks
+        })
+      }else {
+        return ({
+          enable: false,
+          tasks: null
+        })
+      }
+    },
+
+
+    scoreEachOtherNode() {
+      if(this.handleDetailInfo && this.handleDetailInfo.flow && this.handleDetailInfo.flow.nodes && this.handleDetailInfo.flow.nodes[3] && this.handleDetailInfo.flow.nodes[3].enable) {
+        return ({
+          enable: true,
+          tasks: this.handleDetailInfo.flow.nodes[3].tasks
+        })
+      }else {
+        return ({
+          enable: false,
+          tasks: null
+        })
+      }
+    },
+  },
+
+  filters: {
+
+    filterNodeStatus(v) {
+      if (v === 'start') return '开始'
+      if (v === 'target_confirm') return '确认目标'
+      if (v === 'result_input') return '录入结果值'
+      if (v === 'score_self') return '自评'
+      if (v === 'score_each_other') return '互评'
+      if (v === 'score') return '评分'
+      if (v === 'review') return '审批'
+      if (v === 'cc') return '抄送'
+      if (v === 'end') 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 '--'
+    },
+
+    filterNodeStatus(v) {
+      if (v === 'start') return '开始'
+      if (v === 'target_confirm') return '确认目标'
+      if (v === 'result_input') return '录入结果值'
+      if (v === 'score_self') return '自评'
+      if (v === 'score_each_other') return '互评'
+      if (v === 'score') return '评分'
+      if (v === 'review') return '审批'
+      if (v === 'cc') return '抄送'
+      if (v === 'end') return '结束'
+    },
+
+    formatDate(val) {
+      if (val) return moment(val).format('YYYY-MM-DD')
+      else return "--"
+    },
+  },
+
+  activated() {
+    this.reviewIndicatorId = this.$route.query.reviewIndicatorId
+    this.taskId = this.$route.query.taskId
+    this.reviewId = this.$route.query.reviewId
+    this.type = this.$route.query.type
+    this.getTaskDetails(true);
+  },
+
+  beforeDestroy() {
+    this.detailInfo = null
+    this.handleDetailInfo = null
+  },
+
+
+  methods: {
+    // 下拉刷新
+    refresh(done) {
+      this.getTaskDetails()
+      done();
+    },
+
+
+    handleCancel() {
+      this.isShowHandle = false
+      console.log(this.handleEditProp)
+      if(this.handleEditProp === 'files') {
+        this.getTaskDetails()
+      }
+    },
+
+    handleClose(){
+      this.isShowHandle = false
+      console.log(this.handleEditProp)
+      if(this.handleEditProp === 'files') {
+        this.getTaskDetails()
+      }
+    },
+
+
+    // 系统评分 - 立即评分
+    inputScore() {
+      this.formData.score = this.formData.scoreExpression
+    },
+
+    goDetails() {
+      let { reviewId, reviewIndicatorId, flow: { nodes } } = this.detailInfo
+      let showData = {
+        nodes,
+        reviewId,
+        reviewIndicatorId,
+      }
+      this.$router.push({ path: "/handleDetails", query: {showData: JSON.stringify(showData)} })
+    },
+
+
+
+
+    // 获取待办任务详情
+    getTaskDetails() {
+      let url;
+      this.pageTitle = this.type === 'entering' ? '待处理' : '已处理';
+      if(this.type === 'entering') url = `/performance/review/job/${this.$userInfo().site_id}/${this.reviewIndicatorId}/${this.taskId}`;
+      else url = `/performance/review/job/history/${this.$userInfo().site_id}/${this.reviewIndicatorId}/${this.taskId}`;
+      this.$axiosUser('get', url).then(res => {
+        if(res.data.code == 1) {
+          this.detailInfo = res.data.data;
+          this.handleDetailInfo = res.data.data;
+          this.formData.title = this.detailInfo.title;
+          this.formData.target = this.detailInfo.target;
+          this.formData.unit = this.detailInfo.unit;
+          this.formData.result = this.detailInfo.result;
+          this.formData.weight = this.detailInfo.weight;
+          this.formData.content = this.detailInfo.content;
+          this.formData.comment = this.detailInfo.task.comment;
+          this.formData.scoreExpression = this.detailInfo.scoreExpression;
+          this.formData.score = this.detailInfo.task.score;
+          this.comment = this.detailInfo.task.comment;
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'targetConfirm') this.dialogTitle = '确认目标'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'resultInput') this.dialogTitle = '结果录入'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'scoreSelf') this.dialogTitle = '自评'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'scoreEachOther') this.dialogTitle = '互评'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'score') this.dialogTitle = '评分'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'review') this.dialogTitle = '审批'
+          this.detailInfo.userInfo = this.$getEmployeeMapItem(this.detailInfo.employeeId)
+          this.detailInfo.deptList = this.$getEmployeeMapItem(this.detailInfo.employeeId).employee_detail.dept_list
+        }
+      })
+    },
+
+    goMyTarget() {
+      this.$router.push({name: 'myTarget', query: { ids: JSON.stringify(this.okrs) }});
+    },
+
+    handleEdit(props) {
+      this.handleEditProp = props
+      // 每次打开编辑弹框,重置编辑的数据
+      this.formData.title = this.detailInfo.title;
+      this.formData.target = this.detailInfo.target;
+      this.formData.unit = this.detailInfo.unit;
+      this.formData.result = this.detailInfo.result;
+      this.formData.weight = this.detailInfo.weight;
+      this.formData.content = this.detailInfo.content;
+      this.formData.comment = this.detailInfo.task.comment;
+      this.formData.scoreExpression = this.detailInfo.scoreExpression;
+      this.formData.score = this.detailInfo.task.score;
+      this.comment = this.detailInfo.task.comment;
+      if(props === 'title') this.editInfoTitle = '指标标题'
+      if(props === 'target') this.editInfoTitle = '目标值'
+      if(props === 'unit') this.editInfoTitle = '单位'
+      if(props === 'content') this.editInfoTitle = '指标规则'
+      if(props === 'result') this.editInfoTitle = '结果值'
+      if(props === 'score') {
+        if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'scoreSelf') {
+          this.editInfoTitle = '自评评分'
+        }
+
+        if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'scoreEachOther') {
+          this.editInfoTitle = '互评评分'
+        }
+
+        if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'score') {
+          this.editInfoTitle = '评分'
+        }
+
+      }
+      if(props === 'comment') this.editInfoTitle = '意见'
+      if(props === 'files') {
+        this.editInfoTitle = '附件'
+        if(this.detailInfo.task && this.detailInfo.task.files) {
+          this.formData.files = this.detailInfo.task.files;
+          this.img_fileList = this.formData.files;
+        }
+      }
+      this.isShowHandle = true
+    },
+
+
+
+    // 返回布尔值
+    beforeRead(file) {
+      const allowType = ['image/jpeg', 'image/png', 'image/jpg']
+      const maxSize = 5 * 1024 * 1024 // 5MB
+      if (!allowType.includes(file.type)) {
+        this.$toast('请上传 jpg/png 格式图片')
+        return false
+      }
+      if (file.size > maxSize) {
+        this.$toast('图片大小不能超过 5MB')
+        return false
+      }
+      return true
+    },
+
+    // 文件读取完成后自动上传
+    fileUpdate(file) {
+      console.log(file)
+      this.comfirmUploadFiles();
+    },
+
+
+    // 文本框失去焦点事件 - 暂存
+    onFieldBlur(e, val, type) {
+      if(type === 'comment') {
+        this.confirmCommentDialog(1) // 处理每个节点意见的暂存
+        return
+      }
+      let reviewIndicatorId = this.reviewIndicatorId;
+      let { nodeType } = this.detailInfo.task;
+      // 请求参数
+      let data = {
+        taskId: this.taskId,
+       }
+      // 自评,互评,评分获取评分
+      if (type === 'scoreSelf' || type === 'scoreEachOther' || type === 'score') {
+          data['score'] = val;
+      }else {
+        data[type] = val;
+      }
+
+      let url;
+      switch (nodeType) {
+        // 确认目标
+        case 'targetConfirm':
+          url = `/performance/review/target/confirm/${type}/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 录入结果值
+        case 'resultInput':
+          url = `/performance/review/result/Input/${type}/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 自评
+        case 'scoreSelf':
+          url = `/performance/review/score/self/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 互评
+        case 'scoreEachOther':
+          url = `/performance/review/score/each/other/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 评分
+        case 'score':
+          url = `/performance/review/score/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        default:
+          break;
+      }
+
+      this.$axiosUser('post', url, data, 'contentTypeJson').then(res => {
+        if(res.data.code === 1) {
+          this.$toast.success("暂存成功");
+          this.getTaskDetails();
+        }else {
+          this.$toast.fail(res.data.message)
+        }
+        this.isFocus = false
+      })
+
+    },
+
+    onFocus() {
+      this.isFocus = true
+    },
+
+
+    async confirmCommentDialog(type) {
+
+        let reviewIndicatorId = this.reviewIndicatorId;
+        let taskId = this.taskId;
+        let { nodeType } = this.handleDetailInfo.task;
+        let url;
+        switch (nodeType) {
+          case 'targetConfirm':
+            url = `/performance/review/target/confirm/complete/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          case 'resultInput':
+            url = `/performance/review/result/Input/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          // 自评
+          case 'scoreSelf':
+            url = `/performance/review/score/self/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          // 互评
+          case 'scoreEachOther':
+            url = `/performance/review/score/each/other/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          // 评分
+          case 'score':
+            url = `/performance/review/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          case 'review':
+            // 驳回
+            if (this.reject) url = `/performance/review/review/refuse/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            // 通过
+            else url = `/performance/review/review/pass/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          default:
+            break;
+        }
+
+        let data = {
+          taskId,
+          comment: this.comment,
+          complete: type == 1 ? false : true // false 暂存,true 提交
+        }
+
+        // 提交时,验证评分字段
+        if(type == 2) {
+          if(['score'].includes(nodeType)) {
+            if (this.handleDetailInfo.task.score == null || this.handleDetailInfo.task.score == '' || this.handleDetailInfo.task.score == undefined) {
+              return this.$toast.fail('请先录入评分再提交')
+            }
+          }
+          let message = '提交任务将会进入下一个流程节点,确认要提交吗?'
+          if(['review'].includes(nodeType)) {
+            if(!this.reject) message = '审批通过将会进入下一个流程节点(抄送节点),确定要继续操作吗?'
+            else message = '审批驳回将会进入上一个流程节点(评分节点),确定要继续操作吗?'
+          }
+          this.$dialog.confirm({ title:'提示', message }).then(() => {
+            this.$axiosUser('post', url, data, 'contentTypeJson').then(res => {
+              // 提交
+              if (res.data.code == 1) {
+                this.$toast.success('操作成功');
+                this.type = "noEntering"
+                this.getTaskDetails();
+                this.isShowHandle = false;
+                this.comment = "";
+                this.reject = false; // 驳回标识
+                setTimeout(() => {
+                  this.$router.go(-1)
+                }, 1000)
+
+              } else {
+                this.$toast.fail(res.data.message || '操作失败');
+              }
+            })
+          });
+        }else {
+          this.$axiosUser('post', url, data, 'contentTypeJson').then(res => {
+            // 暂存
+            if (res.data.code == 1) {
+              this.type = "entering"
+              this.$toast.success("暂存成功")
+              this.getTaskDetails();
+            }
+            else this.$toast.fail(res.message || '操作失败');
+          })
+        }
+    },
+
+    // 各个任务节点 文件上传
+    async comfirmUploadFiles() {
+      let reviewIndicatorId = this.reviewIndicatorId;
+      let taskId = this.taskId;
+      let { nodeType } = this.handleDetailInfo.task;
+      let url;
+
+      switch (nodeType) {
+        // 结果值附件录入
+        case 'resultInput':
+          url = `/performance/review/result/Input/result/file/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 自评附件录入
+        case 'scoreSelf':
+          url = `/performance/review/score/self/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 互评附件录入
+        case 'scoreEachOther':
+          url = `/performance/review/score/each/other/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 评分附件录入
+        case 'score':
+          url = `/performance/review/score/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 审批附件录入
+        case 'review':
+          url = `/performance/review/review/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        default:
+          break;
+      }
+
+        let data = {
+          taskId,
+          files: this.img_fileList
+        }
+        let res = await this.$axiosUser('post', url, data, 'contentTypeJson')
+        if(res.data.code !== 1) {
+          return this.$toast.fail('上传附件失败,请稍后重试')
+        }else {
+          // this.$toast.success('上传附件成功')
+          // this.getTaskDetails();
+        }
+    },
+
+
+    downWgt (url,name) {
+      let self = this
+      if(!window.plus){
+          window.open(url, '_blank');
+          return false
+      }
+      let dtask = plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
+        function (d, status) {
+          if (status == 200) {
+            plus.runtime.openFile(d.filename,{},(err)=>{
+              // console.log(JSON.stringify(err))
+            });
+          } else {
+            self.$toast.clear()
+            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
+          }
+        }
+      )
+      dtask.start();
+    },
+
+
+    openImg(imgs, index) {
+      let imgArr = imgs.map(item => {
+        return item.url || item;
+      });
+      ImagePreview({
+        images: imgArr,
+        startPosition: index
+      });
+    },
+
+
+    // 审批
+    onReviewConfirm(data) {
+      // 审批通过
+      if(data.name === '通过') {
+      // 审批驳回
+      }else {
+        this.reject = true
+      }
+      this.showReviewStatus = false;
+      this.confirmCommentDialog(2);
+    },
+
+
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+
+
+
+  },
+
+};
+</script>
+
+<style scoped lang="less">
+
+
+
+.all {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  .scroller {
+    position: relative;
+    flex: 1;
+  }
+
+  /deep/ .van-dropdown-menu__title{
+    position: relative;
+    box-sizing: border-box;
+    max-width: 100%;
+    padding: 0 0.16rem;
+    color: #f8f8f8;
+    font-size: 0.3rem;
+    line-height: 0.44rem;
+  }
+
+  /deep/ .van-dropdown-menu__bar{
+    height: 0.8rem;
+    background-color: #26A2FF;
+  }
+  /deep/ .van-dropdown-menu{
+    border-bottom: 0;
+  }
+
+
+  /deep/ .van-dialog__header {
+    padding-top: 0 !important;
+    font-weight: 500 !important;
+    line-height: 1rem !important;
+    text-align: center !important;
+  }
+
+  /deep/ .van-button__text {
+    color: #26A2FF;
+    font-size: 0.3rem;
+  }
+}
+
+
+.isIos {
+  padding-bottom: 0.4rem !important;
+}
+
+/deep/ .overall {
+  height: calc(100% - 1.92rem) !important;
+  position: relative;
+  overflow-y: scroll;
+}
+
+.title {
+  height: 0.8rem;
+  line-height: 0.8rem;
+  font-size: 0.28rem !important;
+  color: #8a8a8a;
+  padding: 0 0.1rem;
+  box-sizing: border-box;
+}
+
+.user-info-box {
+  width: 96%;
+  margin: 0 auto 0.2rem auto;
+  background-color: #fff;
+  padding: 0.2rem;
+  box-sizing: border-box;
+  border-radius: 6px;
+
+  .box-title {
+    width: 1.5rem;
+    background: #fbf3e0;
+    font-size: .28rem;
+    border-radius: 0 .5rem .5rem 0;
+    padding: .04rem 0 .04rem .24rem;
+    margin: 0 0 0.2rem -0.23rem;
+    color: #606266;
+    box-sizing: border-box;
+  }
+
+  .line {
+    width: 100%;
+    height: 0.02rem;
+    border-bottom: .02rem dashed #ccc;
+    margin-bottom: 0.4rem;
+  }
+
+  // margin-bottom: 0.2rem;
+  .user-info {
+    font-size: 0.28rem;
+    color: #89919F !important;
+    margin: 0 0 0.2rem 0;
+    width: 100%;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+  }
+
+  .cycle-type {
+    width: 1.2rem;
+    padding: 0.05rem 0;
+    text-align: center;
+    border-radius: 0.1rem;
+    font-size: 0.28rem;
+    color: #26a2ff;
+    box-sizing: border-box;
+    background-color: #ecf5ff;
+  }
+
+
+
+
+
+  .info-item {
+    margin-bottom: 0.4rem;
+    font-size: 0.28rem;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .review-node {
+      padding: 0.01rem 0.1rem;
+      color: #fff;
+      border-radius: 2px;
+      font-size: 0.26rem;
+      background-color: #67c23a;
+      margin-left: 0.14rem;
+    }
+    .info-item-label {
+      display: flex;
+      align-items: center;
+    }
+    .info-item-value {
+      flex: 1;
+      text-align: right;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+    .text-hidden {
+      max-width: 3rem;
+    }
+
+
+  }
+}
+
+.column {
+  flex-direction: column;
+  align-items: flex-start !important;
+}
+
+.comment-box {
+  width: 100%;
+  padding: 0.1rem;
+  box-sizing: border-box;
+  background-color: #f5f5f5;
+  border-radius: 6px;
+  text-align: left !important;
+  margin-top: 0.1rem;
+}
+
+
+.popup-box {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  background-color: none;
+  .content {
+    width: 100%;
+    overflow: auto;
+  }
+
+  .popup-footer {
+
+    padding: 0.2rem;
+    // border-top: 0.02rem solid #f1f1f1;
+    // background: #fff;
+    position: fixed;
+
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    // box-shadow: 0px -3px 0.15rem #f7f8fa;
+    box-sizing: border-box;
+    .btn:nth-child(1) {
+      margin-bottom: 0.2rem;
+    }
+    .btn {
+      width: 100%;
+      border-radius: 0.5rem;
+      padding: 0.2rem 0.14rem;
+      // border: 0.02rem solid #26A2FF;
+      text-align: center;
+      font-size: 0.3rem;
+      box-sizing: border-box;
+    }
+    .primary {
+      background: #26A2FF;
+      color: #fff;
+    }
+    .plain {
+      background-color: #fff;
+      color: #26A2FF;
+      border: 0.02rem solid #26A2FF;
+    }
+  }
+
+}
+
+
+
+</style>

+ 499 - 0
src/newPerformance/components/public/More.vue

@@ -0,0 +1,499 @@
+<template>
+    <div style="width: 100%; height: 100%;" :class="{ bg_fff: skeletonLoad }">
+      <!-- <van-nav-bar title="更多考核数据" left-text="返回" left-arrow @click-left="$route_back" /> -->
+
+      <van-search placeholder="请输入考核表名称" v-model="params.keyword" @input="keyVal()" />
+
+
+      <!-- 条件筛选 -->
+      <div class="flex-box-ce search-box" style="">
+        <!-- 周期筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center" style="border-right: 1px solid #f1f1f1;">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="openPanel()">
+            <div class="cycle-name">{{ dateParameter.name }}</div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 周期筛选 -->
+        <!-- 时间筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center" style="border-right: 1px solid #f1f1f1;">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="calendarOpen()">
+            <div class="cycle-name" v-html="timeStr"></div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 时间筛选 -->
+
+        <!-- 状态筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="showStatus = true">
+            <div class="cycle-name">{{ statusName }}</div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 状态筛选 -->
+      </div>
+      <!-- 条件筛选 -->
+
+
+      <!-- 骨架屏 -->
+      <VanSkeleton :skeLoad="skeletonLoad">
+        <scroller class="scroller-box" ref="scroller" :isInitRefresh="false" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢" :list="examineList">
+          <div class="examine-list" v-if="filterExamineList && filterExamineList.length > 0">
+            <div class="examine-item" v-for="(item, index) in filterExamineList" :key="item.reviewId" @click="handleChooseItem(item)">
+              <div v-if="item.status == 1" class="examine-item-status" style="background-color: #FF9600;">
+                已结束
+              </div>
+              <div v-if="item.status == 0" class="examine-item-status" >
+                进行中
+              </div>
+              <div class="flex-1 flex-box-ce flex-d-center">
+                <div class="examine-item-title font-flex-word">
+                  {{ item.title }}
+                </div>
+                <div class="examine-item-info">
+                  {{ item.score == null ? '-' : item.score }} / <span style="color: #ff9600;">{{ item.levelName || '-' }}</span>
+                </div>
+              </div>
+
+            </div>
+          </div>
+
+          <noData v-else content="无考核记录"></noData>
+        </scroller>
+      </VanSkeleton>
+      <!-- 骨架屏 -->
+
+      <!-- 周期选择弹框 -->
+      <van-action-sheet v-model="pullonThePanel" :closeable="false">
+        <div class="content">
+          <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel = false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+        </div>
+      </van-action-sheet>
+
+      <!-- 日期选择框 -->
+      <van-calendar
+        v-model="showCalendar"
+        type="range"
+        :allow-same-day="true"
+        :min-date="minDate"
+        :max-date="maxDate"
+        :default-date="timeScope"
+        :show-confirm="false"
+        color="#26A2FF"
+        @close="calendarClose"
+        @confirm="calendarConfirm"
+      >
+        <template v-slot:title>
+          <van-row>
+            <van-col span="20">
+              <van-row type="flex" justify="space-between" style="height: 1rem;">
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="success" size="medium" @click="timeScopeThisWeek">本周</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="success" size="medium" @click="timeScopeLastWeek">上周</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="primary" size="medium" @click="timeScopeThisMoth">本月</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="primary" size="medium" @click="timeScopeLastMonth">上月</van-tag>
+                </van-col>
+              </van-row>
+            </van-col>
+          </van-row>
+        </template>
+      </van-calendar>
+
+      <!-- 状态 -->
+      <van-dialog v-model="showStatus" title="" width="300" confirm-button-text="确定" @confirm="handleConfirm" @cancel="handleCancel"  :show-confirm-button="true" closeOnClickOverlay>
+        <van-radio-group v-model="statusId">
+          <div v-for="(item, index) in statusList" :key="index">
+            <van-radio :name="item.value" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+              <span style="margin-left:.3rem">{{ item.text }}</span>
+            </van-radio>
+          </div>
+        </van-radio-group>
+      </van-dialog>
+
+    </div>
+
+</template>
+
+<script>
+  import Vue from 'vue';
+  import { _debounce, _throttle } from '@/utils/auth';
+  import VanSkeleton from '@/performance/components/public/VanSkeleton';
+  import { DropdownMenu, DropdownItem, Calendar, Switch} from 'vant';
+  import moment from "moment/moment";
+  Vue.use(DropdownMenu)
+    .use(DropdownItem)
+    .use(Switch)
+    .use(Calendar);
+  export default {
+    components: { VanSkeleton },
+
+    props: {
+      employeeId: {
+        type: String | Number,
+        default: ''
+      }
+    },
+    data() {
+
+      let startDate = new Date();
+      startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * 7);
+      startDate = moment(startDate).format('YYYY-MM-DD');
+      let endDate = moment().format('YYYY-MM-DD');
+
+      let today = new Date();
+      let minDate = new Date();
+      minDate.setTime(today.getTime() - 3600 * 1000 * 24 * 30 * 6);
+      let maxDate = new Date(today.getFullYear(),today.getMonth(),1);
+      maxDate.setMonth(maxDate.getMonth() + 1);
+      maxDate.setDate(0);
+
+      return {
+        skeletonLoad: true,
+        keyword: '',
+        examineList: [],
+        filterExamineList: [],
+        pullonThePanel: false,
+
+        columns: [
+          {
+            value: "-1",
+            name: "全部",
+            text: "全部"
+          },
+          {
+            value: "0",
+            name: "自定义",
+            text: "自定义"
+          },
+          {
+            value: "1",
+            name: "年度",
+            text: "年度"
+          },
+          {
+            value: "2",
+            name: "半年度",
+            text: "半年度"
+          },
+          {
+            value: "3",
+            name: "季度",
+            text: "季度"
+          },
+          {
+            value: "4",
+            name: "月度",
+            text: "月度"
+          }
+        ],
+        selectPftiTheEcho: [0, 0], // 选项回显
+        dateParameter: {
+          cycleType: '-1',
+          name: '全部'
+        },
+        showCalendar: false,
+        minDate: minDate,
+        maxDate: maxDate,
+        timeScope: [new Date(startDate),new Date(endDate)],
+
+        userInfo: this.$userInfo(),
+        timeStr: "选择时间",
+        from: "me",
+
+        statusList: [
+          {
+            id: 0, text: "全部", value: "-1"
+          },
+          {
+            id: 1, text: "进行中", value: "0"
+          },
+          {
+            id: 2, text: "已结束", value: "1"
+          },
+        ],
+        showStatus: false,
+        statusId: 0,
+        statusName: "状态",
+        params: {
+          keyword: '',
+          page: 1,
+          pageSize: 15,
+          cateId: '',
+          startDate: '',
+          endDate: '',
+          employeeId: '',
+        },
+      }
+    },
+
+    beforeDestroy() {
+      this.params = {
+        keyword: '',
+        page: 1,
+        pageSize: 15,
+        cateId: '',
+        startDate: '',
+        endDate: '',
+        employeeId: '',
+      };
+      this.from = 'me'
+      this.timeStr = "选择时间";
+      // this.timeScope = [new Date(startDate),new Date(endDate)];
+    },
+
+
+    mounted() {
+      this.params.employeeId = this.employeeId
+      this.params.employeeId = this.params.employeeId ? this.params.employeeId : this.$userInfo().id
+      this.getExamineList();
+    },
+
+    methods: {
+
+
+      // 周期选择事件
+      handleCellClick(e) {
+        console.log(e.currentTarget.id)
+      },
+
+
+      // 搜索
+      keyVal: _debounce(function() {
+        this.pullDown();
+        // console.log(123)
+      }),
+
+      handleChooseItem(item) {
+        // if(this.from == 'me') this.goMePage(item)
+        // else this.goOrgExaminePage(item)
+        this.$emit("onConfirm", { reviewId: item.reviewId, employeeId:  item.employeeId })
+      },
+
+      goOrgExaminePage(item) {
+        this.$router.push({ path: "/orgExamine", query: { reviewId: item.reviewId } })
+      },
+
+      goMePage(item) {
+        this.$router.push({ path: "/newMe", query: { reviewId: item.reviewId, employeeId:  item.employeeId } })
+      },
+
+      // 获取考核表列表
+      getExamineList(is, callback) {
+        let that = this;
+        let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
+        let requestdata;
+        if (that.dateParameter.cycleType == '-1') requestdata = { ...that.params }
+        else requestdata = { ...that.params, cycleType: that.dateParameter.cycleType }
+
+        let hasMore = false
+        is ? '' : that.params.page = 1;
+        that.$axiosUser('get', url, requestdata).then(res => {
+          this.skeletonLoad = false;
+          let { data: { data: { list, total }, code } } = res;
+          if (code == 1) {
+            if (requestdata.page === 1) {
+              that.examineList = list
+            } else {
+              that.examineList = that.examineList.concat(list)
+            }
+
+            hasMore = list.length !== 10
+            callback && callback(hasMore)
+          } else {
+            that.examineList = [];
+          }
+          that.filterExamineList = that.examineList;
+        });
+      },
+
+      // 打开周期选择弹框
+      openPanel(){
+        this.pullonThePanel = true;
+        this.$nextTick(() => {
+          this.theEchoVanPicker()
+        })
+      },
+
+      // 回显
+      theEchoVanPicker() {
+        this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+      },
+
+      //  确认周期选择-考核包搜索
+      onConfirm (data, value) {
+        // let columns = this.columns[list[0]];
+        // let options = this.cycleTypeArr[list[1]]
+        // this.selectPftiTheEcho = list
+        this.dateParameter = {
+          cycleType: data.value,
+          name: data.name
+        };
+        // console.log(this.dateParameter);
+        this.pullDown();
+        this.pullonThePanel = false
+      },
+
+      // 上拉刷新
+      refresh (done) {
+        this.getExamineList(false, done)
+      },
+
+      // 下拉加载
+      infinite (done) {
+        this.params.page ++;
+        this.getExamineList(true, done)
+      },
+
+      pullDown(){
+        setTimeout(() => {
+          this.$refs.scroller.triggerPullToRefresh();
+        }, 50);
+      },
+
+      // 日期选择
+      changeDateGetList() {
+        if(this.timeScope && this.timeScope.length > 0) {
+          this.params.startDate = moment(this.timeScope[0]).format('YYYY-MM-DD')
+          this.params.endDate = moment(this.timeScope[1]).format('YYYY-MM-DD')
+          this.timeStr = this.params.startDate + "<br/>" + this.params.endDate
+          this.getExamineList();
+        }
+
+      },
+
+      // 本周
+      timeScopeThisWeek(){
+        this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
+        this.showCalendar= false
+        this.changeDateGetList()
+      },
+      // 上周
+      timeScopeLastWeek(){
+        this.timeScope = [new Date(moment().subtract(1,'week').startOf('week').format('YYYY-MM-DD')),new Date(moment().subtract(1,'week').endOf('week').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+      // 本月
+      timeScopeThisMoth(){
+        this.timeScope = [new Date(moment().startOf('month').format('YYYY-MM-DD')),new Date(moment().endOf('month').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+      // 上周
+      timeScopeLastMonth(){
+        this.timeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+
+
+      calendarOpen(){
+        this.showCalendar = true;
+      },
+
+      calendarClose(){
+        this.showCalendar = false;
+      },
+
+      calendarConfirm(event){
+        const [start,end] = event;
+        this.timeScope = [start, end];
+        this.showCalendar = false;
+        this.changeDateGetList();
+      },
+
+
+      handleConfirm() {
+        if(this.statusId !== '-1') this.filterExamineList = this.examineList.filter(item => item.status == this.statusId)
+        else this.filterExamineList = this.examineList
+        this.statusName = this.statusList.find(item => item.value == this.statusId).text || '状态'
+        this.showStatus = false
+      },
+
+      handleCancel() {
+        this.showStatus = false
+      }
+
+    }
+  }
+
+
+</script>
+
+<style lang="less" scoped>
+
+  /deep/ .van-calendar__header-subtitle {
+    width: 100%;
+    font-size: 0.28rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .cycle-select-box {
+    width: 100%;
+    padding: 0.2rem 0.1rem;
+    box-sizing: border-box;
+    background-color: #fff;
+    box-sizing: border-box;
+    .icon {
+      margin-right: 6px;
+      width: 0.32rem;
+      height: 0.32rem;
+    }
+    .cycle-name {
+      margin: 0 6px;
+      font-size: 0.3rem;
+    }
+  }
+
+  .search-box {
+    background-color: white;
+    border-top: 1px solid #f1f1f1;
+    border-bottom: 1px solid #f1f1f1;
+    margin-bottom: 0.2rem;
+  }
+
+
+  .scroller-box {
+    height: calc(100% - 2.08rem) !important;
+    position: relative !important;
+    background-color: #f5f7fa;
+    box-sizing: border-box;
+
+    .examine-list {
+      width: 100%;
+      .examine-item {
+        width: 100%;
+        height: 1rem;
+        padding: 0 0.2rem;
+        background-color: #fff;
+        box-sizing: border-box;
+        display: flex;
+        align-items: center;
+        border-bottom: 1px solid #f1f1f1;
+        &-status{
+          padding:0.01rem 0.1rem;
+          color: #fff;
+          border-radius: 2px;
+          font-size: 0.26rem;
+          background-color: #67c23a;
+          margin-right: 0.14rem;
+        }
+
+        &-info {
+          font-size: 0.26rem;
+        }
+      }
+    }
+
+
+  }
+</style>

+ 203 - 0
src/newPerformance/components/public/OperateLog.vue

@@ -0,0 +1,203 @@
+<template>
+  <div class="log-list-box">
+    <!-- 操作日志 -->
+    <div>
+
+      <div class="modTit">操作日志</div>
+      <div class="modCont" style="">
+        <div
+          v-for="(item, index) in logList"
+          :key="index"
+          :style="index != logList.length - 1 ? 'min-height: 1rem;' : ''"
+          style="position: relative; padding-bottom: .2rem;"
+        >
+
+          <van-row gutter="10">
+            <van-col span="15">
+              <div v-if="item.employeeId"  style="display:flex;">
+                <userImage class="about-me__avatar" :id="item.employeeId" :user_name="item.name" fontSize=".24" width="0.5rem" height="0.5rem" font_min></userImage>
+                <span  style="font-size:.255rem;padding: .06rem 0 0 .07rem;" class="font-flex-word">{{ item.name }}</span>
+              </div>
+              <div v-else style="display:flex;">
+                <img src="static/images/robot.png" alt="" style="width: 0.5rem; height: 0.5rem;"/>
+                <span style="font-size:.255rem; padding: .06rem 0 0 .07rem;" class="font-flex-word">系统操作</span>
+              </div>
+
+              <div v-if="index != logList.length - 1" class="bian"></div>
+            </van-col>
+            <van-col span="9" style="font-size:.24rem;color:#ababab; padding:.06rem 0 0 0; text-align: right;">{{ item.createTime }}</van-col>
+          </van-row>
+          <van-row>
+            <van-col offset="2" span="" style="font-size:.255rem;padding-top:.06rem;white-space:normal;">
+              <div style="color:#ababab;width: 100%;word-break:break-all;" v-if="item.content">{{ item.content }}</div>
+            </van-col>
+          </van-row>
+        </div>
+
+
+        <span style="font-size: .26rem;color: #5699ff;" @click="unfold" v-if="logList.length <= 3 && recordAllList.length > 3">全部记录</span>
+        <span style="font-size: .26rem;color: #5699ff;" @click="packUp" v-if="logList.length > 3">收起</span>
+
+        <!-- 加载提示 -->
+        <div v-if="loading" class="tip">加载中...</div>
+        <!-- <div v-if="!hasMore" class="tip">没有更多了</div> -->
+
+        <!-- 触发器(哨兵元素) -->
+        <div ref="sentinel" class="sentinel"></div>
+      </div>
+
+
+    </div>
+  </div>
+</template>
+
+<script>
+  export default {
+    props: {
+      reviewId: {
+        type: String | Number,
+        default: ''
+      },
+
+      reviewIndicatorId: {
+        type: String | Number,
+        default: ''
+      }
+    },
+
+    data() {
+      return {
+        logList: [],
+        recordAllList: [],
+        page: 0,
+        pageSize: 3,
+        total: 0,
+        loading: false,  // 加载状态
+        hasMore: true,    // 是否还有更多
+        canLoadMore: false,
+        params: {
+          reviewId: '',
+          page: 1,
+          pageSize: 10,
+        },
+      }
+    },
+
+
+    mounted() {
+
+      this.params.reviewId = this.reviewId
+      this.getLogData(true); // 首屏数据
+      this.$nextTick(() => {
+        this.createObserver(); // 创建交叉观察器
+      })
+
+    },
+
+    beforeDestroy() {
+      this.observer && this.observer.disconnect();
+    },
+
+
+    methods: {
+
+      createObserver() {
+        this.observer = new IntersectionObserver(
+          (entries) => {
+            const entry = entries[0];
+            if (entry.isIntersecting && !this.loading && this.hasMore && this.canLoadMore) {
+              this.params.page++;
+              this.getLogData();
+            }
+          },
+          { root: null, threshold: 0 }   // root=null 表示视口
+        );
+        if(this.$refs && this.$refs.sentinel) {
+          this.observer.observe(this.$refs.sentinel);
+        }
+      },
+
+      async getLogData(isInit = false) {
+        this.loading = true;
+        let url = `/performance/statistics/logs/${this.$userInfo().site_id}/${this.reviewId}`
+        let requestParams = {}
+
+        if (this.reviewIndicatorId) {
+          requestParams = { ...this.params, reviewIndicatorId: this.reviewIndicatorId }
+        } else {
+          requestParams = { ...this.params }
+        }
+        try {
+          const res = await this.$axiosUser("get", url, requestParams);
+          this.total = res.data.data.total
+          let list = res.data.data.list;
+          list = list.reverse();
+          this.recordAllList.push(...list);
+          if(isInit) {
+            list.forEach((item, index) => {
+              if (index < 3) {
+                this.logList.push(item);
+              }
+            });
+          }
+          this.hasMore = this.recordAllList.length < this.total;
+        }
+        finally {
+          this.loading = false;
+        }
+
+      },
+
+
+      // 展开记录
+      unfold() {
+        this.canLoadMore = true;
+        this.logList = this.recordAllList;
+      },
+
+      // 收起记录
+      packUp() {
+        this.canLoadMore = false;
+        let listtre = [];
+        this.recordAllList.forEach((item, index) => {
+          if (index < 3) {
+            listtre.push(item);
+          }
+        });
+        this.logList = listtre;
+      },
+
+    },
+  }
+</script>
+
+<style scoped lang="less">
+
+  .log-list-box {
+    width: 100%;
+    height: 100%;
+
+    .modTit {
+      background-color: #efefef;
+      height: 0.8rem;
+      line-height: 0.8rem;
+      font-size: 0.28rem;
+      color: #8a8a8a;
+      padding-left: 0.1rem;
+      box-sizing: border-box;
+    }
+    .modCont {
+      padding: 0.3rem;
+      background-color: #fff;
+    }
+
+    .tip {
+      text-align: center;
+      color: #8a8a8a;
+      height: 0.5rem;
+      font-size: 0.24rem;
+      line-height: 0.5rem;
+    }
+  }
+
+</style>

+ 40 - 0
src/newPerformance/components/public/VanSkeleton.vue

@@ -0,0 +1,40 @@
+<template>
+  <div style="display:inline;">
+    <van-skeleton :row="5" :loading="skeLoad">
+      <slot></slot>
+    </van-skeleton>
+  </div>
+</template>
+
+<script>
+import Vue from "vue";
+import { Skeleton } from "vant";
+Vue.use(Skeleton);
+export default {
+  props: {
+    skeLoad: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {};
+  },
+  components: {},
+  watch: {},
+  methods: {},
+  created() {},
+  mounted() {}
+};
+</script>
+
+<style scoped lang="less">
+/deep/ .van-skeleton__content {
+// height: 100%;
+  padding: 0.3rem 0;
+  .van-skeleton__row {
+    height: 0.7rem;
+    margin: 1.2rem 0;
+  }
+}
+</style>

+ 377 - 0
src/newPerformance/components/workbenchcontent/backlog.vue

@@ -0,0 +1,377 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="待办事项" left-text="" left-arrow @click-left="routerBack" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <template>
+        <van-tabs v-model="type" @change="changeTab">
+          <van-tab title="待处理" name="noEntering"></van-tab>
+          <van-tab title="已处理" name="entering"></van-tab>
+        </van-tabs>
+
+        <header class="flex-box-ce">
+          <div class="flex-1">
+            当前待办:
+            <span v-if="commission > 0" style="color: #e42000; font-size: .29rem;">{{ commission }}条</span>
+          </div>
+          <div class="selector" @click="selectPfTIme">
+            <span>{{ selectPftiText }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+        </header>
+
+        <scroller v-if="type == 'noEntering'" ref="work_bench_scroller" class="all" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="noEnteringList">
+          <template v-if="noEnteringList && noEnteringList.length > 0">
+            <div class="list-item" v-for="(item, index) in noEnteringList" :key="index" @click="goHandlePage(item.reviewId, item.reviewIndicatorId, item.taskId, 'entering')">
+
+              <div class="flex-box-ce" style="justify-content: space-between;">
+                <div class="flex-box-ce">
+                  <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" fontSize="0.28" width="0.6rem" height="0.6rem" style="margin-right: 0.08rem;"></userImage>
+                  <div style="font-size: 0.28rem; font-weight: 500; margin-right: 0.14rem;">{{item.employeeName}}</div>
+                </div>
+                <div style="font-size: 0.28rem; " class="fontColorC">{{ item.reviewTitle }}</div>
+              </div>
+
+              <div style="line-height: 0.6rem; font-size: 0.3rem; margin-bottom: 0.1rem;">指标:{{ item.title }} </div>
+
+              <div class="flex-box-ce" style="justify-content: space-between; margin-bottom: 0.1rem;">
+                <div class="node-type">
+                  {{ item.nodeType | formatNodeType }}
+                </div>
+                <div class="btn">去处理</div>
+              </div>
+
+            </div>
+          </template>
+          <van-empty v-else description="暂无绩效考核数据" />
+          <div style="height: 0.5rem;"></div>
+        </scroller>
+
+        <scroller v-if="type == 'entering'" ref="work_bench_scroller2" class="all" :on-refresh="refresh2" :on-infinite="infinite2" noDataText="我也是有底线的" :list="enteringList">
+          <template v-if="enteringList && enteringList.length > 0">
+            <div class="list-item" v-for="(item, index) in enteringList" :key="index" @click="goHandlePage(item.reviewId, item.reviewIndicatorId, item.taskId, 'noEntering')">
+              <div class="flex-box-ce" style="justify-content: space-between;">
+                <div class="flex-box-ce">
+                  <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" fontSize="0.28" width="0.6rem" height="0.6rem" style="margin-right: 0.08rem;"></userImage>
+                  <div style="font-size: 0.28rem; font-weight: 500; margin-right: 0.14rem;">{{item.employeeName}}</div>
+                </div>
+                <div style="font-size: 0.28rem; " class="fontColorC">{{ item.reviewTitle }}</div>
+              </div>
+              
+              <div style="line-height: 0.6rem; font-size: 0.3rem; margin-bottom: 0.1rem;">指标:{{ item.title }} </div>
+              
+              <div class="flex-box-ce" style="justify-content: space-between; margin-bottom: 0.1rem;">
+                <div class="node-type">
+                  {{ item.nodeType | formatNodeType }}
+                </div>
+                <div class="btn">查看详情</div>
+              </div>
+            </div>
+          </template>
+
+          <van-empty description="暂无绩效考核数据" v-if="enteringList.length == 0" />
+          <div style="height: 0.5rem;"></div>
+        </scroller>
+
+      </template>
+    </VanSkeleton>
+
+    <van-dialog v-model="selectpfdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="doSthForData.type">
+        <van-radio
+          v-for="(item, index) in selectpfList"
+          :key="index"
+          :name="item.value"
+          @click="clickpfTime(item)"
+          style="margin:.3rem 0 .3rem .4rem;font-size:.3rem"
+          icon-size="16px"
+        >
+          <span style="margin-left:.3rem">{{ item.label }}</span>
+        </van-radio>
+      </van-radio-group>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { mapGetters, mapState } from 'vuex';
+import moment from 'moment';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import {Tab, Tabs, Search} from 'vant'
+Vue.use(Tab).use(Tabs).use(Search)
+export default {
+  data() {
+    return {
+      skeletonLoad: false, // 过度骨架屏
+      backlogList: [],
+      commission: 0,
+      doSthForData: {
+        siteId: this.$userInfo().site_id,
+        employeeId: this.$userInfo().id,
+        page: 1, // 当期页
+        pageSize: 15, // 一页多少数据
+        type: 0 // 0-全部 1-确认目标 2-录入结果 3-自评 4-互评 5-评分 6-审批 7-考核面谈
+      },
+      theBackupList: [],
+      // 分类相关
+      selectpfList: [
+        // 选择时间选项
+        { label: '全部', value: 0 },
+        { label: '确认目标', value: 1 },
+        { label: '录入结果', value: 2 },
+        { label: '自评', value: 3 },
+        { label: '互评', value: 4 },
+        { label: '评分', value: 5 },
+        { label: '审批', value: 6 }
+      ],
+      selectpfdlg: false,
+      selectPftiText: '全部', // 默认值
+      pendingList: [] ,//提供给考核详情上下切换人员列表
+      plcList:[],
+      userInfo: this.$userInfo(),
+      type:'noEntering',
+      noEnteringList: [],
+      enteringList:[],
+      enteringList2:[],
+      page: 1,
+    };
+  },
+
+  computed: {
+    ...mapGetters(['site_info'])
+  },
+
+  components: { VanSkeleton },
+
+  filters: {
+    formatNodeType(val) {
+      // targetConfirm-确认目标 resultInput-录入结果值 scoreSelf-自评 scoreEachOther-互评 score-评分 review-审批
+      if(val === 'targetConfirm') return '确认目标'
+      if(val === 'resultInput') return '录入结果'
+      if(val === 'scoreSelf') return '自评'
+      if(val === 'scoreEachOther') return '互评'
+      if(val === 'score') return '评分'
+      if(val === 'review') return '审批'
+    }
+  },
+
+
+  activated() {
+    this.page = 1;
+    this.doSthForData.page = 1;
+    this.doSthForData.type = 0;
+    this.selectPftiText = '全部'; // 默认值
+    if(this.type == 'noEntering'){
+      setTimeout(() => {
+        this.$refs.work_bench_scroller.triggerPullToRefresh();
+      }, 50);
+    }else{
+      setTimeout(() => {
+        this.$refs.work_bench_scroller2.triggerPullToRefresh();
+      }, 50);
+    }
+  },
+
+
+
+  methods: {
+
+    changeTab(name) {
+      this.page = 1;
+      this.doSthForData.page = 1;
+      this.doSthForData.type = 0;
+      this.selectPftiText = '全部'; // 默认值
+      if(this.type == 'noEntering'){
+        console.log("请求待处理数据")
+        setTimeout(() => {
+          this.$refs.work_bench_scroller.triggerPullToRefresh();
+        }, 50);
+      }else{
+        setTimeout(() => {
+          this.$refs.work_bench_scroller2.triggerPullToRefresh();
+        }, 50);
+      }
+    },
+
+    getNoEntering(callback) {
+      let hasMore = false;
+      let url = `/performance/review/job/employee/app/${this.$userInfo().site_id}/${this.$userInfo().id}`
+      this.commission = 0;
+      this.$axiosUser('get', url, this.doSthForData).then(res => {
+        if(res.data.code == 1) {
+          this.commission = res.data.data.total;
+          let list = res.data.data.list;
+          this.skeletonLoad = false;
+          if(list && list.length > 0) {
+            list.forEach(item => {
+              let userInfo = this.$getEmployeeMapItem(item.employeeId)
+              item.userInfo = userInfo
+            })
+          }
+
+          if (this.doSthForData.page === 1) {
+            this.noEnteringList = list;
+          } else {
+            this.noEnteringList = this.noEnteringList.concat(list);
+          }
+          hasMore = list.length !== 10;
+          callback && callback(hasMore);
+        }
+      })
+    },
+
+    getEnteringList(callback) {
+      let hasMore = false;
+      this.commission = 0;
+      let url = `/performance/review/job/employee/app/history/${this.$userInfo().site_id}/${this.$userInfo().id}`
+      this.$axiosUser('get', url, this.doSthForData).then(res => {
+        if(res.data.code == 1) {
+          this.commission = res.data.data.total;
+          let list = res.data.data.list;
+          this.skeletonLoad = false;
+          if(list && list.length > 0) {
+            list.forEach(item => {
+              let userInfo = this.$getEmployeeMapItem(item.employeeId)
+              item.userInfo = userInfo
+            })
+          }
+
+          if (this.doSthForData.page === 1) {
+            this.enteringList = list;
+          } else {
+            this.enteringList = this.enteringList.concat(list);
+          }
+          hasMore = list.length !== 10;
+          callback && callback(hasMore);
+        }
+      })
+    },
+
+    clickpfTime(item) {
+      this.selectPftiText = item.label;
+      this.doSthForData.page = 1;
+      if(this.type === "noEntering") {
+        setTimeout(() => {
+          this.$refs.work_bench_scroller.triggerPullToRefresh();
+        }, 50);
+      }else {
+        setTimeout(() => {
+          this.$refs.work_bench_scroller2.triggerPullToRefresh();
+        }, 50);
+      }
+
+      this.selectpfdlg = false;
+    },
+
+    selectPfTIme() {
+      this.selectpfdlg = true;
+    },
+
+    goHandlePage(reviewId, reviewIndicatorId, taskId, type) {
+      this.$router.push({ path:'/newBacklogDetails', query: { reviewId, reviewIndicatorId, taskId, type } });
+    },
+
+
+    // 上拉刷新
+    refresh(done) {
+      this.doSthForData.page = 1;
+      this.getNoEntering(done);
+    },
+
+    // 下拉加载
+    infinite(done) {
+      this.doSthForData.page++;
+      this.getNoEntering(done);
+    },
+
+
+
+    // 返回上一页
+    routerBack() {
+      this.$route_back();
+    },
+
+    // 上拉刷新
+    refresh2(done) {
+      this.doSthForData.page = 1;
+      this.getEnteringList(done);
+    },
+
+    // 下拉加载
+    infinite2(done) {
+      this.doSthForData.page++;
+      this.getEnteringList(done);
+    },
+
+  },
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  height: calc(100% - 2.64rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+.all2{
+  height: calc(100% - 1.84rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  padding: 0.2rem;
+  background-color: #fff;
+  padding-left: 0.2rem;
+  font-size: 0.3rem;
+  z-index: 1;
+  box-sizing: border-box;
+  border-bottom: 1px solid #f1f1f1;
+  border-top: 1px solid #f1f1f1;
+}
+
+.backlog_list_tit {
+  background-color: #f5f7fa;
+  padding: 0.2rem 0 0.2rem 0.2rem;
+  font-size: 0.28rem;
+}
+.backlog_list {
+  padding: 0.32rem 0.3rem 0.32rem 0.45rem;
+  box-sizing: border-box;
+  span {
+    font-size: 0.29rem;
+  }
+}
+
+.mb-2 {
+  margin-bottom: 0.2rem;
+}
+
+.list-item {
+  width: 96%;
+  padding: 0.2rem;
+  background-color: #fff;
+  box-sizing: border-box;
+  font-size: 0.28rem;
+  position: relative;
+  margin: 0.2rem auto 0 auto;
+  border-radius: 8px;
+  .node-type {
+    background-color: #ecf5ff;
+    width: 1.3rem;
+    text-align: center;
+    padding: 0.05rem;
+    color: #fff;
+    border-radius: 6px;
+    font-size: 0.3rem;
+    color: #26a2ff;
+    margin-right: 0.14rem;
+  }
+
+  .btn {
+    padding: 0.05rem;
+    border-radius: 6px;
+    color: #26a2ff;
+    font-size: 0.28rem;
+  }
+}
+</style>

+ 199 - 0
src/newPerformance/utils/auth.js

@@ -0,0 +1,199 @@
+import store from '@/store'
+import {getUserData} from '@/utils/auth'
+/* 角色*/
+/*
+创始人 creator
+主管理员 masterAdministrator
+子管理员 childAdministrator
+部门管理员 deptManager
+员工 employee
+*/
+// 权限
+/*
+1   绩效考核
+2   OKR
+3   管理范围 全公司
+4   管理范围 所在部门以及下级部门
+5   管理范围 特定部门
+6   考核管理 可见考核结果
+7   考核管理 发起考核
+8   考核管理 开始评分
+9   考核管理 调整结果
+10  考核管理 调整等级
+11  考核管理 导出报表
+12  指标库管理
+13  指定考评模板管理
+14  全部考评模板管理
+15  基础设置
+16  绩效报表
+*/
+
+// 获取当前登录者在绩效系统中的身份
+export function getRole(type) {
+  /* type为判断哪些角色*/
+
+  var role = window.plus ? JSON.parse(plus.storage.getItem('role')) : JSON.parse(localStorage.getItem('role'))
+  let is = false;
+  switch (type) {
+    case 1: // 判断是否是主子管理员
+      if (role == 'masterAdministrator' || role == 'childAdministrator') {
+        is = true
+      }
+      break
+    case 2: // 判断是否是部门管理员
+      if (role == 'deptManager') {
+        is = true
+      }
+      break
+    case 3: // 判断是否是员工
+      if (role == 'employee') {
+        is = true
+      }
+      break
+    case 4: // 判断是否是创始人
+      if (role == 'creator') {
+        is = true
+      }
+      break
+  }
+  return is
+}
+// 判断当前登录者是否有某项权限
+export function getPermis(type) {
+  /* type为传入的权限id*/
+  let jurisdictions = getUserData().per_permission.permission.map((item) => {
+    return item.id
+  })
+  return jurisdictions.indexOf(type) >= 0
+}
+
+// 判断是否具有权限
+export function isAuthoritys_jx(id, arr) { // 判断是否为某项权限:id为权限ID,arr为数据源
+  var jurisdictions
+  if (arr) {
+    jurisdictions = arr.map((item) => {
+      return item.id
+    })
+  } else { // 当没有指定数据源,代表判断当前登录者,如果登陆者是创始人,直接返回真
+    jurisdictions = getUserData().per_permission.permission.map((item) => {
+      return item.id
+    })
+  }
+  if (typeof(id) === 'number') { // 单个权限
+    return jurisdictions.indexOf(id) >= 0
+  } else { // 多个权限一起判断,如果有一个真就返回真
+    const is = jurisdictions.some(item => {
+      if (id.indexOf(item) >= 0) {
+        return true
+      }
+    })
+    return is
+  }
+}
+
+// 自动积分相关
+export function returnStr3(item, index, arr = [], expression) { //列举 百分比
+  let str = '';
+  let point = returnPoint(item.point); //得分
+  let Lieh = expression.compare == 1 ? '【结果值】' : expression.compare == 2 ? '【结果值/目标值】' : '【结果值-目标值】'
+  let jiajian = item.selectVal == 1 ? '加' : '扣';
+  // 公式开始
+  if (index == 0) {
+    str = `${Lieh}比【目标值】每增加${item.plusNum}时,【得分=${point}】${jiajian}${item.numVal},最多${jiajian}${item.maxNum}<br/>`
+    return str
+  }
+  if (index == 1) { //公式中间
+    str = `${Lieh}比【目标值】每减少${item.plusNum}时,【得分=${point}】${jiajian}${item.numVal},最多${jiajian}${item.maxNum}<br/>`
+    return str
+  }
+  //公式结束
+  if (index == 2) {
+    str = `${Lieh}${item.selectVal=='1'?'>':'<'}${item.plusNum},得分=0<br/>`
+    return str
+  }
+};
+export function returnStr2(item, index, arr = [], expression) { //列举 公式
+  let str = '';
+  let point = returnPoint(item.point); //得分
+  let Lieh = expression.compare == 1 ? '【结果值】' : expression.compare == 2 ? '【结果值/目标值】' : '【结果值-目标值】'
+  let val = expression.reference == '1' ? item.selectRefer : '【' + item.referStr + '】'
+  // 公式开始
+  if (index == 0) {
+    str = `${Lieh}==${val},得分=${point}<br/>`
+    return str
+  }
+  //公式结束
+  if (index == arr.length - 1) {
+    str = `否在,得分=${point}<br/>`
+    return str
+  }
+  if (index != 0 && index != arr.length - 1) { //公式中间
+    str = `${Lieh}==${val},得分=${point}<br/>`
+    return str
+  }
+};
+export function returnStr(item, index, arr = [], expression) { //连续区间 公式
+  let str = '';
+  let point = returnPoint(item.point); //得分
+  let Lieh = expression.compare == 1 ? '【结果值】' : expression.compare == 2 ? '【结果值/目标值】' : '【结果值-目标值】'
+  let val = expression.reference == '1' ? item.selectRefer : '【' + item.referStr + '】'
+  let slectSymbol = item.slectSymbol == '>' ? '>=' : item.slectSymbol == '≥' ? '>' : '='
+  // 公式开始
+  if (index == 0) {
+    str = `${Lieh}${slectSymbol}${val},得分=${point}<br/>`
+    return str
+  }
+  //公式结束
+  if (index == arr.length - 1) {
+    str = `${item.refer}${item.symbol}${Lieh},得分=${point}<br/>`
+    return str
+  }
+  if (index != 0 && index != arr.length - 1) {
+    let upItemVal = expression.reference == '1' ? arr[index - 1].selectRefer : '#' + arr[index - 1].referStr +
+      '#'; //上一个数据
+    //公式中间
+    let symbol = item.symbol == '≥' ? '>=' : item.symbol
+    if (item.slectSymbol == '=') {
+      str = `${Lieh}==${val},得分=${point}<br/>`
+    } else {
+      str = `${upItemVal}${symbol}${Lieh}${slectSymbol}${val},得分=${point}<br/>`
+    }
+    return str
+  }
+};
+export function returnPoint(point) {
+  let str = '';
+  if (!point) {
+    return str
+  }
+  point.forEach(e => {
+    str += e
+  })
+  return str
+};
+export function getExpressionStr(arr) {
+  let expressionStr = '';
+  if (arr.logic_type == 1) {
+    let logic_section = JSON.parse(JSON.stringify(arr.logic_section))
+    logic_section.forEach((item, index) => {
+      expressionStr += returnStr(item, index, logic_section, arr)
+    })
+  }
+  if (arr.logic_type == 2) {
+    let logic_enum = JSON.parse(JSON.stringify(arr.logic_enum))
+    logic_enum.forEach((item, index) => {
+      expressionStr += returnStr2(item, index, logic_enum, arr)
+    })
+  }
+  if (arr.logic_type == 3) {
+    let logic_percent = JSON.parse(JSON.stringify(arr.logic_percent))
+    logic_percent.forEach((item, index) => {
+      expressionStr += returnStr3(item, index, logic_percent, arr)
+    })
+  }
+  if (arr.logic_type == 4) {
+    let logic_eq = JSON.parse(JSON.stringify(arr.logic_eq))
+    expressionStr = `得分=${returnPoint(logic_eq)}`;
+  }
+  return expressionStr
+};

+ 34 - 0
src/newPerformance/utils/observer-store.js

@@ -0,0 +1,34 @@
+import Vue from 'vue'
+
+// 全局响应式仓库
+export const listStore = Vue.observable({
+  list: [],        // 已加载数据
+  page: 1,         // 当前页
+  loading: false,  // 是否正在请求
+  hasMore: true    // 是否还有更多
+})
+
+// 对外暴露的“方法集合”
+export const actions = {
+  async loadMore() {
+    if (listStore.loading || !listStore.hasMore) return
+    listStore.loading = true
+    try {
+      let url = `/performance/statistics/logs/${this.$userInfo().site_id}/${this.reviewId}`
+      let res = await this.$axiosUser("get", url, requestParams)
+      console.log("请求日志列表")
+      console.log(res);
+      // const res = await fetch(`/api/items?page=${listStore.page}`).then(r => r.json())
+      listStore.list.push(...res.data.data.list)
+      listStore.page++
+      listStore.hasMore = res.data.data.list.length > 0
+    } finally {
+      listStore.loading = false
+    }
+  },
+  reset() {   // 重置(下拉刷新或切换 tab)
+    listStore.list = []
+    listStore.page = 1
+    listStore.hasMore = true
+  }
+}

+ 606 - 0
src/newPerformance/view/handleDetails.vue

@@ -0,0 +1,606 @@
+<template>
+  <div class="all">
+    <van-nav-bar title="处理详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="overall">
+      <scroller>
+        <div class="modTit">
+          审批详情
+        </div>
+        <ol class="steps">
+          <template v-for="node in showData.nodes">
+            <template v-if="node.type === 'targetConfirms'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'target_confirm' ? 'active' : ''">
+                  1.确认目标{{ showData.businessStatus === 'target_confirm' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.children && node.children.length > 0">
+                    <div class="content-info" v-for="child in node.children" :key="child.id">
+                      <div class="user-type" v-if="child.tasks && child.tasks.length > 0">
+                        {{ child.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-if="child.tasks && child.tasks.length > 0">
+                        <div class="info" v-for="task in child.tasks" :key="task.taskId">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <!-- <el-tooltip effect="dark" placement="right">
+                              <div v-html="task.comment" slot="content" style="max-width: 300px">
+                              </div>
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </el-tooltip> -->
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                          </div>
+
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="content" v-else>
+                    未开始
+                  </div>
+                </li>
+              </template>
+
+              <template v-if="!node.enable">
+                <li class="title">1.确认目标</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+            </template>
+
+            <template v-if="node.type === 'resultInput'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'result_input' ? 'active' : ''">
+                  2.录入结果{{ showData.businessStatus === 'result_input' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.tasks && node.tasks.length > 0">
+                    <div class="content-info">
+                      <div class="user-type">
+                        {{ node.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-for="task in node.tasks" :key="task.taskId">
+                        <div class="info">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }},结果值:{{ task.result || '--'}}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                           <!-- <el-tooltip effect="dark" placement="right">
+                              <div v-html="task.comment" slot="content" style="max-width: 300px">
+                              </div>
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </el-tooltip> -->
+                          </div>
+                        </div>
+
+                        <div class="files" v-if="task.files && task.files.length > 0">
+                          <div class="file-title">附件列表</div>
+                          <div class="file-list">
+                            <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                              <!-- {{ file | filterFileName }} -->
+                              {{ '附件' + (index + 1) }}
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+
+
+                  </div>
+                  <div v-else class="content">
+                    未开始
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">2.录入结果</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'scoreSelf'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'score_self' ? 'active' : ''">
+                  3.自评{{ showData.businessStatus === 'score_self' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.tasks && node.tasks.length > 0">
+                    <div class="content-info">
+                      <div class="user-type">
+                        {{ node.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-for="task in node.tasks" :key="task.taskId">
+                        <div class="info">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }},评分:{{ task.score || '--' }}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                          </div>
+                        </div>
+
+                        <div class="files" v-if="task.files && task.files.length > 0">
+                          <div class="file-title">附件列表</div>
+                          <div class="file-list">
+                            <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                              {{ '附件' + (index + 1) }}
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                  <div v-else class="content">
+                    未开始
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">3.自评</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'scoreEachOther'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'score_each_other' ? 'active' : ''">
+                  4.互评{{ showData.businessStatus === 'score_each_other' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.tasks && node.tasks.length > 0">
+                    <div class="content-info">
+                      <div class="user-type">
+                        {{ node.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-for="task in node.tasks" :key="task.taskId">
+                        <div class="info">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }},评分:{{ task.score || '--' }}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            <!-- <el-tooltip effect="dark" placement="right">
+                              <div v-html="task.comment" slot="content" style="max-width: 300px">
+                              </div>
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </el-tooltip> -->
+                          </div>
+                        </div>
+
+                        <div class="files" v-if="task.files && task.files.length > 0">
+                          <div class="file-title">附件列表</div>
+                          <div class="file-list">
+                            <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                              {{ '附件' + (index + 1) }}
+                            </div>
+                          </div>
+                        </div>
+
+                      </div>
+                    </div>
+                  </div>
+                  <div v-else class="content">
+                    未开始
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">4.互评</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'scores'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'score' ? 'active' : ''">
+                  5.评分{{ showData.businessStatus === 'score' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.children && node.children.length > 0">
+                    <div class="content-info" v-for="child in node.children" :key="child.id">
+                      <div class="user-type" v-if="child.tasks && child.tasks.length > 0">
+                        {{ child.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-if="child.tasks && child.tasks.length > 0">
+                        <template v-for="task in child.tasks">
+                          <div class="info" :key="task.taskId">
+                            <div class="info-left">
+                              <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                                {{ task.state === 'created' ? '进行中' : '已完成' }},
+                              </span>
+                              {{ task.assigneeName }},评分:{{ task.score }}
+                            </div>
+                            <div class="info-right" v-if="task.comment">
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                              <!-- <el-tooltip effect="dark" placement="right">
+                                <div v-html="task.comment" slot="content" style="max-width: 300px">
+                                </div>
+                                <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                              </el-tooltip> -->
+                            </div>
+                          </div>
+
+                          <div class="files" v-if="task.files && task.files.length > 0">
+                            <div class="file-title">附件列表</div>
+                            <div class="file-list">
+                              <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                                {{ '附件' + (index + 1) }}
+                              </div>
+                            </div>
+                          </div>
+                        </template>
+                      </div>
+                      <div v-else>
+                        未开始
+                      </div>
+                    </div>
+
+                  </div>
+
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">5.评分</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'reviews'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'review' ? 'active' : ''">
+                  6.审批{{ showData.businessStatus === 'review' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.children && node.children.length > 0">
+
+                    <div class="content-info" v-for="child in node.children" :key="child.id">
+                      <div class="user-type" v-if="child.tasks && child.tasks.length > 0">
+                        {{ child.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-if="child.tasks && child.tasks.length > 0">
+
+                        <template v-for="task in child.tasks">
+                          <div class="info" :key="task.taskId">
+                            <div class="info-left">
+                              <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                                {{ task.state === 'created' ? '进行中' : '已完成' }},
+                              </span>
+                              {{ task.assigneeName }},评分:{{ task.score }}
+                            </div>
+                            <div class="info-right" v-if="task.comment">
+                              <!-- <el-tooltip effect="dark" placement="right">
+                                <div v-html="task.comment" slot="content" style="max-width: 300px">
+                                </div>
+                                <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                              </el-tooltip> -->
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </div>
+                          </div>
+
+                          <div class="files" v-if="task.files && task.files.length > 0">
+                            <div class="file-title">附件列表</div>
+                            <div class="file-list">
+                              <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                                <!-- {{ file | filterFileName }} -->
+                                {{ '附件' + (index + 1) }}
+                              </div>
+                            </div>
+                          </div>
+                        </template>
+
+
+                      </div>
+                      <div v-else>
+                        未开始
+                      </div>
+                    </div>
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">6.审批</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+          </template>
+
+
+        </ol>
+
+        <!-- 操作日志 -->
+        <OperateLogVue v-if="showData" :reviewId="reviewId" :reviewIndicatorId="reviewIndicatorId"/>
+      </scroller>
+
+
+    </div>
+
+  </div>
+</template>
+
+<script>
+  import Vue from 'vue';
+  import OperateLogVue from '@/newPerformance/components/public/OperateLog.vue'
+  import { ImagePreview } from 'vant';
+  Vue.use(ImagePreview);
+
+  export default {
+
+    components: {
+      OperateLogVue
+    },
+
+    data() {
+      return {
+        reviewIndicatorId: "",
+        reviewId: "",
+        showData: null,
+        type: "",
+      }
+    },
+
+    filters: {
+      filterType(v) {
+          if (v == 'leader') return v = "管理员"
+          if (v == 'self') return v = "被考核人"
+          if (v == 'post') return v = "岗位"
+          if (v == 'user') return v = "指定人员"
+          if (v == 'deptLeader') return v = "部门"
+      },
+
+      filterFileName(str) {
+          if (str) {
+            let lastIndex = str.lastIndexOf("/")
+            return str.substr(lastIndex + 1, str.length - 1);
+          }
+      }
+    },
+
+    created() {
+      this.showData = JSON.parse(this.$route.query.showData);
+      this.reviewIndicatorId = this.showData.reviewIndicatorId
+      this.reviewId = this.showData.reviewId
+    },
+    methods: {
+
+      // 文件预览
+      openFileReview(url) {
+        let file = {
+            url
+        }
+        let imgFiles = ['BMP', 'GIF', 'PNG', 'JPEG', 'JPG', 'bmp', 'gif', 'png', 'jpeg', 'jpg'];
+        let lastIndex = file.url && file.url.lastIndexOf("/") || -1
+        let suffix; //文件后缀名
+
+        if (lastIndex > 0) {
+            suffix = file.url.substr(lastIndex + 1, file.url.length - 1).split(".")[1];
+            if (imgFiles.includes(suffix)) {
+                ImagePreview({
+                  images: [file.url],
+                  startPosition: 0
+                });
+            } else {
+                window.open(file.url, '_blank');
+            }
+        }
+      },
+    }
+  }
+</script>
+
+<style scoped lang="less">
+  .all {
+    width: 100%;
+    height: 100%;
+    .overall {
+      height: calc(100% - 0.92rem) !important;
+      position: relative;
+      overflow-y: scroll;
+    }
+    .modTit {
+      background-color: #efefef;
+      padding-left: 0.1rem;
+      height: 0.8rem;
+      line-height: 0.8rem;
+      font-size: 0.28rem;
+      box-sizing: border-box;
+      color: #8a8a8a;
+    }
+  }
+
+  .green-color {
+      color: #67c23a;
+  }
+
+  .orange-color {
+      color: #e6a23c;
+  }
+
+  .gray-color {
+      color: rgb(144, 147, 153);
+      background: rgb(244, 244, 245);
+      border-color: rgb(144, 147, 153);
+  }
+
+  .show-data-box {
+
+    .item-list {
+      .item {
+
+        .value-box {
+          margin-bottom: 5px;
+
+          .content {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+
+            &-left {
+              display: flex;
+              align-items: center;
+
+              &-status {}
+            }
+          }
+        }
+      }
+    }
+  }
+
+
+  .steps {
+    display: flex;
+    flex-direction: column;
+    margin: 0;
+    padding: 0.2rem;
+    box-sizing: border-box;
+    background-color: #fff;
+    .title {
+      width: 100%;
+      height: 0.5rem;
+      line-height: 0.5rem;
+      font-size: 0.26rem;
+      color: #000;
+    }
+
+    .info-box {
+      display: flex;
+      margin: 0.1rem 0;
+
+      .line {
+        margin: 0 0.2rem;
+        width: 0.02rem;
+        border: 0.02rem dashed #ccc;
+      }
+
+      .content {
+        width: 90%;
+        background-color: #f7f7f7;
+        padding: 0.1rem;
+        color: #89919F !important;
+        box-sizing: border-box;
+        color: #999;
+        font-size: 0.24rem;
+        &-info {
+          display: flex;
+          flex-direction: column;
+
+          .user-type {
+            width: 1.6rem;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            border-radius: 0.4rem;
+            border: 1px solid;
+            height: 0.4rem;
+            font-size: 0.24rem;
+            color: #409eff;
+            background: #ecf5ff;
+            border-color: #b3d8ff;
+          }
+
+          .task-info {
+            margin: 0.1rem 0;
+            color: #89919F !important;
+            font-size: 0.24rem;
+            .info {
+              width: 100%;
+              display: flex;
+              flex-direction: column;
+              font-size: 0.24rem;
+              margin: 0.2rem 0;
+              .info-left {
+              }
+              .info-right {
+              }
+            }
+          }
+        }
+      }
+    }
+
+  }
+
+  .active {
+    color: #409eff !important;
+  }
+
+
+  .files {
+    display: flex;
+    flex-direction: column;
+    border-radius: 6px;
+
+    .file-title {
+      color: #89919F !important;
+      font-weight: 600;
+    }
+
+    .file-item {
+      color: #26a2ff !important;
+      transition: 0.2s;
+      padding-left: 0.1rem;
+      margin-top: 0.1rem;
+      box-sizing: border-box;
+      &:hover {
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
+</style>

+ 104 - 0
src/newPerformance/view/inits.vue

@@ -0,0 +1,104 @@
+<template>
+  <div class="all">
+    <div v-show="!appNavJx" class="noData flex-box-v flex-center-center">
+      <div class="data-all">
+        <img src="static/images/init.gif" class="appImg" />
+        <div style="font-size: .31rem;">管理执行难,就用功道云</div>
+      </div>
+    </div>
+    <div v-show="appNavJx" class="jxNav">
+      <img :src="'static/images/' + navList[navNew].image + '.png'" />
+      <van-button @click="navNew++" v-if="navNew < 1" type="primary" color="rgb(125 171 255)" block>下一步</van-button>
+      <van-button @click="navPaths" v-else type="primary" color="rgb(125 171 255)" block>进入</van-button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      userInfo: {}, // 绩效接口人员信息
+      userData: {}, // 7.0系统接口人员信息
+      newNav: this.plusStoGet('newNav'),
+      appNavJx: false,
+      navList: [{ image: 'newNav1' }, { image: 'newNav2' }],
+      navNew: 0
+    };
+  },
+  created() {
+    this.$removeCache("addthePlan")
+    this.$removeCache("actionplanDetails")
+    this.$removeCache("actionplanList")
+  },
+  activated() {
+    this.newNav = this.plusStoGet('newNav');
+    this.appNavJx = false;
+    this.setRouters();
+  },
+  methods: {
+    setRouters() {
+        if (this.newNav) {
+          this.$router.replace({ name: 'navigation',query:{index:this.$route.query.index} });
+        } else {
+          this.appNavJx = true;
+        }
+    },
+    navPaths() {
+      this.plusStoSet('newNav', 'true', () => {
+        this.$router.replace({ name: 'navigation',query:{index:this.$route.query.index} });
+      });
+    },
+    plusStoGet(key) {
+      if (window.plus) {
+        return plus.storage.getItem(key);
+      } else {
+        return localStorage.getItem(key);
+      }
+    },
+    plusStoSet(key, val, fun = function() {}) {
+      if (window.plus) {
+        plus.storage.setItem(key, val);
+      } else {
+        localStorage.setItem(key, val);
+      }
+      fun();
+    }
+  }
+};
+</script>
+
+<style scoped="scoped" lang="less">
+.all {
+  background-color: #fff;
+}
+.appImg {
+  width: 200px;
+  height: 200px;
+}
+.noData {
+  text-align: center;
+  position: fixed;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+}
+.data-all {
+  margin-bottom: 10%;
+  color: #595959;
+}
+.jxNav {
+  width: 100%;
+  height: 100%;
+  img {
+    width: 100%;
+    margin-top: 50px;
+  }
+  button {
+    width: 90%;
+    margin: auto;
+    border-radius: 5px;
+  }
+}
+</style>

+ 863 - 0
src/newPerformance/view/myTarget/krDetail.vue

@@ -0,0 +1,863 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="KR详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all-box" style="height: calc(100% - 0.92rem);position: relative;">
+      <template >
+        <header class="header">
+          <div class="flex-box">
+            <div class="flex-1" style="font-weight: 600;padding: 0 0.2rem;padding-left: 0.1rem;">{{krDetail.name}}</div>
+          </div>
+          <div class="flex-box-ce fontColorC header-message" style="font-size: 0.26rem;margin-top:0.14rem">
+            <userImage :img_url="krDetail.owner_userInfo.img_url" :user_name="krDetail.owner_userInfo.name" width="0.7rem" height="0.7rem"></userImage>
+            <span>{{ krDetail.owner_userInfo.name }}</span>
+            <van-icon name="star" class="yellow"/>
+            <span>{{krDetail.confident}}分</span>
+            <van-circle layer-color="#E5E9F2" v-model="krDetail.currentRate" :color="krDetail.risk_level==2? '#FF9600':krDetail.risk_level==3? '#f56c6c':' #2879ff'" :rate="krDetail.process" :stroke-width="120" size="20px"/>
+            <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:krDetail.risk_level==2,red:krDetail.risk_level==3}">{{ krDetail.process }}%</span>
+          </div>
+        </header>
+        <div class="scroller">
+          <div class="box" style="border-bottom: 0.2rem solid #f5f7fa;">
+              <div class="title">基本信息</div>
+              <div class="flex-box"><div class="label flex-1">发布人</div><div>{{$getEmployeeMapItem(krDetail.publisher_id).name}}</div></div>
+              <div class="flex-box"><div class="label flex-1">KR权重</div><div>{{krDetail.weight}}%</div></div>
+              <div class="flex-box"><div class="label flex-1">起止时间</div>
+                <div>{{krDetail.start_time}}~{{krDetail.end_time}}</div>
+                <template v-if="krDetail.o_composite_state!=6">
+                  <span v-if="krDetail.day>0" style="padding-left: 0.14rem;">剩余<span class="green">{{krDetail.day}}</span>天</span>
+                  <span v-if="krDetail.day<0" style="padding-left: 0.14rem;">过期<span class="red">{{Math.abs(krDetail.day)}}</span>天</span>
+                </template>
+              </div>
+              <div class="flex-box"><div class="label flex-1">KR评分</div>
+                  <span v-if="krDetail.score===-0.1" class="fontColorC">暂未评分</span>
+                  <span v-else>{{krDetail.score}}分</span>
+              </div>
+              <div class="flex-box">
+                <div class="label flex-1">评分说明</div>
+                <span v-if="krDetail.score_detail" style="max-width: 5.6rem;">{{krDetail.score_detail}}</span>
+                <span v-else class="fontColorC">暂无说明</span>
+              </div>
+              <div class="flex-box">
+                <div class="label">子目标</div>
+                <div class="flex-1" style="text-align: right;">
+                  <span v-if="krOs.length==0" class="fontColorC">暂无子目标</span>
+                  <div v-else class="hoverBlue" style="margin-bottom: 5px;text-align: right;" v-for="(item, index) in krOs" :key="index">
+                    {{item.name}}
+                  </div>
+                </div>
+              </div>
+          </div>
+          <van-tabs v-model="tabActive" class="shadow">
+            <van-tab :title="item.title" :name="item.name" :disabled="item.disabled" v-for="(item, index) in tabs" :key="index"></van-tab>
+            </van-tabs>
+          <div style="margin-top: 0.2rem;">
+            <template v-if="tabActive==1">
+              <div class="list-box" v-for="(item, index) in krsListAll" :key="index">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;border-bottom: 1px solid #f1f1f1;padding-bottom: 0.2rem;">
+                  <span class="flex-1" style="font-size: 0.26rem;" v-if="item.plans.length>0">计划任务<span class="blue">{{returnSum(item.plans)}}</span>/<span>{{item.plans.length}}</span></span>
+                </div>
+                <div style="padding:0 0.1rem;">
+                  <template v-if="item.projects.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index3) in item.projects" :key="task_item.id" @click="openDetail(task_item,3)">
+                        <van-icon name="paid" class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"/>
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD')}} 截止</span>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <template v-if="item.plans.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index2) in item.plans" :key="index2" @click="openDetail(task_item,1)">
+                        <van-icon :name="taskStatus(task_item.composite_state).icon"
+                        class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"
+                        :class="(task_item.day<=0&&$moment(task_item.end_date).format('YYYY-MM-DD')!=$moment().format('YYYY-MM-DD')) ? 'red':''"
+                        />
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD HH:mm')}} 截止</span>
+                            <template v-if="task_item.statistics.plan_total">
+                              <van-icon name="orders-o" />
+                              <span style="font-size: 0.26rem;">
+                                <span class="blue">{{task_item.statistics.plan_finish}}</span>/<span>{{task_item.statistics.plan_total}}</span>
+                              </span>
+                            </template>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <div v-if="item.projects.length==0&&item.plans.length==0" style="text-align: center;margin: 0.2rem 0;font-size: 0.28rem;" class="fontColorC">用“任务”推动目标达成,合理规划安排工作</div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive==2">
+              <Evolve v-if="kr_id" :isOperation="isOperation && !krDetail.process_conf.enable_automatic && krDetail.can_edit" readonly :process="Number(krDetail.process)" :target_id="Number(kr_id)" :target_type="2" style="padding: 0 0.2rem;"></Evolve>
+            </template>
+          </div>
+          <div style="height: 3rem;"></div>
+        </div>
+        <!-- <div class="aite" @click="openCommunication"><van-icon name="more" class="fontColorB" /></div> -->
+        <footer class="footer">
+          <div class="flex-box-ce" v-if="isOperation">
+            <van-icon name="chat-o" @click="openCommunication" style="margin-left: 0.2rem;font-size:0.6rem;" class="fontColorC"/>
+          </div>
+          <div v-else class="fontColorC gt" @click="openCommunication">有事沟通,可@Ta</div>
+        </footer>
+      </template>
+
+    </div>
+    <!-- 关联任务 -->
+    <TaskSearch :visible.sync="isShwoTaskSearch" @confirm="ActiveRelevanceTask"></TaskSearch>
+
+    <!-- 修改KR -->
+    <van-popup v-model:show="isShowUpdateKr" round position="bottom" :style="{ height: '90%',background:'#fff' }" @close="isShowUpdateKr=false">
+       <div>
+         <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+           <div class="blue" @click="isShowUpdateKr=false">取消</div>
+           <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">编辑</div>
+           <div class="blue" @click="confirmUpdateKr">确定</div>
+         </header>
+         <div>
+           <van-field v-model="form.name" rows="3"  type="textarea" maxlength="100"  placeholder="书写建议:KR是可量化的,需要体现行动效果"  show-word-limit/>
+           <van-cell title="开始时间" is-link :value="form.start_date" @click="openTime(1)" />
+           <van-cell title="截止时间" is-link :value="form.end_date" @click="openTime(2)"/>
+           <van-cell title="负责人" is-link @click="openSelectUser(2)"><div>{{form.owner_name}}</div></van-cell>
+           <van-cell title="信心指数" is-link @click="isShowSelectConfidence=true"><div>{{form.confident}}分</div></van-cell>
+         </div>
+       </div>
+    </van-popup>
+    <!-- 信心 -->
+    <van-action-sheet v-model="isShowSelectConfidence">
+      <div>
+        <van-picker show-toolbar :columns="pointArr"  @change="onChange" value-key="name" item-height="50px" @confirm="onConfirmConfidence" @cancel="isShowSelectConfidence = false">
+          <template #columns-top>
+              <div style="font-weight: 600;font-size: 0.34rem;text-align: center;">{{pointName}}</div>
+          </template>
+          <template #option="option">
+              <div class="flex-box-ce">
+                <van-rate v-model="option.value" allow-half :size="22" color="#ffd21e" void-icon="star" void-color="#eee" readonly />
+                <div style="padding-left: 0.2rem;">{{option.name}}</div>
+              </div>
+          </template>
+        </van-picker>
+      </div>
+    </van-action-sheet>
+
+    <!-- 选择时间 -->
+    <van-action-sheet v-model="isShowSelectTime">
+      <van-datetime-picker @cancel="isShowSelectTime=false" @confirm="selectConfirm" v-model="currentDate" type="date" :title="timeIndex==1? '开始时间':'截止时间'" :min-date="minDate" :max-date="maxDate"/>
+    </van-action-sheet>
+    <!-- 权重 -->
+    <van-popup v-model:show="isShowUpdateWeight" round position="bottom" :style="{ height: '90%', background: '#fff' }" @close="isShowUpdateWeight=false">
+      <div>
+        <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+          <div class="blue" @click="isShowUpdateWeight=false">取消</div>
+          <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">编辑权重</div>
+          <div class="blue" @click="confirmWeight">确定</div>
+        </header>
+        <div class="wInput">
+            <van-field v-for="(item, index) in krsList" :key="index" v-model="item.weight" input-align="right" @input="[(item.weight = item.weight.match(/\d+(\.\d{0,2})?/) ? item.weight.match(/\d+(\.\d{0,2})?/)[0] : '')]">
+                <template #label>
+                  <div>
+                    <span class="blue" style="padding-right: 3px;">KR{{index+1}}</span>
+                    <span>{{item.name}}</span>
+                  </div>
+                </template>
+                <template #right-icon> <span>%</span></template>
+            </van-field>
+            <div class="flex-box-ce flex-box-end" style="padding:0.24rem 0.32rem;">
+                <div class="updateprocess" @click="pingJun">平均权重</div>
+                <div class="fontColorC" style="margin-left: 0.2rem;font-size: 0.28rem;">总权重:{{getKrWeight}}%</div>
+            </div>
+        </div>
+      </div>
+    </van-popup>
+
+    <!-- 人员选择 -->
+    <EmployeeSelector  :isRequired="true" title="选择人员" :visible.sync="selectUser" @confirm="confirmUser" :can_select_dept="false" :multi="false" :selected.sync="selected_user"></EmployeeSelector>
+
+    <!-- 进度 -->
+    <Progress :visible.sync="isShwoUpdateProgress" :progressData="progressData" @confirm="update"></Progress>
+
+    <!-- 选择 -->
+    <van-action-sheet v-model="isShowbelong" :actions="scopeArr" @select="activebelong" cancel-text="取消" close-on-click-action/>
+    <!-- 评分 -->
+    <van-popup v-model:show="isShowUpdatePoint" round position="bottom" :style="{ height: '90%', background: '#fff' }" @close="isShowUpdatePoint=false">
+      <div>
+        <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+          <div class="blue" @click="isShowUpdatePoint=false">取消</div>
+          <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">KR评分</div>
+          <div class="blue" @click="confirmPoint">确定</div>
+        </header>
+        <div>
+          <van-field label="评分"  ref="input" input-align="right" placeholder="评分(0~10)" type="digit" v-model.trim="pointData.score"> <template #right-icon><span>分</span></template></van-field>
+          <van-field v-model="pointData.score_detail" rows="3" type="textarea" maxlength="500" placeholder="请输入评分说明" show-word-limit />
+          <van-cell title="@ta查看" is-link @click="openSelectUser(1)">
+              <div v-if="employees.length>0">
+                  <span v-for="(item, index) in employees" :key="index">{{ item.name }}<span v-if="employees.length - index > 1">,</span></span>
+              </div>
+              <span v-else class="input-ccc">请选择</span>
+          </van-cell>
+        </div>
+      </div>
+    </van-popup>
+    <!-- @人员 -->
+    <EmployeeSelector title="人员"  :visible.sync="selectUserAll" @confirm="confirmCreator" :selected.sync="selected_user_all"
+      :can_select_dept="false" :dept_multi="false" :append_body="true" :isShowDepts="false"
+    />
+
+    <!-- 可见范围 -->
+    <van-action-sheet v-model="isShowV" :actions="vArr" @select="activevArr" cancel-text="取消" close-on-click-action/>
+
+    <!-- 关联KR -->
+    <TargetSearch :visible.sync="isShwoKrSearch" :showSelectType="2" @confirm="ActiveRelevanceKr"></TargetSearch>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import {Circle,ActionSheet,Rate,Picker,DatetimePicker,Tab, Tabs, } from 'vant';
+Vue.use(Circle).use(ActionSheet).use(Rate).use(Picker).use(DatetimePicker).use(Tabs).use(Tab);
+
+import Evolve from '@/okr/components/public/Evolve';
+import Progress from '@/okr/components/public/Progress';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import {getOperation,taskStatus} from '@/okr/utils/auth';
+import TaskSearch from '@/okr/components/public/TaskSearch';
+import TargetSearch from '@/okr/components/public/TargetSearch';
+
+export default {
+  components:{Progress,EmployeeSelector,Evolve,TaskSearch,TargetSearch},
+  name: 'krDetail',
+  data() {
+    return {
+      taskStatus:taskStatus,
+      isShowbelong:false,
+      isShwoUpdateProgress:false,
+      isShowSelectConfidence:false,
+      isShowUpdatePoint:false,
+      isShowUpdateKr:false,
+      isShowSelectTime:false,
+      isShowUpdateWeight:false,
+      pointData:{kr_id:'',score:'',score_detail:'',to_employee_id:[]},
+      employees:[],
+      selectUserAll:false,
+      selected_user_all: { dept: [], employee: [] },//参与人员
+      selectUser:false,
+      selected_user: { dept: [], employee: [] },//参与人员
+      userInfo: this.$userInfo(),
+      currentDate:'',
+      timeIndex:1,
+      pointArr:[
+        {name:'1分',value:0.5,code:'1'},
+        {name:'2分',value:1,code:'1'},
+        {name:'3分',value:1.5,code:'2'},
+        {name:'4分',value:2,code:'2'},
+        {name:'5分',value:2.5,code:'3'},
+        {name:'6分',value:3,code:'3'},
+        {name:'7分',value:3.5,code:'4'},
+        {name:'8分',value:4,code:'4'},
+        {name:'9分',value:4.5,code:'5'},
+        {name:'10分',value:5,code:'5'},
+      ],
+      minDate: new Date(2020, 0, 1),
+      maxDate: new Date(2050, 10, 1),
+      columns:[],
+      krsList:[],
+      form:{
+        name:'',
+        owner_id:'',
+        owner_name:'',
+        confident:'',
+        start_date:'',//	是	string	开始日期,格式:2022-01-01
+        end_date:'',//	是	string	结束日期,格式:2022-01-01
+      },
+      scopeArr:[{
+          value: 1,
+          name:'KR 评分',
+          disabled: false
+        },
+        {
+          value: 2,
+          name:'更新完成度',
+          disabled: false
+        },
+        {
+          value: 3,
+          name:'编辑基本信息',
+          disabled: false
+        },
+        {
+          value: 4,
+          name:'编辑权重',
+          disabled: false
+        },
+        {
+          value: 5,
+          name:'删除KR',
+          color: '#f56c6c',
+          disabled: false
+        }
+      ],
+      processList: [],
+      kr_id:0,
+      krDetail:{owner_userInfo:{},process:0,publisher_userInfo:{},visible:1,process_conf:{}},
+      krOs:[],
+      progressData:{},
+      sumWeight:0,
+      isOperation:true,
+      pointNameArr:[
+        {name:'不可能完成',code:'1'},
+        {name:'很难完成,需要帮助',code:'2'},
+        {name:'有挑战,可以尝试',code:'3'},
+        {name:'有信心完成',code:'4'},
+        {name:'轻松完成',code:'5'},
+      ],
+      pointName:'不可能完成',
+      tabActive: 0,
+      tabs: [
+        {title:'计划',name:1,disabled:false},
+        {title:'进展',name:2,disabled:false},
+        {title:'',name:0,disabled:true}
+      ],
+      krsListAll:[],//包括任务
+      isShwoTaskSearch:false,
+
+      // 可见范围
+      isShowV:false,
+      vArr:[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}],
+      addTaskIndex:1,
+      selectKr:{},
+      isShwoKrSearch:false,
+    };
+  },
+  computed:{
+    getKrWeight(){
+      let sumWeight=0;
+      this.krsList.forEach(item=>{
+        sumWeight+=Number(item.weight)
+      })
+      this.sumWeight= Math.round(sumWeight)
+      return this.sumWeight
+    }
+  },
+  watch:{
+    tabActive(val){
+      if(val==1){
+        this.getkrTaskList();
+      }
+    },
+  },
+  mounted() {
+    if(this.$route.query.id){
+      this.kr_id=this.$route.query.id;
+      this.getKrDetail();
+    }
+  },
+  activated() {
+  	this.getkrTaskList();
+  },
+  methods: {
+    openDetail(item,type){
+      if(type==1){
+        this.$router.push({name: 'taskDetail', query: {id: item.id, readonly: 1}})
+      }else if(type==3) {
+        return
+        this.$router.push({name: 'projectDetail', query: {id: item.id}})
+      }
+    },
+    //执行
+    getkrTaskList(){
+      if(!this.krDetail.o_id){return false}
+      let data={
+        o_id:this.krDetail.o_id,//	是	string	目标id
+        kr_ids:this.kr_id,
+        plan_calc:1,
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/plan/list/o',data).then(res => {
+        let list=res.data.data.list;
+        list.forEach(e=>{
+          if(e.plans&&e.plans.length>0){
+            e.plans.forEach(item=>{
+              item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
+            })
+          }
+        })
+        this.krsListAll=list;
+      })
+    },
+    //关联母任务
+    ActiveRelevanceTask(item){
+        if(item.id){
+          this.$axiosUser('POST', '/api/pro/okr/plan/relate/other',{plan_id:item.id,target_type:2,target_id:this.kr_id}).then(res => {
+               this.getkrTaskList();
+          })
+        }
+    },
+    //关联项目
+    ActiveRelevanceKr(item){
+      this.$axiosUser('post', '/api/pro/okr/project/bind',{project_id:item.item.id,kr_id:this.selectKr.id}).then(res => {
+           this.getkrTaskList();
+      });
+    },
+    activevArr(item){
+      if(this.addTaskIndex==1){
+        if(item.value==1){
+          let data={
+            target_type:	2,//是	string	计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
+            target_id:this.selectKr.id,//是	integer	绑定的对象id 跟对象种类配对使用
+          }
+          this.$router.push({name: 'addTask', query: data})
+        }else{
+          this.$router.push({name: 'addProject', query: {kr_id:this.selectKr.id}})
+        }
+      }else{
+        if(item.value==1){
+            this.kr_id=this.selectKr.id;
+            this.isShwoTaskSearch=true;
+        }else{
+            this.isShwoKrSearch=true;
+        }
+      }
+    },
+    addTask(item,index){
+      this.addTaskIndex=index;
+      this.selectKr=item;
+      if(index==1){
+        this.vArr=[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}];
+      }else{
+        this.vArr=[{value: 1,name: '关联任务'},{value: 2,name: '关联项目'}];
+      }
+      this.isShowV=true;
+    },
+    returnSum(arr){
+      if(arr.length==0){return 0};
+      let sum=0;
+      arr.forEach(item=>{
+        if(item.composite_state==6){
+          sum++;
+        }
+      })
+      return sum
+    },
+    onChange(e,val) {
+      this.pointNameArr.some(item=>{
+        if(val.code==item.code){
+          this.pointName=item.name
+          return true
+        }
+      })
+    },
+    pingJun(){
+      let weight=Math.floor((100/(this.krsList.length)) * 100) / 100
+      this.krsList.forEach(item=>{
+         item.weight=weight
+      })
+    },
+    // 沟通
+    openCommunication(){
+      let data = {
+        item: JSON.stringify(this.krDetail),
+        target_type:2,
+        readonly: 1
+      }
+      this.$router.push({name: 'communication', query: data})
+    },
+    update(){
+      this.getKrDetail();
+    },
+    //更新完成度
+    updateProgress(){
+        let item=this.krDetail;
+        this.progressData={
+          target_type:2,
+          id:item.id,
+          process:Number(item.process),
+          risk_level:item.risk_level,
+          process_conf:item.process_conf,
+        }
+        this.isShwoUpdateProgress=true;
+    },
+    //目标详情
+    getTargetDateil(){
+      this.$axiosUser('get', '/api/pro/okr/public/obj/detail',{object_id:this.krDetail.o_id}).then(res => {
+        let data=res.data.data;
+        if(!data.can_edit){ //不可编辑权重
+          this.scopeArr.forEach(item=>{
+            if(item.value==4){item.disabled=true}
+          })
+        }
+      })
+    },
+    //KR详情
+    getKrDetail(){
+      this.krOs=[];
+      this.krDetail={owner_userInfo:{},process:0,publisher_userInfo:{},visible:1,process_conf:{}};
+      if(!this.kr_id){return false}
+      this.$axiosUser('get', '/api/pro/okr/public/kr/detail',{kr_id:this.kr_id}).then(res => {
+          let data=res.data.data;
+          data.owner_userInfo=this.$getEmployeeMapItem(data.owner_id);
+          data.publisher_userInfo=this.$getEmployeeMapItem(data.publisher_id);
+          data.day=this.$moment(data.end_time).diff(this.$moment().format('YYYY-MM-DD'), 'day');
+          this.isOperation=getOperation(data.publisher_id,data.owner_id);
+          if(data.statistics.sub_o_total>0){
+            this.getKrTarget(data.id);
+          }
+          this.krDetail=data;
+          if(!data.can_edit){ //不可编辑
+            this.scopeArr.forEach(item=>{
+              if(item.value==3){item.disabled=true}
+            })
+          }
+          if(!this.isOperation){ //完成度
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){item.disabled=true}
+            })
+          }
+          if(!data.can_score){ //不可评分
+            this.scopeArr.forEach(item=>{
+              if(item.value==1){item.disabled=true}
+            })
+          }
+          if(!data.can_delete){ //不可删除
+            this.scopeArr.forEach(item=>{
+              if(item.value==5){item.disabled=true}
+            })
+          }
+          this.getTargetDateil();
+      }).finally(()=>{
+          if(!this.tabActive){
+            this.tabActive=1;
+          }
+      })
+    },
+    //kr 子目标列表
+    getKrTarget(id){
+      this.$axiosUser('get', 'api/pro/okr/public/kr/sub/list', {kr_id:id}).then(res => {
+        this.krOs=res.data.data.os;
+      })
+    },
+    deletekr(){
+      if(this.krsList.length==0){
+        this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.krDetail.o_id}).then(res => {
+            let list=res.data.data.list;
+            if(list.length==1){
+              this.$toast('当前KR为最后一个,不能删除')
+              return false
+            }else{
+              this.$axiosUser('POST', '/api/pro/okr/kr/d',{kr_id:this.kr_id}).then(res => {
+                  setTimeout(()=>{
+                    this.$toast('已删除')
+                    this.$route_back()
+                  },500)
+              })
+            }
+        })
+        return false
+      }else if(this.krsList.length==1){
+        this.$toast('当前KR为最后一个,不能删除')
+        return false
+      }
+      this.$axiosUser('POST', '/api/pro/okr/kr/d',{kr_id:this.kr_id}).then(res => {
+            setTimeout(()=>{
+              this.$toast('已删除')
+              this.$route_back()
+            },500)
+      })
+    },
+    confirmWeight(){
+      let sumWeight=0;
+      let krs=[]
+      this.krsList.forEach(item=>{
+          sumWeight+=Number(item.weight);
+          krs.push({id:item.id,weight:item.weight*100})
+      })
+      sumWeight=Math.round(sumWeight);
+      // if(sumWeight!=100){
+      //    this.$toast("KR权重总和要为100");
+      //    return false
+      // }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_weight',{object_id:this.krDetail.o_id,kr:JSON.stringify(krs)}).then(res => {
+        if(this.krDetail.o_id){ //kr详情调整权重
+          this.getKrDetail();
+        }
+        this.isShowUpdateWeight=false
+      })
+    },
+    selectConfirm(val){
+      if(this.timeIndex==1){
+        this.form.start_date=this.$moment(this.currentDate).format('YYYY-MM-DD');
+      }else{
+        this.form.end_date=this.$moment(this.currentDate).format('YYYY-MM-DD');
+      }
+      this.isShowSelectTime = false;
+    },
+    onConfirmConfidence(v){
+      this.form.confident=v.value*2;
+      this.isShowSelectConfidence=false
+    },
+    confirmUpdateKr(){
+      if(this.form.start_date&&this.form.end_date){
+        if(this.form.start_date>this.form.end_date){
+          this.$toast("开始时间不能大于截止时间")
+          return false
+        }
+      }
+      this.form.kr_id=this.kr_id;
+      this.$axiosUser('post', '/api/pro/okr/kr/ms',this.form).then(res=>{
+         this.isShowUpdateKr=false
+         this.getKrDetail();
+      })
+    },
+    openTime(index){
+      this.timeIndex=index;
+      if(index==1){
+        this.currentDate=new Date(this.form.start_date);
+      }else{
+        this.currentDate=new Date(this.form.end_date);
+      }
+      this.isShowSelectTime = true;
+    },
+    confirmUser(item){
+       let employee=item.employee[0];
+       this.form.owner_id=employee.id;
+       this.form.owner_name=employee.name;
+    },
+    openSelectUser(index){
+      if(index==1){
+        this.selected_user_all.employee=this.employees;
+        this.selectUserAll=true;
+      }else if(index==2){
+        this.selected_user.employee=[{name:this.form.owner_name,id:this.form.owner_id}];
+        this.selectUser=true;
+      }
+    },
+    confirmCreator(item){
+      let employee=item.employee;
+      this.employees=employee;
+      let to_employee_id=employee.map(e=>{
+        return e.id
+      })
+      this.pointData.to_employee_id=to_employee_id.toString();
+    },
+    confirmPoint(){
+      if(this.pointData.score===''){
+        this.$toast("请输入分值");
+        return false
+      }
+      if(this.pointData.score>10){
+        this.$toast("请输入0~10之间数值");
+        return false
+      }
+      let params={
+        kr_id:this.kr_id,
+        score:Number(this.pointData.score),
+      }
+      if(this.employees.length>0){
+        params.to_employee_ids=this.pointData.to_employee_id
+      }
+      if(this.pointData.score_detail){
+        params.score_detail=this.pointData.score_detail;
+      }
+      this.$axiosUser('post', '/api/pro/okr/kr/score',params).then(res => {
+          this.isShowUpdatePoint=false;
+          this.$toast("已评分");
+          this.getKrDetail();
+      })
+    },
+
+    activebelong(item){
+      if(item.value==1){
+        this.pointData={kr_id:'',score:this.krDetail.score==-1? 0:this.krDetail.score,score_detail:this.krDetail.score_detail,to_employee_id:[]};
+        this.isShowUpdatePoint=true;
+        this.$nextTick(() => {
+            setTimeout(()=>{
+              this.$refs.input.focus();
+            },500)
+        });
+      }else if(item.value==2){
+        this.updateProgress();
+      }else if(item.value==3){
+        this.form={
+          name:this.krDetail.name,
+          owner_id:this.krDetail.owner_userInfo.id,
+          owner_name:this.krDetail.owner_userInfo.name,
+          start_date:this.krDetail.start_time,//	是	string	开始日期,格式:2022-01-01
+          end_date:this.krDetail.end_time,//	是	string	结束日期,格式:2022-01-01
+          confident:this.krDetail.confident
+        },
+        this.isShowUpdateKr=true;
+      }else if(item.value==4){
+        this.getKrList()
+      }else{
+        this.$dialog.confirm({ title:'删除', message: 'kr删除操作不可恢复!请谨慎操作'}).then(() => {
+            this.deletekr();
+        });
+      }
+    },
+    getKrList(){
+      this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.krDetail.o_id}).then(res => {
+          let list=res.data.data.list;
+          this.krsList =list;
+          this.isShowUpdateWeight=true;
+      })
+    },
+  },
+};
+</script>
+
+<style scoped lang="less">
+  .btns span {
+    width: 1.4rem;
+    text-align: center;
+    padding: 0.04rem 0.1rem;
+    color: #26A2FF;
+    margin-left: 0.2rem;
+    border: 0.02rem solid #26A2FF;
+    border-radius: 0.06rem;
+    font-size: 0.26rem;
+  }
+  .list-box {
+    // padding: 0.2rem;
+    font-size: 0.32rem;
+    background-color: #fff;
+    border-radius: 5px;
+    margin: 0 0.2rem;
+    margin-top: 0.2rem;
+  }
+  .shadow {
+    border-bottom: 1px solid #f5f7fa;
+  }
+  .footer {
+    padding: 0.14rem 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+  }
+  .footer .gt {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    border: 0.02rem solid #f1f1f1;
+    font-size: 0.32rem;
+  }
+  .footer i{
+    font-size: 0.6rem;
+  }
+  .footer .btn {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    // border: 0.02rem solid #26A2FF;
+    color: #fff;
+    text-align: center;
+    background: #26A2FF;
+    font-size: 0.32rem;
+  }
+.updateprocess {
+    border: 1px solid #409EFF;
+    padding: 2px 6px;
+    border-radius: 25px;
+    font-size: 12px;
+    cursor: pointer;
+    margin-left: 10px;
+    color: #409EFF;
+}
+.wInput /deep/ .van-field__label{
+  width: 5rem;
+}
+.o-content {
+  border-radius: 5px;
+  padding: 5px;
+  margin-left: 16px;
+}
+.o-content:hover {
+  background-color: #f7f8fa;
+}
+.o-content:hover .fontColorC {
+  display: block !important;
+  cursor: pointer;
+}
+.biaos {
+  width: 10px;
+  height: 10px;
+  background-color: #26a2ff;
+  border: 1px solid #fff;
+  border-radius: 100%;
+  box-shadow: 0 0 10px #26a2ff;
+  display: inline-block;
+  margin-right: 10px;
+}
+.biaos2 {
+  background-color: #ff9600;
+  box-shadow: 0 0 10px #ff9600;
+}
+.biaos3 {
+  background-color: #f56c6c;
+  box-shadow: 0 0 10px #f56c6c;
+}
+ .label{
+   color: #89919F;
+ }
+.box{
+   padding:0.24rem;
+   font-size: 0.3rem;
+}
+ .box .flex-box{
+   margin-top: 0.2rem;
+ }
+.title{
+  position: relative;
+  padding-left: 0.14rem;
+}
+.title::after {
+    content: "";
+    position: absolute;
+    width: 0.06rem;
+    height: 0.26rem;
+    border-radius: 0.06rem;
+    background-color: #26A2FF;
+    left: 0;
+    top: 0.07rem;
+}
+.scroller {
+  height: calc(100% - 1.76rem) !important;
+  overflow-y: auto;
+  background-color: #fff;
+}
+.header-message span{
+  padding-left: 5px;
+  padding-right: 10px;
+}
+.aite {
+  width: 1rem;
+  height: 1rem;
+  text-align: center;
+  line-height: 1rem;
+  font-size: 0.6rem;
+  cursor: pointer;
+  display: inline-block;
+  box-shadow: 0 0 3px #89919f;
+  border-radius: 100%;
+  background-color: #fff;
+  position: fixed;
+  z-index: 2;
+  bottom: 0.4rem;
+  right: 0.4rem;
+}
+.aite i {
+  font-size: 0.36rem;
+}
+.header {
+  padding: 0.24rem;
+  background-color: #fff;
+  border-bottom: 1px solid #f1f1f1;
+}
+</style>

+ 244 - 160
src/okr/view/target/target - 副本.vue → src/newPerformance/view/myTarget/myTarget.vue

@@ -1,46 +1,74 @@
 <template>
   <div style="height: 100%;">
     <van-nav-bar title="目标管理" left-text="返回" @click-left="$route_back" left-arrow>
-      <!-- <div slot="right" @click="selectGl = true" style="color: #fff;">更多</div> -->
+      <div slot="right" @click="isShowPopup = true" style="color: #fff;">筛选<van-icon name="list-switch" /></div>
     </van-nav-bar>
     <div class="all">
-      <div class="flex-box-ce header">
-        <div class="flex-1 flex-box-ce">
-          <userImage v-if="selectDataBox.type=='user'" :img_url="selectDataBox.img_url" :user_name="selectDataBox.name" fontSize="0.26" width="0.7rem" height="0.7rem"></userImage>
-          <img src="static/images/e66f.jpg" v-else style="width: 0.7rem; height: 0.7rem;"/>
-          <span style="padding-left: 0.1rem;font-size: 0.32rem;font-weight: 600;max-width: 1.8rem;padding-right: 0.1rem;" class="font-flex-word">{{ selectDataBox.name }}</span>
-          <!-- <van-icon name="play" class="fontColorD" style="transform:rotate(90deg)"/> -->
+      <div style="background-color: #fff;">
+        <div style="padding: 0.24rem;border-bottom: 1px solid #f1f1f1;" class="flex-box-ce flex-center-center" @click="openPanel()">
+          <icon name="YMPicker_item_icon" style="margin-right: 6px;width: 0.3rem;height: 0.3rem;" class="fontColorC"></icon>
+          <div>{{ dateParameter.year }}年</div>
+          <div style="margin: 0 6px;">{{ dateParameter.name }}</div>
+          <van-icon name="arrow-down" />
         </div>
-        <!-- 我的部门 -->
-<!--        <div v-else-if="selectGlVal==2" class="flex-1 flex-box-ce">
-          <template v-if="dept_list.length>0">
-              <span class="fontColorB font-flex-word" style="max-width: 3rem;padding-right: 0.1rem;font-size: 0.32rem;font-weight: 600;" @click="isShowDept=true">{{deptInfo.dept_name}}</span>
-              <van-icon name="play" class="fontColorD" style="transform:rotate(90deg)" @click="isShowDept=true"/>
-          </template>
-        </div> -->
-        <!-- 全公司 -->
-<!--        <div v-else class="flex-1 flex-box-ce">
-          <span class="fontColorB font-flex-word" style="max-width: 3rem;padding-right: 0.1rem;font-size: 0.32rem;font-weight: 600;" @click="isShowSelectDept=true" v-if="selected_dept.dept[0]">{{selected_dept.dept[0].dept_name}}</span>
-          <span v-else @click="isShowSelectDept=true" style="max-width: 3rem;padding-right: 0.1rem;font-size: 0.32rem;font-weight: 600;">全公司</span>
-          <van-icon name="play" class="fontColorD" style="transform:rotate(90deg)" @click="isShowSelectDept=true"/>
-        </div> -->
+        <!-- <van-tabs v-model="activeName">
+          <van-tab v-for="(item,index) in tabs" :title="item.title" :name="item.name" :key="index" v-if="item.isShow"></van-tab>
+        </van-tabs> -->
+      </div>
 
-        <div class="flex-box-ce search-box">
-          <div @click="openPanel()">{{ dateParameter.year }}年</div>
-          <div @click="openPanel()" style="margin: 0 6px;">{{ dateParameter.name }}</div>
+      <template v-if="activeName=='a'">
+        <!-- <div class="flex-box-ce flex-d-wrap" style="padding: 0 0.2rem;margin-top: 0.24rem;">
+          <div class="search-item" style="border-radius: 25px;font-size: 0.28rem;" @click="targetType=item.id" v-for="(item, index) in targetTypeArr" :key="index" :class="item.id==targetType? 'searchActive':''">{{ item.name }}</div>
+        </div> -->
+      </template>
+      <template v-if="activeName=='b'">
+        <div class="selector" @click="isShowDept=true">
+          <span>{{ deptInfo.dept_name }}</span>
           <van-icon name="arrow-down" />
-          <div @click="isShowPopup=true;" style="border-left: 1px solid #ccc;padding-left: 0.15rem;margin-left: 0.15rem;">
-            <icon name="tab_filter" width="0.3rem" height="0.3rem"></icon>
-          </div>
         </div>
-        <div @click="isShowSelectUser=true" class="flex-box flex-center-center" style="width: 0.6rem;height: 0.6rem;border: 1px solid #f1f1f1;border-radius: 50%;margin-left: 0.1rem;">
-          <van-icon name="cluster-o"  style="font-size: 0.36rem;"/>
+        <div style="overflow-x: scroll;margin: 0.2rem;">
+            <div class="flex-box-ce">
+                <div
+                :class="{userActive:ownerUserInfo.id==item.id}"
+                @click="ownerUserInfo = item"
+                style="padding:0.14rem;border-radius: 5px;"
+                class="flex-box-v flex-center-center"
+                v-for="(item,index) in userList" :key="index">
+                  <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                  <div class="clamp userName">{{item.name}}</div>
+                </div>
+            </div>
         </div>
-      </div>
-      <div class="flex-box-ce flex-d-wrap" style="padding: 0 0.2rem;" v-if="selectGlVal==1&&selectDataBox.id==userId">
-        <div class="search-item" style="border-radius: 25px;font-size: 0.28rem;" @click="targetType=item.id" v-for="(item, index) in targetTypeArr" :key="index" :class="item.id==targetType? 'searchActive':''">{{ item.name }}</div>
-      </div>
-      <div class="scroller" :class="{scroller2:selectGlVal==1&&selectDataBox.id==userId}">
+      </template>
+      <template v-if="activeName=='c'">
+        <div style="overflow-x: scroll;margin: 0.2rem;">
+            <div class="flex-box-ce">
+                <div class="flex-box-v flex-center-center" style="padding: 0.14rem;" @click="openGz">
+                   <div class="addUser" style="">+</div>
+                   <div class="clamp userName">设置</div>
+                </div>
+
+                <div
+                :class="{userActive:follUserInfo.id==item.id}"
+                @click="follUserInfo=item"
+                style="padding:0.14rem;border-radius: 5px;"
+                class="flex-box-v flex-center-center"
+                v-for="(item,index) in followList" :key="index">
+                  <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                  <div class="clamp userName">{{item.name}}</div>
+                </div>
+            </div>
+        </div>
+      </template>
+      <template v-if="activeName=='d'">
+        <div class="selector" @click="isShowSelectUser=true">
+          <span v-if="selectDataBox.name">{{ selectDataBox.name }}</span>
+          <span v-else class="fontColorC">选择人员或部门</span>
+          <van-icon name="arrow-down" />
+        </div>
+        <div style="height: 0.2rem;"></div>
+      </template>
+      <div class="scroller" :class="{scroller2:activeName=='b',scroller3:activeName=='c',scroller4:activeName=='d'}">
         <scroller ref="scroller" :isInitRefresh="false" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢" :list="targetList">
           <div class="list-box" v-for="(item,index) in targetList" :key="index" >
               <div class="flex-box" @click="openDetail(item,1)">
@@ -54,7 +82,7 @@
                         <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;">{{$getEmployeeMapItem(item.owner_id).name}}</span>
                         <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.composite_state==6">已结束</span>
                         <template v-else>
-                            <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.process_ut">{{item.process_ut}} 更新</span>
+                          <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.process_ut">{{item.process_ut}} 更新</span>
                         </template>
                         <span class="flex-1"></span>
                         <div class="progress"><div class="progress-inner" :class="{bjYellow:item.risk_level==2,bjRed:item.risk_level==3}" :style="{width:item.process>100? '100%':item.process+'%'}"></div></div>
@@ -69,39 +97,14 @@
                   <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:krItem.risk_level==2,red:krItem.risk_level==3}">{{ krItem.process }}%</span>
               </div>
           </div>
-          <div v-if="targetList.length==0" style="text-align: center;margin-top: 2rem;" class="fontColorC">
-              <template v-if="selectGlVal!=2">
-                <span>未找到相关的目标</span>
-                <div @click="$router.push({name: 'addTarget'})" style="margin: 0 auto;margin-top: 0.8rem;background-color: #26A2FF;color: #fff;border-radius: 25px;width: 2rem;padding: 0.1rem 0;font-size: 0.28rem;">添加目标</div>
-              </template>
-              <template v-else>
-                <template v-if="dept_list.length==0">
-                    <span>暂无所属部门</span>
-                </template>
-                <template v-else>
-                  <span>未找到相关的目标</span>
-                  <div @click="$router.push({name: 'addTarget'})" style="margin: 0 auto;margin-top: 0.8rem;background-color: #26A2FF;color: #fff;border-radius: 25px;width: 2rem;padding: 0.1rem 0;font-size: 0.28rem;">添加目标</div>
-                </template>
-              </template>
+          <div v-if="targetList.length == 0" style="text-align: center;margin-top: 2rem;" class="fontColorC">
+              <span>未找到相关的目标</span>
           </div>
         </scroller>
-        <div class="aite" @click="$router.push({name: 'addTarget'})">+</div>
       </div>
 
-      <EmployeeSelector  title="选择部门"
-        :close_clear_data="false" :can_select_employee="false"
-        :dept_multi="false" @confirm="confirmDept" :visible.sync="isShowSelectDept"
-        :selected.sync="selected_dept" :append_body="true" :isShowDepts="true"
-      ></EmployeeSelector>
-
-      <!-- 人员选择 -->
-      <EmployeeDeptSelector
-        title="选择人员"
-        :visible.sync="isShowSelectUser"
-        @confirm="confirmUser"
-        :selectDataBox.sync="selectDataBox">
-      </EmployeeDeptSelector>
     </div>
+
     <!-- 选择部门 -->
     <van-dialog v-model="isShowDept" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
       <van-radio-group v-model="deptInfo.dept_id">
@@ -112,21 +115,23 @@
         </div>
       </van-radio-group>
     </van-dialog>
-    <!-- 选择范围 -->
-    <van-dialog v-model="selectGl" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
-      <van-radio-group v-model="selectGlVal">
-        <div v-for="(item, index) in selectGlType" :key="index">
-          <van-radio :name="item.value" @click="clickGlConfirm(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
-            <span style="margin-left:.3rem">{{ item.label }}</span>
-          </van-radio>
-        </div>
-      </van-radio-group>
-    </van-dialog>
+
+    <!-- 周期选择 -->
     <van-action-sheet v-model="pullonThePanel" :closeable="false">
       <div class="content">
         <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel=false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
       </div>
     </van-action-sheet>
+
+    <!-- 人员选择 -->
+    <EmployeeDeptSelector
+      title="选择人员"
+      :visible.sync="isShowSelectUser"
+      @confirm="confirmUser"
+      :selectDataBox.sync="selectDataBox">
+    </EmployeeDeptSelector>
+
+    <!-- 筛选 -->
     <van-popup v-model="isShowPopup" position="right" style="height: 100%;left: 20%;">
       <div style="position: relative;height: 100%;">
         <div style="border-bottom: 1px solid #f1f1f1;font-size: 16px;font-weight: 700;height: 0.92rem;line-height: 0.92rem;padding: 0 0.2rem;">高级筛选</div>
@@ -136,12 +141,12 @@
               <div class="search-item" @click="belong_type=item.id" v-for="(item, index) in targetArr" :key="index" :class="item.id==belong_type? 'searchActive':''">{{ item.name }}</div>
             </div>
         </div>
-        <div style="padding: 10px;">
+       <!-- <div style="padding: 10px;">
           <div style="margin-bottom: 15px;font-size: 0.32rem;">状态</div>
             <div class="flex-box-ce flex-d-wrap">
               <div class="search-item" @click="sortId=item.id" v-for="(item, index) in sortArr" :key="index" :class="item.id==sortId? 'searchActive':''">{{ item.name }}</div>
             </div>
-        </div>
+        </div> -->
         <div style="position: fixed;bottom: 0.2rem;left: 0.2rem;right: 0.2rem;">
           <div class="btn" @click="isShowPopup=false">确认</div>
         </div>
@@ -152,13 +157,13 @@
 
 <script>
 import Vue from 'vue';
-import {Picker,Popup,Circle,Icon} from 'vant';
+import {Picker,Popup,Circle,Icon,Tab, Tabs,} from 'vant';
 import { _debounce, _throttle } from '@/utils/auth';
 import { getBelongType,getColumns,cycleTypeArr} from '@/okr/utils/auth';
 
 import EmployeeSelector from '@/components/EmployeeSelector';
 import EmployeeDeptSelector from '@/components/EmployeeDeptSelector';
-Vue.use(Picker).use(Popup).use(Circle).use(Icon);
+Vue.use(Picker).use(Popup).use(Circle).use(Icon).use(Tabs).use(Tab)
 export default {
   components:{EmployeeSelector,EmployeeDeptSelector},
   name: 'Target',
@@ -174,22 +179,15 @@ export default {
       page_size:10,
       cycleTypeArr:cycleTypeArr(true),
       value:5,
-      selectGl: false,
-      selectGlVal: 1,
-      selectGlType: [// 选择时间选项
-        { value: 1, label: '我的目标' },
-        { value: 2, label: '我的部门' },
-        { value: 3, label: '公司全部' },
-      ],
       userId:this.$userInfo().id,
       userInfo: this.$userInfo(),
       dept_list:this.$userInfo().employee_detail.dept_list,
-      deptInfo:{},
+      deptInfo:this.$userInfo().employee_detail.dept_list[0]? this.$userInfo().employee_detail.dept_list[0]:{},
       isShowDept:false,
       targetTypeArr: [{ name: '我负责的', id: 1 }, { name: '我参与的', id: 2 }, { name: '我关注的', id: 3 }],
       targetType:1,
       dateParameter: {
-        year: this.$moment().format('YYYY'),
+        year: '',
         cycle_type: 0,
         dateId: 1,
         name: '全部周期'
@@ -211,10 +209,13 @@ export default {
       targetList:[],
       isShowSelectUser:false,
       selected_user: { dept: [], employee: [] } ,//传入已选部门
-      isShowSelectDept:false,
-      selected_dept: { dept: [], employee: [] } ,//传入已选部门
-      isShowSearch:false,
       selectDataBox:{},
+      tabs:[{title:'我的目标',name:'a',isShow:true},{title:'我的部门',name:'b',isShow:true},{title:'关注的人',name:'c',isShow:true},{title:'全公司',name:'d',isShow:true}],
+      activeName: 'd',
+      userList:[],
+      ownerUserInfo:{},
+      followList:[],
+      follUserInfo:{},
     };
   },
   watch:{
@@ -230,39 +231,75 @@ export default {
     },
     targetType(){
       this.pullDown();
-    }
+    },
+    ownerUserInfo(){
+      this.pullDown();
+    },
+    follUserInfo(){
+      this.pullDown();
+    },
+    activeName(val){
+      if(this.activeName=='a'){
+        this.pullDown();
+      }
+      if(this.activeName=='d'){
+        this.pullDown();
+      }
+      if(this.activeName=='b'){
+        this.get_employee_list();
+      }
+      if(this.activeName=='c'){
+        this.getGzUserList();
+      }
+    },
   },
   methods: {
-    openPanel(){
-      this.pullonThePanel=true;
-      this.$nextTick(() => {
-        this.theEchoVanPicker()
-      })
+    openGz(){
+      this.$router.push({name: 'attentionList',query:{index:1}})
     },
-    confirmDept(data) {
-      this.selected_dept.dept=data.dept
-      this.pullDown();
+    getGzUserList(){
+      this.$axiosUser('get', '/api/pro/okr/follow', { type:1 }).then(res=>{
+         this.followList = res.data.data.list;
+         if(this.followList.length>0){
+           this.follUserInfo=this.followList[0];
+         }else{
+           this.follUserInfo={};
+           this.pullDown();
+         }
+      })
     },
     confirmDept2(data){
       this.deptInfo=JSON.parse(JSON.stringify(data));
-      this.pullDown();
+      this.get_employee_list();
       this.isShowDept=false;
     },
+    get_employee_list() {
+      this.$axiosUser('get', '/api/pro/employee/list', { dept_id:this.deptInfo.dept_id }, 'v2').then(res => {
+        let list=res.data.data.list;
+        list.unshift({name:'全部',id:0})
+        this.userList=list;
+        if(this.userList.length>0){
+          this.ownerUserInfo=this.userList[0];
+        }
+      });
+    },
+
+    openPanel(){
+      this.pullonThePanel=true;
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+
     confirmUser(item){
-      if(item.is){
-        setTimeout(()=>{
-          this.$router.push({name: 'attentionList',query:{index:item.index}})
-        },500)
-      }else{
-        this.selectDataBox=item;
-        this.pullDown();
-      }
+      this.selectDataBox = item;
+      this.pullDown();
     },
     openDetail(item,type){
       if(type==1){
-        this.$router.push({name: 'targetDetail', query: {id: item.id}})
+        this.$router.push({name: 'myTargetDetail', query: {id: item.id}})
       }else {
-        this.$router.push({name: 'krDetail', query: {id: item.id}})
+        this.$router.push({name: 'myKrDetail', query: {id: item.id}})
       }
     },
     // 考核包搜索
@@ -287,29 +324,12 @@ export default {
     theEchoVanPicker() { // 回显
       this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
     },
-    clickGlConfirm(item) {
-      this.selectGlVal = item.value;
-      if(item.value==2){//我的部门
-        if(this.dept_list.length>0){
-          this.deptInfo=JSON.parse(JSON.stringify(this.dept_list[0])) ;
-
-        }else{
-          this.deptInfo={};
-          this.targetList=[];
-        }
-      }
-      this.pullDown();
-      this.selectGl = false;
-    },
-    getList(isUpdatePage,callback){
-      if(this.selectGlVal==2&&this.dept_list.length==0){
-        callback && callback(hasMore)
-        return false
-      }
 
+    getList(is,callback){
       let hasMore = false
+      is? '':this.page=1;
       let params = {
-        page:isUpdatePage? this.page:1,
+        page:is? this.page:1,
         page_size: this.page_size,
         cycle_type:this.dateParameter.cycle_type,
         year:this.dateParameter.year,
@@ -317,33 +337,33 @@ export default {
         quarter:0,
         half_year:0,
         month:0,
-        sort_ct:2
+        sort_ct:2,
+        ids: []
       };
-      !isUpdatePage? this.page=1:'';
-
-      // if(this.selectGlVal==1){ //我的目标
-      //   let userId=this.userInfo.id;
-      //   if(userId==this.userId){
-      //     this.targetType==1? params.owner_id=userId:this.targetType==2? params.joiner_id=userId:params.follower_id=userId;
-      //   }else{
-      //     params.owner_id=userId
-      //   }
-      // }else if(this.selectGlVal==2){//我的部门
-      //   params.dept=this.deptInfo.dept_id;
-      // }else if(this.selectGlVal==3){//全部部门
-      //   if(this.selected_dept.dept[0]){
-      //       params.dept=this.selected_dept.dept[0].dept_id;
-      //   }
-      // }
-      if(this.selectDataBox.type=='user'){
-        let userId=this.selectDataBox.id;
-        if(userId==this.userId){
-          this.targetType==1? params.owner_id=userId:this.targetType==2? params.joiner_id=userId:params.follower_id=userId;
+      if(!params.year) delete params.year
+      if(!params.quarter) delete params.quarter
+      if(!params.half_year) delete params.half_year
+      if(!params.month) delete params.month
+      params.ids = this.$route.query.ids || "[]";
+      if(this.activeName=='a'){ //我的目标
+        this.targetType==1? params.owner_id=this.userId:this.targetType==2? params.joiner_id=this.userId:params.follower_id=this.userId;
+      }else if(this.activeName=='b'){//我的部门
+        params.dept=this.deptInfo.dept_id;
+        params.owner_id=this.ownerUserInfo.id;
+      }else if(this.activeName=='c'){//我关注的
+        if(this.follUserInfo.id){
+          params.owner_id=this.follUserInfo.id;
         }else{
-          params.owner_id=userId
+          this.targetList=[];
+          callback && callback(hasMore)
+          return false
+        }
+      }else if(this.activeName=='d'){//全公司
+        if(this.selectDataBox.type == 'user'){
+          params.owner_id = this.selectDataBox.id;
+        }else if(this.selectDataBox.type=='dept'){
+          params.dept=this.selectDataBox.id;
         }
-      }else{
-        params.dept=this.selectDataBox.id;
       }
 
       if(this.sortId){//状态
@@ -358,7 +378,7 @@ export default {
       if(this.dateParameter.cycle_type==4){
         params.month=this.dateParameter.dateId
       }
-      this.$axiosUser('get', '/api/pro/okr/obj/list', params).then(res => {
+      this.$axiosUser('get', '/api/pro/okr/public/obj/list', params).then(res => {
           let list=res.data.data.list
           list.forEach(item=>{
             item.krs.forEach(e=>{
@@ -384,25 +404,83 @@ export default {
       this.page++;
       this.getList(true,done)
     },
+    getUnitList(){
+      this.$axiosUser('get', '/api/pro/okr/public/kr/unit_list').then(res => {
+    	let data=res.data.data;
+    	data.reverse()
+       this.$setCache('unitList',data)
+      })
+    },
   },
   created() {
-    let data=this.$userInfo()
-    data.type='user';
-    this.selectDataBox=data
+    this.getUnitList();
     this.columns.forEach((e,index)=>{
       if(e.value==this.dateParameter.year){
         this.selectPftiTheEcho[0]=index
       }
     })
-     this.getList();
+    this.tabs=[
+      {title:'我的目标',name:'a',isShow:true},
+      {title:'我的部门',name:'b',isShow:!this.$userInfo().is_okr_manager&&this.dept_list.length>0},
+      {title:'关注的人',name:'c',isShow:true},
+      {title:'全公司',name:'d',isShow:true},
+    ]
+    this.getList();
   },
   activated() {
-    this.getList();
+    if(this.activeName=='c'){
+      this.getGzUserList();
+    }else{
+      this.pullDown();
+    }
   },
 };
 </script>
 
 <style scoped lang="less">
+.addUser{
+    font-size: .6rem;
+    padding: 0.2rem;
+    border: 0.02rem dashed #89919f;
+    text-align: center;
+    height: 0.4rem;
+    width: 0.4rem;
+    line-height: .4rem;
+    color: #89919f;
+    border-radius: 2rem;
+}
+.userName{
+    font-size: 0.28rem;
+    width: 1rem;
+    text-align: center;
+    color: #89919F;
+}
+.userActive{
+  background-color: #E9F0FD;
+}
+.userActive .userName{
+ color: #26A2FF;
+}
+.selector {
+  z-index: 1;
+  display: flex;
+  justify-content: center;
+  width: 100%;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.28rem;
+  border-top: 1px solid #f1f1f1;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+  span {
+    max-width: 3.5rem;
+    overflow: hidden;
+  }
+}
 .aite{
     width: 1rem;
     height: 1rem;
@@ -474,11 +552,17 @@ export default {
   margin-bottom: 0.24rem;
 }
 .scroller{
-   height: calc(100% - 1.3rem);
+   height: calc(100% - 2.75rem);
    position: relative;
 }
 .scroller2{
-   height: calc(100% - 2rem);
+   height: calc(100% - 4.5rem);
+}
+.scroller3{
+   height: calc(100% - 3.7rem);
+}
+.scroller4{
+   height: calc(100% - 2.84rem);
 }
 .all {
   height: calc(100% - 0.92rem) !important;

+ 945 - 0
src/newPerformance/view/myTarget/targetDetail.vue

@@ -0,0 +1,945 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="目标详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all-box">
+      <template v-if="targetDetail.visible==1">
+        <header class="header">
+          <div class="flex-box">
+            <!-- 目标综合状态 1-未开始 2-负责人未接收 3-运行中 4-已延期 5-已达标(进度大于等于100) 6-已结束 -->
+<!--            <span class="status" v-if="targetDetail.composite_state==1">未开始</span>
+            <span class="status" v-if="targetDetail.composite_state==2">未接收</span>
+            <span class="status" v-if="targetDetail.composite_state==3">进行中</span>
+            <span class="status" v-if="targetDetail.composite_state==4">已延期</span>
+            <span class="status" v-if="targetDetail.composite_state==5">已达标</span> -->
+            <span class="status" v-if="targetDetail.composite_state==6">已结束</span>
+            <div class="flex-1" style="font-weight: 600;padding: 0 0.2rem;padding-left: 0.1rem;">{{targetDetail.name}}</div>
+          </div>
+          <div class="flex-box-ce" style="margin: 0.16rem 0;">
+            <div class="progress"><div class="progress-inner" :class="{bjYellow:targetDetail.risk_level==2,bjRed:targetDetail.risk_level==3}" :style="{width:targetDetail.process>100? '100%':targetDetail.process+'%'}"></div></div>
+            <span style="padding-left: 0.1rem;font-size: 0.24rem;" class="blue" :class="{orange:targetDetail.risk_level==2,red:targetDetail.risk_level==3}">{{ targetDetail.process }}%</span>
+            <template v-if="targetDetail.process != targetDetail.process_last">
+              <span v-if="targetDetail.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ targetDetail.updatePro }}%</span>
+              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ targetDetail.updatePro }}%</span>
+            </template>
+            <div class="flex-1"></div>
+            <div class="orange" v-if="targetDetail.score>=0">{{targetDetail.score}}</div>
+          </div>
+          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+            <span>{{$getEmployeeMapItem(targetDetail.owner_id).name}}</span>
+            <span style="margin: 0 0.1rem;padding: 0 0.1rem;border-left: 1px solid #f1f1f1;border-right: 1px solid #f1f1f1;">
+
+                {{targetDetail.belong_type==2? (dept_tree[targetDetail.dept_id]? dept_tree[targetDetail.dept_id].name:''):getBelongType(targetDetail.belong_type).name}}
+            </span>
+            <span class="flex-1">{{targetDetail.year}}年 {{targetDetail.dateStr}}</span>
+          </div>
+          <template v-if="targetDetail.kr_id">
+            <div class="flex-box" v-if="targetDetail.p_kr" style="font-size: 0.26rem;margin-top: 0.2rem;border-top: 1px solid #f1f1f1;padding-top: 0.2rem;height: 0.36rem;">
+                <span class="fontColorC">对齐目标:</span>
+                <div class="flex-1 font-flex-word">{{targetDetail.p_kr.name}}</div>
+            </div>
+          </template>
+          <template v-else-if="targetDetail.o_id">
+            <div class="flex-box" v-if="targetDetail.p_objectives" style="font-size: 0.26rem;margin-top: 0.2rem;border-top: 1px solid #f1f1f1;padding-top: 0.2rem;height: 0.36rem;">
+                <span class="fontColorC">对齐目标:</span>
+                <div class="flex-1 font-flex-word">{{targetDetail.p_objectives.name}}</div>
+            </div>
+          </template>
+        </header>
+        <van-tabs v-model="tabActive" class="shadow"><van-tab :title="item" v-for="(item, index) in tabs" :key="index"></van-tab></van-tabs>
+        <div class="scroller">
+          <scroller ref="scroller">
+            <template v-if="tabActive == 0">
+              <div class="list-box" v-for="(item, index) in krsList" :key="index" @click="openDetail(item,2)">
+                <div class="clamp2" style="margin-bottom: 5px;">{{item.name}}</div>
+                <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                  <span>{{$getEmployeeMapItem(item.owner_id).name}}</span>
+                  <span class="padding-l-r flex-box-ce">{{item.weight}}%</span>
+                  <span class="flex-box-ce" style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;"><van-icon name="star" class="yellow" />{{item.confident}}分</span>
+                  <van-circle :key="item.id" layer-color="#E5E9F2" v-model="item.currentRate" :color="item.risk_level==2? '#FF9600':item.risk_level==3? '#f56c6c':' #2879ff'" :rate="item.process"  :stroke-width="120" size="20px"/>
+                  <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:item.risk_level==2,red:item.risk_level==3}">{{ item.process }}%</span>
+                </div>
+              </div>
+
+            </template>
+            <template v-if="tabActive == 1">
+              <div class="list-box" v-for="(item, index) in krsListAll" :key="index">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;border-bottom: 1px solid #f1f1f1;padding-bottom: 0.2rem;">
+                  <div class="blue" style="font-size: 0.26rem;font-weight: 600;margin-right: 0.1rem;">KR{{index+1}}</div>
+                  <div class="flex-1 font-flex-word" style="padding-right: 0.2rem;font-size: 0.3rem;">{{item.name}}</div>
+                  <!-- <span style="font-size: 0.26rem;" v-if="item.plans.length>0">计划任务<span class="blue">{{returnSum(item.plans)}}</span>/<span>{{item.plans.length}}</span></span> -->
+                </div>
+                <div style="padding:0 0.1rem;">
+
+                  <template v-if="item.projects.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index3) in item.projects" :key="task_item.id" @click="openDetail(task_item,3)">
+                        <van-icon name="paid" class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"/>
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD')}} 截止</span>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <template v-if="item.plans.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index2) in item.plans" :key="index2" @click="openDetail(task_item,1)">
+                        <van-icon :name="taskStatus(task_item.composite_state).icon"
+                        class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"
+                        :class="(task_item.day<=0&&$moment(task_item.end_date).format('YYYY-MM-DD')!=$moment().format('YYYY-MM-DD')) ? 'red':''"
+                        />
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD HH:mm')}} 截止</span>
+                            <template v-if="task_item.statistics.plan_total">
+                              <van-icon name="orders-o" />
+                              <span style="font-size: 0.26rem;">
+                                <span class="blue">{{task_item.statistics.plan_finish}}</span>/<span>{{task_item.statistics.plan_total}}</span>
+                              </span>
+                            </template>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <div v-if="item.projects.length==0&&item.plans.length==0" style="text-align: center;margin: 0.2rem 0;font-size: 0.28rem;" class="fontColorC">用“项目/任务”推动目标达成,合理规划安排工作</div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive == 3">
+              <div style="height: 100%;background-color: #fff;padding: 0.2rem;border-top: 1px solid #f1f1f1;">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;">
+                  <div class="flex-1">
+                    <div class="user-title">发布人</div>
+                    <div class="flex-box-v" style="text-align: center;width: 1.06rem">
+                      <userImage :id="targetDetail.publisher_id" :user_name="$getEmployeeMapItem(targetDetail.publisher_id).name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;" class="font-flex-word">{{ $getEmployeeMapItem(targetDetail.publisher_id).name }}</div>
+                    </div>
+                  </div>
+                  <div class="flex-1">
+                    <div class="user-title">负责人</div>
+                    <div class="flex-box-ce">
+                      <div style="text-align: center;width: 1.06rem">
+                        <userImage :img_url="targetDetail.owner_userInfo.img_url" :user_name="targetDetail.owner_userInfo.name" width="0.7rem" height="0.7rem"></userImage>
+                        <div style="font-size: 0.26rem;padding: 0.1rem 0;" class="font-flex-word">{{ targetDetail.owner_userInfo.name }}</div>
+                      </div>
+                      <div class="zj" v-if="isUpdate" @click="openSelectUser(1)">转交</div>
+                    </div>
+                  </div>
+                </div>
+                <div style="margin-bottom: 0.2rem;">
+                  <div class="user-title">参与人员</div>
+                  <div class="flex-box-ce flex-d-wrap">
+                    <div class="flex-box-v" style="margin-right: 0.2rem;text-align: center;margin-bottom: 0.2rem;position: relative;"  v-for="(item, index) in targetDetail.joiner_employee_items"  :key="index" >
+                      <userImage :img_url="item.img_url" :user_name="item.name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;width: 1.06rem" class="font-flex-word">{{ item.name }}</div>
+                      <!-- <van-icon name="clear" class="delete-user red" /> -->
+                      <div class="zj2" v-if="isUpdate" @click="joinerUpdate(false,item.id)">删除</div>
+                    </div>
+                    <div class="addUser" v-if="isUpdate" @click="openSelectUser(2)">+</div>
+                  </div>
+                </div>
+                <div style="margin-bottom: 0.2rem;">
+                  <div class="user-title">关注人员</div>
+                  <div class="flex-box-ce flex-d-wrap">
+                    <div class="flex-box-v" style="margin-right: 0.2rem;text-align: center;margin-bottom: 0.2rem;" v-for="(item, index) in targetDetail.follower_employee_items" :key="index">
+                      <userImage :img_url="item.img_url" :user_name="item.name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;width: 1.06rem" class="font-flex-word">{{ item.name }}</div>
+                      <div class="zj2" v-if="isUpdate" @click="deleteFollower(false,item.id)">删除</div>
+                    </div>
+                    <div class="addUser" v-if="isUpdate" @click="openSelectUser(3)">+</div>
+                  </div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive == 2">
+              <div style="padding: 0.2rem;background-color: #fff;border-top: 1px solid #f1f1f1;">
+                <div class="flex-box-ce flex-d-wrap">
+                  <div class="search-item" @click="targetType = item.id"  v-for="(item, index) in targetTypeArr" :key="index"  :class="item.id == targetType ? 'searchActive' : ''">{{ item.name }}</div>
+                  <div class="flex-1"></div>
+                </div>
+                <template v-if="targetType==1">
+                  <div v-for="(item, index) in processList" :key="index" style="margin-top: 0.24rem;">
+                    <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                      <span class="biaos" :class="{ biaos2: item.risk_level == 2, biaos3: item.risk_level == 3 }"></span>
+                      <div class="black flex-1" style="font-weight: 700;font-size: 16px;">
+                      {{ item.process }}%
+                        <template v-if="item.process != item.process_last">
+                          <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                          <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                        </template>
+                      </div>
+                      <span class="fontColorC" style="font-size: 0.26rem;">{{ item.create_time }}</span>
+                    </div>
+                    <div class="flex-box o-content">
+                      <pre v-if="item.content" class="flex-1 fontColorB" style="margin: 0px;">{{ item.content }}</pre>
+                      <div v-else class="flex-1 fontColorD">暂无内容</div>
+                    </div>
+                  </div>
+                  <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processList.length==0">目标进展一目了然?赶快更新完成度吧</div>
+                </template>
+                <template v-if="targetType==2">
+                    <div v-for="(item, index) in processData.kr" :key="index" style="margin-top: 0.24rem;">
+                      <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                        <span class="biaos" :class="{biaos2:item.process_info&&item.process_info.risk_level==2,biaos3:item.process_info&&item.process_info.risk_level==3}"></span>
+                        <span class="okr-index">KR{{ index + 1 }}</span>
+                        <div class="font-flex-word fontColorC flex-1" style="padding-right:0.2rem;font-size: 0.28rem;">{{item.name}}</div>
+                        <div class="black" style="font-weight: 700;font-size: 16px;">
+                            {{ item.process }}%
+                            <template v-if="item.process != item.process_last">
+                              <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                            </template>
+                        </div>
+                      </div>
+                      <div v-if="item.process_info">
+                        <div class="o-content fontColorB">
+                            <pre v-if="item.process_info.content" style="margin: 0px;">{{item.process_info.content}}</pre>
+                            <span v-else class="fontColorD" style="font-size: 13px;">暂未更新</span>
+                        </div>
+                        <div style="padding-left: 0.34rem;font-size: 12px;" class="fontColorC">{{item.process_info.create_time}}</div>
+                      </div>
+                      <div class="pre fontColorD" v-else style="font-size: 13px;padding: 5px 0.5rem;">暂未更新</div>
+                    </div>
+                    <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processData.kr==0">暂无进展</div>
+                </template>
+                <template v-if="targetType==3">
+                    <div v-for="(item, index) in processData.objectives" :key="index" style="margin-top: 0.24rem;">
+                      <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                        <span class="biaos" :class="{biaos2:item.process_info&&item.process_info.risk_level==2,biaos3:item.process_info&&item.process_info.risk_level==3}"></span>
+                        <div class="huan"><span></span></div>
+                        <div class="font-flex-word fontColorC flex-1" style="padding-right:0.2rem;font-size: 0.28rem;">{{item.name}}</div>
+                        <div class="black" style="font-weight: 700;font-size: 16px;">
+                            {{ item.process }}%
+                            <template v-if="item.process != item.process_last">
+                              <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                            </template>
+                        </div>
+                      </div>
+                      <div v-if="item.process_info">
+                        <div class="o-content fontColorB">
+                            <per v-if="item.process_info.content" style="margin: 0px;">{{item.process_info.content}}</per>
+                            <span v-else class="fontColorD" style="font-size: 13px;">暂未更新</span>
+                        </div>
+                        <div style="padding-left: 0.34rem;font-size: 12px;" class="fontColorC">{{item.process_info.create_time}}</div>
+                      </div>
+                      <div class="pre fontColorD" v-else style="font-size: 13px;padding: 5px 0.5rem;">暂未更新</div>
+                    </div>
+                    <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processData.objectives==0">暂无进展</div>
+                </template>
+              </div>
+            </template>
+            <div style="height: 3rem;"></div>
+          </scroller>
+          <footer class="footer">
+            <div class="flex-box-ce">
+               <van-icon name="chat-o" @click="openCommunication" style="margin-left: 0.2rem;font-size:0.6rem;" class="fontColorC"/>
+            </div>
+          </footer>
+        </div>
+      </template>
+
+       <van-row type="flex" justify="space-around" class="c" v-else>
+          <van-col span="24">
+            <div style="text-align: center;margin-top: 2rem;margin-bottom: 1rem;">
+              <img src='static/images/noPeople.png' style="width: 3.5rem;"/>
+            </div>
+            <p class="text_center fontColorC">暂无查看权限</p>
+          </van-col>
+        </van-row>
+    </div>
+    <van-dialog v-model="isShowProcess" show-cancel-button :beforeClose="subContent">
+      <van-cell-group>
+        <van-field v-model="processInfo.content" rows="4"  class="textarea-box" type="textarea" maxlength="500" placeholder="请输入进展与障碍" show-word-limit/>
+      </van-cell-group>
+    </van-dialog>
+
+    <!-- 进度 -->
+    <Progress :visible.sync="isShwoUpdateProgress" :progressData="progressData" @confirm="update"></Progress>
+    <!-- 添加KR -->
+    <AddKr :o_id="Number(o_id)" :isShowWeight="false" :visible.sync="isShowAddKr" @confirm="confirmAddkr"></AddKr>
+    <!-- 详情 -->
+    <van-action-sheet v-model="isShowbelong" :actions="scopeArr" @select="activebelong" cancel-text="取消" close-on-click-action/>
+    <!-- 修改基本信息 -->
+    <UpdateTarget :visible.sync="isShwoUpdateDetail" :targetDetail="targetDetail" :o_id="Number(o_id)" @confirm="getTargetDateil"></UpdateTarget>
+    <!-- 关联任务 -->
+    <TaskSearch :visible.sync="isShwoTaskSearch" @confirm="ActiveRelevanceTask"></TaskSearch>
+    <!-- 人员选择 -->
+    <EmployeeSelector :multi="false" :isRequired="true" key="selected_user" title="选择人员" :visible.sync="selectUser" @confirm="confirmUser" :can_select_dept="false" :selected.sync="selected_user"></EmployeeSelector>
+
+    <!-- 可见范围 -->
+    <van-action-sheet v-model="isShowV" :actions="vArr" @select="activevArr" cancel-text="取消" close-on-click-action/>
+
+    <!-- 关联KR -->
+    <TargetSearch :visible.sync="isShwoKrSearch" :showSelectType="2" @confirm="ActiveRelevanceKr"></TargetSearch>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { Tab, Tabs, Circle,ActionSheet } from 'vant';
+import UpdateTarget from '@/okr/components/public/UpdateTarget';
+import TaskSearch from '@/okr/components/public/TaskSearch';
+import AddKr from '@/okr/components/public/AddKr';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import Progress from '@/okr/components/public/Progress';
+import TargetSearch from '@/okr/components/public/TargetSearch';
+
+import {taskStatus,getBelongType,getDateStr,getOperation} from '@/okr/utils/auth';
+Vue.use(Tabs).use(Tab).use(Circle).use(ActionSheet);
+export default {
+  components:{UpdateTarget,AddKr,TaskSearch,EmployeeSelector,Progress,TargetSearch},
+  data() {
+    return {
+      targetDetail:{visible:1},
+      processInfo:{},
+      getBelongType:getBelongType,
+      taskStatus:taskStatus,
+      userInfo: this.$userInfo(),
+      tabActive: 0,
+      tabs: ['OKRs', '计划', '进展','成员'],
+      targetTypeArr: [{ name: '目标进展', id: 1 }, { name: 'KR进展', id: 2 }, { name: '子目标进展', id: 3 }],
+      targetType: 1,
+      isShowbelong:false,
+      isShwoTaskSearch:false,
+      scopeArr:[{value: 0, name:'关注目标', disabled: false},{value: 1, name:'编辑基本信息',disabled: false},{value: 2,name:'结束目标',disabled: false},{value: 4,name:'复制目标',disabled: false},{value: 3,name:'删除目标',color: '#f56c6c',disabled: false}],
+      processList: [],
+      processData:{kr:[],objectives:[]},
+      isShwoUpdateDetail:false,
+      isShowAddKr:false,
+      userId:0,
+      krName:'',
+      weight:0,
+      o_id:0,
+      kr_id:0,
+      krsList:[],
+      krsListAll:[],//包括任务
+      isFollower:false,//是否关注
+      isUpdate:false,
+      selectUser:false,
+      selected_user: { dept: [], employee: [] } ,//传入已选部门
+      isShwoUpdateProgress:false,
+      progressData:{},
+      isShowProcess:false,
+      isOperation:true,
+      dept_tree:{},
+
+      // 可见范围
+      isShowV:false,
+      vArr:[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}],
+      addTaskIndex:1,
+      selectKr:{},
+      isShwoKrSearch:false,
+    };
+  },
+  watch:{
+    isFollower(val){
+      if(val){
+        this.scopeArr.forEach(item=>{
+          if(item.value==0){item.name='取消关注'}
+        })
+      }else{
+        this.scopeArr.forEach(item=>{
+          if(item.value==0){item.name='关注目标'}
+        })
+      }
+    },
+    tabActive(val){
+      if(val==0){
+        this.getKrList();
+      }else if(val==1){
+        this.getkrTaskList();
+      }else if(val==2){
+        this.getProcess();
+      }
+    }
+  },
+  methods: {
+    //关联项目
+    ActiveRelevanceKr(item){
+      this.$axiosUser('post', '/api/pro/okr/project/bind',{project_id:item.item.id,kr_id:this.selectKr.id}).then(res => {
+       this.getkrTaskList();
+      });
+    },
+    activevArr(item){
+      if(this.addTaskIndex==1){
+        if(item.value==1){
+          let data={
+            target_type:	2,//是	string	计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
+            target_id:this.selectKr.id,//是	integer	绑定的对象id 跟对象种类配对使用
+          }
+          this.$router.push({name: 'addTask', query: data})
+        }else{
+          this.$router.push({name: 'addProject', query: {kr_id:this.selectKr.id}})
+        }
+      }else{
+        if(item.value==1){
+            this.kr_id=this.selectKr.id;
+            this.isShwoTaskSearch=true;
+        }else{
+            this.isShwoKrSearch=true;
+        }
+      }
+    },
+    openDetail(item,type){
+
+      if(type==1){
+        this.$router.push({name: 'myTargetDetail', query: {id: item.id}})
+      }else if(type==2){
+        this.$router.push({name: 'myKrDetail', query: {id: item.id}})
+      }else if(type==3){
+        // this.$router.push({name: 'projectDetail', query: {id: item.id}})
+        return
+      }
+    },
+    subContent(action, done){
+       if (action == 'confirm') {
+         this.$axiosUser('post', '/api/pro/okr/process/content',{p_id: this.processInfo.id, content: this.processInfo.content}).then(res => {
+           this.getProcess();
+           this.isShowProcess = false;
+         })
+         done()
+       }else{
+         done()
+       }
+    },
+    compileContent(item){
+      this.processInfo = JSON.parse(JSON.stringify(item));
+      this.isShowProcess = true;
+    },
+    update(){
+      this.getTargetDateil();
+      this.getProcess();
+    },
+    // 沟通
+    openCommunication(){
+      let data = {
+        item: JSON.stringify(this.targetDetail),
+        target_type: 1,
+        readonly: 1
+      }
+      this.$router.push({name: 'communication', query:data})
+    },
+    // 获取部门列表
+    returnArr(list,arr){
+      list.forEach(item=>{
+        arr[item.id]=item
+        if(item.children.length>0){
+          this.returnArr(item.children,arr)
+        }
+      })
+    },
+    // 获取部门列表
+    get_department_list() {
+      this.$axiosUser('get','/api/pro/department/tree','','v2').then((res) => {
+          let list=res.data.data.list
+          let dept_tree={};
+          this.returnArr(list,dept_tree)
+          this.dept_tree=dept_tree
+      })
+    },
+    //更新完成度
+    updateProgress(){
+      let item=this.targetDetail;
+      this.progressData={
+        target_type:1,
+        id:item.id,
+        o_id:item.id,
+        process:Number(item.process),
+        risk_level:item.risk_level,
+        process_conf:item.process_conf,
+      }
+      this.isShwoUpdateProgress=true;
+    },
+    //获取最新字段
+    getProcess(){
+      let axios= this.$axiosUser('get', '/api/pro/okr/public/process/list', {target_type:1,target_id:this.o_id,page:1,page_size:100})
+      let axios2= this.$axiosUser('get', '/api/pro/okr/public/process/sub', {target_type:1,target_id:this.o_id})
+      Promise.all([axios,axios2]).then(res => {
+          let data=res[1].data.data
+          data.objectives=this.updatePro(data.objectives);
+          data.kr=this.updatePro(data.kr);
+          this.processData=data;
+          this.processList=this.updatePro(res[0].data.data.list)
+      })
+    },
+    updatePro(arr){
+      arr.forEach(item=>{
+         item.updatePro=Math.abs(item.process-item.process_last).toFixed(2);
+         item.isUpdatePro=item.process-item.process_last
+      })
+      return arr;
+    },
+    openSelectUser(index){
+      this.selectUserIndex=index;
+      this.selectUser=true;
+    },
+    confirmUser(data) {
+      let user=data.employee[0]
+      if(this.selectUserIndex==1){
+        let params={object_id:this.targetDetail.id,owner_id:user.id,}
+        this.$axiosUser('POST', 'api/pro/okr/obj/change_owner', params).then(res => {
+            this.getTargetDateil();
+        })
+      }else if(this.selectUserIndex==2){
+        this.joinerUpdate(true,user.id);
+      }else{
+        this.deleteFollower(true,user.id);
+      }
+    },
+    //参与者
+    joinerUpdate(is,id){
+      let data={
+        object_id:this.o_id,
+        joiner_id:id,
+        action:is? 'add':'remove',
+      }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_joiner',data).then(res => {
+          this.getTargetDateil();
+      })
+    },
+    //关注者
+    deleteFollower(is,id){
+      let data={
+        object_id:this.o_id,
+        employee_id:id,
+        action:is? 'add':'remove',
+      }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_focus',data).then(res => {
+          this.getTargetDateil();
+      })
+    },
+    //关联母任务
+    ActiveRelevanceTask(item){
+        if(item.id){
+          this.$axiosUser('POST', '/api/pro/okr/plan/relate/other',{plan_id:item.id,target_type:2,target_id:this.kr_id}).then(res => {
+               this.getkrTaskList();
+          })
+        }
+    },
+    addTask(item,index){
+      this.addTaskIndex=index;
+      this.selectKr=item;
+      if(index==1){
+        this.vArr=[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}];
+      }else{
+        this.vArr=[{value: 1,name: '关联任务'},{value: 2,name: '关联项目'}];
+      }
+      this.isShowV=true;
+    },
+    confirmAddkr(item){
+      this.$axiosUser('POST','api/pro/okr/kr/create',item).then(res => {
+         this.$toast("已添加");
+         this.getKrList()
+      })
+    },
+    activebelong(item){
+      if(item.value==0){//关注
+        this.$axiosUser('POST','/api/pro/okr/obj/follow',{o_id:this.o_id}).then(res => {
+           this.$toast(this.isFollower? "已取消":'已关注');
+           this.getTargetDateil();
+        })
+      }else if(item.value==1){//编辑
+        this.isShwoUpdateDetail=true;
+      }else if(item.value==2){//结束目标
+        if(item.name=='结束目标'){
+          this.$dialog.confirm({ title:'结束', message: '确定要结束目标吗?'}).then(() => {
+            this.$axiosUser('post', '/api/pro/okr/obj/to_finish', { object_id: this.o_id }).then(res => {
+                this.getTargetDateil()
+            });
+          });
+        }else{
+          this.$axiosUser('POST', '/api/pro/okr/obj/to_start',{object_id:this.o_id}).then(res => {
+             this.getTargetDateil()
+          })
+        }
+      }else if(item.value==3){//删除
+        this.$dialog.confirm({ title:'删除', message: '目标删除操作不可恢复!请谨慎操作'}).then(() => {
+          this.$axiosUser('post', '/api/pro/okr/public/obj/d', { o_id: this.o_id }).then(res => {
+              this.$toast("已删除");
+              setTimeout(()=>{
+                this.$route_back()
+              },500)
+          });
+        });
+      }else if(item.value==4){//复制目标
+        this.$router.push({name: 'copyTarget', query: {id:this.o_id}})
+      }
+    },
+    returnSum(arr){
+      if(arr.length==0){return 0};
+      let sum=0;
+      arr.forEach(item=>{
+        if(item.composite_state==6){
+          sum++;
+        }
+      })
+      return sum
+    },
+    //执行
+    getkrTaskList(){
+	  if(!this.o_id){
+		  return false
+	  }
+      let data={
+        o_id:this.o_id,//	是	string	目标id
+        plan_calc: 1
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/plan/list/o',data).then(res => {
+        let list=res.data.data.list;
+        list.forEach(e=>{
+          if(e.plans&&e.plans.length>0){
+            e.plans.forEach(item=>{
+              item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
+            })
+          }
+        })
+        this.krsListAll=list;
+      })
+    },
+    //OKRs
+    getKrList(){
+      this.krsList=[];
+      this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.o_id}).then(res => {
+          let list=res.data.data.list;
+          this.krsList=list
+      })
+    },
+    //目标详情
+    getTargetDateil(){
+      this.isFollower=false;
+      this.$axiosUser('get', '/api/pro/okr/public/obj/detail',{object_id:this.o_id}).then(res => {
+          let data=res.data.data;
+          data.dateStr=getDateStr(data)
+          data.owner_userInfo=this.$getEmployeeMapItem(data.owner_id);//负责人
+          data.special_employee_items=data.special_employee_ids.map(e=>{ //可见人员
+              return this.$getEmployeeMapItem(e)
+          })
+          data.joiner_employee_items=data.joiner_ids.map(e=>{//参与人员
+              return this.$getEmployeeMapItem(e)
+          })
+          data.follower_employee_items=data.follower_ids.map(e=>{//关注者
+              return this.$getEmployeeMapItem(e)
+          })
+          if(data.follower_ids.length>0){
+            data.follower_ids.some(e=>{//关注者
+                if(e==this.userInfo.id){
+                   this.isFollower=true;
+                   return true
+                }
+            })
+          }
+          if(data.finish_status!=0){
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){item.name='重启目标'}
+            })
+          }else{
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){ item.name='结束目标' }
+            })
+          }
+
+          // 权限[{value: 0, name:'关注目标'},{value: 1, name:'编辑基本信息'},{value: 2,name:'结束目标'},{value: 3,name:'删除目标',color: '#f56c6c'}],
+          if(!data.can_edit){ //不可编辑
+            this.scopeArr.forEach(item=>{
+              if(item.value==1){
+                item.disabled=true
+              }
+              if(item.value==2&&item.name=='结束目标'){
+                item.disabled=true
+              }
+              // if(item.value==4){
+              //   item.disabled=true
+              // }
+            })
+          }
+          if(!data.can_delete){ //不可删除
+            this.scopeArr.forEach(item=>{
+              if(item.value==3){item.disabled=true}
+            })
+          }
+
+          this.isOperation=getOperation(data.publisher_id,data.owner_id);
+          this.targetDetail=this.updatePro([data])[0];
+      })
+    },
+  },
+  mounted() {
+    this.get_department_list();
+    if(this.$route.query.id){
+      this.o_id=this.$route.query.id;
+      this.getTargetDateil();
+      this.getKrList();
+    }
+  },
+  activated() {
+  	 this.getkrTaskList();
+  }
+};
+</script>
+
+<style scoped lang="less">
+  .textarea-box /deep/ .van-field__control{
+    max-height: 400px;
+  }
+  .footer {
+    padding: 0.14rem 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+  }
+  .footer .gt {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    border: 0.02rem solid #f1f1f1;
+    font-size: 0.32rem;
+  }
+  .footer i{
+    font-size: 0.6rem;
+  }
+  .footer .btn {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    // border: 0.02rem solid #26A2FF;
+    color: #fff;
+    text-align: center;
+    background: #26A2FF;
+    font-size: 0.32rem;
+  }
+  .huan{
+    position: relative;
+    width: 0.4rem;
+    height: 0.4rem;
+    border-radius: 100%;
+    background-color: #E9F1FE;
+    box-sizing: border-box;
+    text-align: center;
+    margin-right: 0.1rem;
+  }
+  .huan span{
+    border: 2px solid #26A2FF;
+    border-radius: 100%;
+    width: 0.16rem;
+    height: 0.16rem;
+    display: inline-block;
+  }
+  .status{
+    position: relative;
+    // top: 1px;
+    font-size: 0.24rem;
+    border-radius: 15px;
+    line-height:0.32rem;
+    color: #26A2FF;
+    height: 0.32rem;
+    padding: 0px 0.04rem;
+    border: 1px solid #26A2FF;
+  }
+  .aite{
+      width: 1rem;
+      height: 1rem;
+      text-align: center;
+      line-height: 1rem;
+      font-size: 0.6rem;
+      cursor: pointer;
+      display: inline-block;
+      box-shadow: 0 0 3px #89919f;
+      border-radius: 100%;
+      background-color: #fff;
+      position: absolute;
+      z-index: 2;
+      bottom: 0.4rem;
+      right: 0.4rem;
+  }
+  .aite i{
+    font-size: 0.36rem;
+  }
+.o-content {
+  border-radius: 5px;
+  padding: 5px;
+  margin-left: 0.24rem;
+  margin-bottom: 5px;
+  font-size: 0.28rem;
+}
+.o-content:hover {
+  background-color: #f7f8fa;
+}
+.o-content:hover .fontColorC {
+  display: block !important;
+  cursor: pointer;
+}
+.biaos {
+  width: 0.14rem;
+  height: 0.14rem;
+  background-color: #26a2ff;
+  border: 1px solid #fff;
+  border-radius: 100%;
+  box-shadow: 0 0 0.14rem #26a2ff;
+  display: inline-block;
+  margin-right: 0.14rem;
+}
+.biaos2 {
+  background-color: #ff9600;
+  box-shadow: 0 0 0.14rem #ff9600;
+}
+.biaos3 {
+  background-color: #f56c6c;
+  box-shadow: 0 0 0.14rem #f56c6c;
+}
+.add-jz {
+  width: 1.4rem;
+  text-align: center;
+  padding: 0.04rem 0.08rem;
+  color: #26a2ff;
+  border: 1px solid #26a2ff;
+  border-radius: 25px;
+  cursor: pointer;
+  font-size: 0.26rem;
+}
+.search-item {
+  padding: 0.06rem 0.1rem;
+  background-color: #f7f8fa;
+  color: #89919f;
+  width: 1.3rem;
+  text-align: center;
+  margin-right: 0.2rem;
+  border-radius: 3px;
+  font-size: 0.3rem;
+  border-radius: 25px;
+  font-size: 0.26rem;
+}
+.searchActive {
+  color: #26A2FF;
+  background-color: #e9f0fd;
+}
+.delete-user {
+  position: absolute;
+  right: -4px;
+  top: -4px;
+  padding: 0;
+}
+.btns span {
+  width: 1.4rem;
+  text-align: center;
+  padding: 0.04rem 0.1rem;
+  color: #26A2FF;
+  margin-right: 0.2rem;
+  border: 0.02rem solid #26A2FF;
+  border-radius: 0.06rem;
+  font-size: 0.26rem;
+}
+.user-title {
+  font-size: 0.28rem;
+  // font-weight: 700;
+  color: #89919f;
+  margin: 0.2rem 0;
+}
+.addUser {
+  font-size: 0.6rem;
+  padding: 0.2rem;
+  border: 1px dashed #89919f;
+  text-align: center;
+  height: 0.4rem;
+  width: 0.4rem;
+  line-height: 0.4rem;
+  color: #89919f;
+  border-radius: 100px;
+}
+.zj {
+  width: 1rem;
+  text-align: center;
+  color: #26A2FF;
+  border: 0.02rem solid #26A2FF;
+  border-radius: 0.04rem;
+  font-size: 0.24rem;
+}
+.zj2 {
+  width: 1rem;
+  text-align: center;
+  color: #f56c6c;
+  border: 0.02rem solid #f56c6c;
+  border-radius: 0.04rem;
+  font-size: 0.24rem;
+}
+.addKr {
+  padding: 0.2rem;
+  font-size: 0.3rem;
+  background-color: #fff;
+  border-radius: 5px;
+  text-align: center;
+  margin: 0 0.2rem;
+  margin-top: 0.2rem;
+}
+.padding-l-r {
+  padding: 0 0.1rem;
+  border-left: 1px solid #f1f1f1;
+  border-right: 1px solid #f1f1f1;
+  margin: 0 0.1rem;
+}
+.scroller {
+  height: calc(100% - 3.58rem) !important;
+  position: relative !important;
+}
+.list-box {
+  padding: 0.2rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0.2rem;
+  margin-top: 0.2rem;
+}
+.shadow {
+  border-bottom: 1px solid #f5f7fa;
+}
+/deep/ .van-tabs__line {
+  width: 20px !important;
+  background-color: #26A2FF;
+}
+/deep/ .van-tab--active {
+  color: #26A2FF;
+}
+.all-box {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+}
+.progress {
+  border-radius: 100px;
+  background-color: #ebeef5;
+  overflow: hidden;
+  position: relative;
+  vertical-align: middle;
+  height: 0.2rem;
+  width: 3rem;
+}
+.progress-inner {
+  width: 0%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding-top: 1px;
+  height: 100%;
+  background-image: linear-gradient(to right, #99bbff 0%, #2879ff 100%);
+  border-radius: 100px;
+  color: #fff;
+  white-space: nowrap;
+  transition: width 0.6s ease;
+}
+  .bjYellow{
+    background-image: linear-gradient(to right, #fedf86 0%, #FF9600 100%);
+  }
+  .bjRed{
+    background-image: linear-gradient(to right, #FEA2A2 0%, #F16060 100%);
+  }
+.header {
+  padding: 0.24rem;
+  background-color: #fff;
+  z-index: 9999;
+  // background-image: linear-gradient(to bottom, #26A2FF 0%, #99BBFF 100%);
+}
+</style>

+ 467 - 0
src/newPerformance/view/navhome/me.vue

@@ -0,0 +1,467 @@
+<template>
+  <div class="all" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="考核详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="overall">
+      <VanSkeleton :skeLoad="skeletonLoad" v-if="isYou">
+        <scroller>
+          <div class="title">
+            <span>考核信息</span>
+            <span class="more-btn" @click="isShowMore = true">
+              查看更多
+              <van-icon name="arrow" />
+            </span>
+         </div>
+
+
+          <div class="list-box">
+
+            <div class="flex-box-ce" style="margin-bottom: 0.2rem;">
+              <div v-if="showUserInfo && showUserInfo.id">
+                <userImage class="about-me__avatar" :id="showUserInfo.id" :img_url="showUserInfo.img_url"  :user_name="showUserInfo.name"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+              </div>
+              <div class="user-info">
+                <div style="margin-bottom: 0.05rem; color: #000;">{{ showUserInfo.name }}</div>
+                <template v-if="showDeptList && showDeptList.length > 0">
+                  <span v-for="item in showDeptList" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
+                </template>
+              </div>
+            </div>
+
+            <div class="examine-info">
+              <div class="info-item flex-box-ce">
+                考核周期:&nbsp;&nbsp;&nbsp; <div class="cycle-type">{{ cycleType | formatCycleType }}</div>
+              </div>
+              <div class="info-item">
+                <van-icon name="calendar" />考核时间:&nbsp;&nbsp;&nbsp;{{ startTime | formatDate }} 至 {{ endTime | formatDate }}
+              </div>
+              <div class="info-item">
+                考核等级:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ levelName || '-' }}</span>
+              </div>
+              <div class="info-item">
+                考核评分:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ score == undefined  || score == null || score == '' ? '-' : score }}</span>
+              </div>
+            </div>
+
+          </div>
+
+          <div class="title">指标列表</div>
+
+          <div class="list-box">
+            <div class="examine-info" v-for="(item, index) in indicators" :key="item.reviewIndicatorId">
+              <div class="tips">
+                <div class="tip-item" v-if="item.okrs && item.okrs.length > 0" @click="goMyTarget(item.okrs)">过程跟踪</div>
+                <div class="tip-item" @click="goDetails(item)">处理详情</div>
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  审批阶段:
+                </div>
+                <div v-if="item.businessStatus !== 'end'" class="review-node">
+                  {{ item.businessStatus | filterNodeStatus }}
+                </div>
+                <div v-else class="review-node" style="background-color: #FF9600;">
+                  {{ item.businessStatus | filterNodeStatus }}
+                </div>
+              </div>
+
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  指标:
+                </div>
+                {{ item.title }}
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  目标:
+                </div>
+                {{ item.target || '-' }} {{ item.target && item.unit ?  item.unit : '' }}
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  结果值:
+                </div>
+                {{ item.result || '-' }}
+              </div>
+
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  权重:
+                </div>
+                {{ item.weight || '-' }}
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  单位:
+                </div>
+                {{ item.unit || '-' }}
+              </div>
+
+              <div class="info-item" v-if="item.content">
+                <div class="info-item-title">
+                  规则:
+                </div>
+                <div class="bg-gray">
+                  {{ item.content }}
+                </div>
+              </div>
+
+              <div class="info-item" v-if="item.resultFiles && item.resultFiles.length > 0">
+                <div class="info-item-title" style="width: 2rem;">
+                  结果值附件:
+                </div>
+                <div class="bg-gray">
+                  <div v-for="(item, index) in item.resultFiles">
+                    附件{{ index + 1}}
+                  </div>
+                </div>
+
+              </div>
+
+              <div v-if="index !== indicators.length - 1" class="line"></div>
+            </div>
+          </div>
+
+          <OperateLogVue v-if="detailInfo" :reviewId="reviewId" />
+
+          <div style="width: 100%; height: 1rem;">
+
+          </div>
+        </scroller>
+      </VanSkeleton>
+      <noData content="无考核记录" v-else></noData>
+      <van-popup v-model:show="isShowMore" round position="bottom" :style="{ height: '80%' }">
+        <More v-if="isShowMore" :employee-id="employeeId" @onConfirm="chooseExamineItem"/>
+      </van-popup>
+    </div>
+  </div>
+</template>
+<script>
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import OperateLogVue from '@/newPerformance/components/public/OperateLog.vue'
+import More from '@/newPerformance/components/public/More.vue'
+import moment from 'moment';
+  export default {
+    components: {
+      VanSkeleton,
+      OperateLogVue,
+      More
+    },
+
+  data() {
+    return {
+      skeletonLoad: true,
+      isYou: true,
+      isShowMore: false,
+      userInfo: this.$userInfo(),
+      showUserInfo: {
+        id: '',
+        name: '',
+        img_url: ''
+      },
+      showDeptList: [],
+      meList: [],
+      title: "",
+      startTime: "",
+      endTime: "",
+      cycleType: "",
+      score: 0,
+      status: '',
+      levelName: '', // 考核详情信息
+      detailInfo: null,
+      indicators: [],
+      reviewId: '',
+      employeeId: "",
+      performList: [],
+      params: {
+        keyword: '',
+        page: 1,
+        pageSize: 10,
+        startDate: '',
+        endDate: '',
+        employeeId: ''
+      },
+    };
+  },
+
+  filters: {
+    filterNodeStatus(v) {
+      if (v === 'start') return '开始'
+      if (v === 'target_confirm') return '确认目标'
+      if (v === 'result_input') return '录入结果值'
+      if (v === 'score_self') return '自评'
+      if (v === 'score_each_other') return '互评'
+      if (v === 'score') return '评分'
+      if (v === 'review') return '审批'
+      if (v === 'cc') return '抄送'
+      if (v === 'end') return '结束'
+    },
+
+    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 '--'
+    },
+  },
+
+
+  methods: {
+    getTemplateList() {
+      let that = this
+      let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
+      // const startOfMonth = moment().startOf('month').format('YYYY-MM-DD') // 当月第一天
+      // const endOfMonth = moment().endOf('month').format('YYYY-MM-DD'); // 当月最后一天
+      let requestdata;
+      if (that.cycleType == '-1') requestdata = { ...that.params }
+      else requestdata = { ...that.params, cycleType: that.cycleType }
+      requestdata.employeeId = that.employeeId
+      that.$axiosUser('get', url, requestdata).then(res => {
+          let { data: { data: { list, total }, code } } = res;
+          if (code == 1) {
+            if (list && list.length > 0) {
+              this.isYou = true
+              that.performList = list;
+              let { reviewId } = that.performList[0] || '';
+              if (reviewId) that.getDetails(reviewId);
+            }else {
+              this.isYou = false
+              that.performList = [];
+            }
+          }
+      });
+    },
+
+
+    getDetails(reviewId) {
+        // reviewId = reviewId ? reviewId : 24
+        // this.loading = true
+        let url = `/performance/statistics/review/info/${this.$userInfo().site_id}/${reviewId}`
+        this.$axiosUser('get', url).then(res => {
+            this.skeletonLoad = false;
+            let { data: { reviewId, title, indicators, employeeId, levelName, startTime, endTime, cycleType, score, status }, code } = res.data
+            this.reviewId = reviewId
+            if (code == 1) {
+                this.detailInfo = res.data.data;
+                console.log(!this.detailInfo)
+                if(!this.detailInfo) {
+                  this.isYou = false
+                  return
+                } else {
+                  this.isYou = true
+                  this.title = title || ''
+                  this.cycleType = cycleType || ''
+                  this.score = score
+                  this.status = status || ''
+                  this.startTime = startTime || ''
+                  this.endTime = endTime || ''
+                  this.levelName = levelName || ''
+                  this.indicators = indicators.reverse() || [];
+                  this.showUserInfo = this.$getEmployeeMapItem(employeeId);
+                  this.showDeptList = this.$getEmployeeMapItem(employeeId).employee_detail.dept_list;
+                  // 处理附件列表
+                  if (this.tableData && this.tableData.length > 0) {
+                      let resultFiles = []
+                      this.tableData.forEach(item => {
+                          if (item.flow.nodes && item.flow.nodes.length > 0) {
+                              let resultInputNode = item.flow.nodes[1] // 取到结果值节点
+                              if (resultInputNode.tasks && resultInputNode.tasks.length > 0) {
+                                  resultInputNode.tasks.forEach(task => {
+                                      if (task.files && task.files.length > 0) {
+                                          task.files.forEach(file => {
+                                              resultFiles.push(file)
+                                          })
+                                      }
+                                  })
+                                  item.resultFiles = resultFiles
+                              }
+                          }
+                      })
+                  }
+                }
+
+            }
+
+        });
+    },
+
+    goMorePage() {
+      this.$router.push("/more")
+    },
+
+    goMyTarget(okrs) {
+      this.$router.push({name: 'myTarget', query: {ids: JSON.stringify(okrs)}});
+    },
+
+    goDetails(item) {
+      let { reviewId, reviewIndicatorId, flow: { nodes } } = item
+      let showData = {
+        nodes,
+        reviewId: this.reviewId,
+        reviewIndicatorId
+      }
+      this.$router.push({ path: "/handleDetails", query: {showData: JSON.stringify(showData)} })
+    },
+
+    chooseExamineItem(data) {
+      this.isShowMore = false;
+      this.detailInfo = null;
+      this.skeletonLoad = true;
+      this.reviewId = data.reviewId
+      this.employeeId = data.employeeId
+      this.getDetails(this.reviewId);
+    },
+
+  },
+
+
+
+  activated() {
+    this.reviewId = this.$route.query.reviewId
+    this.employeeId = this.$route.query.employeeId
+    this.employeeId = this.employeeId ? this.employeeId : this.userInfo.id
+    console.log(this.employeeId );
+    if(this.reviewId) {
+      this.getDetails(this.reviewId);
+    }else {
+      this.getTemplateList()
+    }
+  },
+
+
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  width: 100%;
+  height: 100%;
+  position: relative !important;
+  background-color: #f5f7fa;
+  box-sizing: border-box;
+
+  .overall {
+    height: calc(100% - 0.92rem) !important;
+    position: relative;
+    overflow-y: scroll;
+  }
+}
+
+
+
+.title {
+  margin: 0.2rem 0;
+  padding: 0 0.2rem;
+  box-sizing: border-box;
+  font-size: 0.3rem;
+  font-weight: 600;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  .more-btn {
+    font-weight: normal;
+    color: #0597ff;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    i {
+      margin: 0.06rem 0 0 0.02rem;
+    }
+  }
+
+}
+
+
+
+
+.list-box {
+  width: 96%;
+  padding: 0.24rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  box-sizing: border-box;
+  margin: 0.24rem auto;
+  .add-task-title {
+    font-weight: 600;
+    font-size: 0.32rem;
+  }
+
+  .user-info {
+    font-size: 0.28rem;
+    color: #89919F !important;
+    margin: 0 0 0 0.2rem;
+  }
+
+  .cycle-type {
+    padding: 0.08rem;
+    border-radius: 0.1rem;
+    color: #26a2ff;
+    box-sizing: border-box;
+    background-color: #ecf5ff;
+  }
+
+  .examine-info {
+    font-size: 0.28rem;
+    position: relative;
+
+    .tips {
+      position: absolute;
+      top: 0.1rem;
+      right: -0.2rem;
+      .tip-item {
+        padding: 0.1rem;
+        border-top-left-radius: 0.1rem;
+        border-bottom-left-radius: 0.1rem;
+        color: #26a2ff;
+        z-index: 999;
+        box-sizing: border-box;
+        background-color: #ecf5ff;
+        margin-bottom: 0.1rem;
+      }
+    }
+    .info-item {
+      margin-bottom: 0.2rem;
+      color: #89919F !important;
+      .info-item-title {
+        width: 1.4rem;
+        color: #000;
+      }
+      .review-node {
+        padding: 0.01rem 0.1rem;
+        color: #fff;
+        border-radius: 2px;
+        font-size: 0.26rem;
+        background-color: #67c23a;
+        margin-left: 0.14rem;
+      }
+    }
+
+    .line {
+      width: 100%;
+      margin: 0.5rem auto;
+      height: 1px;
+      background-color: #f1f1f1;
+    }
+  }
+
+
+}
+
+.bg-gray {
+  background-color: #f5f5f5;
+  padding: 0.2rem;
+  box-sizing: border-box;
+  margin: 0.1rem;
+  color: #999;
+  border-radius: 5px;
+}
+
+
+</style>

+ 494 - 0
src/newPerformance/view/navhome/more.vue

@@ -0,0 +1,494 @@
+<template>
+    <div style="width: 100%; height: 100%;" :class="{ bg_fff: skeletonLoad }">
+      <van-nav-bar title="更多考核数据" left-text="返回" left-arrow @click-left="$route_back" />
+
+      <van-search placeholder="请输入考核表名称" v-model="params.keyword" @input="keyVal()" />
+
+
+
+      <!-- 条件筛选 -->
+      <div class="flex-box-ce search-box" style="">
+        <!-- 周期筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center" style="border-right: 1px solid #f1f1f1;">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="openPanel()">
+            <div class="cycle-name">{{ dateParameter.name }}</div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 周期筛选 -->
+        <!-- 时间筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center" style="border-right: 1px solid #f1f1f1;">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="calendarOpen()">
+            <div class="cycle-name" v-html="timeStr"></div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 时间筛选 -->
+
+        <!-- 状态筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="showStatus = true">
+            <div class="cycle-name">{{ statusName }}</div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 状态筛选 -->
+      </div>
+      <!-- 条件筛选 -->
+
+
+      <!-- 骨架屏 -->
+      <VanSkeleton :skeLoad="skeletonLoad">
+        <scroller class="scroller-box" ref="scroller" :isInitRefresh="false" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢" :list="examineList">
+          <div class="examine-list" v-if="filterExamineList && filterExamineList.length > 0">
+            <div class="examine-item" v-for="(item, index) in filterExamineList" :key="item.reviewId" @click="handleChooseItem(item)">
+              <div v-if="item.status == 1" class="examine-item-status" style="background-color: #FF9600;">
+                已结束
+              </div>
+              <div v-if="item.status == 0" class="examine-item-status" >
+                进行中
+              </div>
+              <div class="flex-1 flex-box-ce flex-d-center">
+                <div class="examine-item-title font-flex-word">
+                  {{ item.title }}
+                </div>
+                <div class="examine-item-info">
+                  {{ item.score == null ? '-' : item.score }} / {{ item.levelName || '-' }}
+                </div>
+              </div>
+
+            </div>
+          </div>
+
+          <noData v-else content="无考核记录"></noData>
+        </scroller>
+      </VanSkeleton>
+      <!-- 骨架屏 -->
+
+      <!-- 周期选择弹框 -->
+      <van-action-sheet v-model="pullonThePanel" :closeable="false">
+        <div class="content">
+          <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel = false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+        </div>
+      </van-action-sheet>
+
+      <!-- 日期选择框 -->
+      <van-calendar
+        v-model="showCalendar"
+        type="range"
+        :allow-same-day="true"
+        :min-date="minDate"
+        :max-date="maxDate"
+        :default-date="timeScope"
+        :show-confirm="false"
+        color="#26A2FF"
+        @close="calendarClose"
+        @confirm="calendarConfirm"
+      >
+        <template v-slot:title>
+          <van-row>
+            <van-col span="20">
+              <van-row type="flex" justify="space-between" style="height: 1rem;">
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="success" size="medium" @click="timeScopeThisWeek">本周</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="success" size="medium" @click="timeScopeLastWeek">上周</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="primary" size="medium" @click="timeScopeThisMoth">本月</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="primary" size="medium" @click="timeScopeLastMonth">上月</van-tag>
+                </van-col>
+              </van-row>
+            </van-col>
+          </van-row>
+        </template>
+      </van-calendar>
+
+      <!-- 状态 -->
+      <van-dialog v-model="showStatus" title="" width="300" confirm-button-text="确定" @confirm="handleConfirm" @cancel="handleCancel"  :show-confirm-button="true" closeOnClickOverlay>
+        <van-radio-group v-model="statusId">
+          <div v-for="(item, index) in statusList" :key="index">
+            <van-radio :name="item.value" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+              <span style="margin-left:.3rem">{{ item.text }}</span>
+            </van-radio>
+          </div>
+        </van-radio-group>
+      </van-dialog>
+
+    </div>
+
+</template>
+
+<script>
+  import { _debounce, _throttle } from '@/utils/auth';
+  import VanSkeleton from '@/performance/components/public/VanSkeleton';
+  import { DropdownMenu, DropdownItem, Calendar, Switch} from 'vant';
+  import moment from "moment/moment";
+
+  export default {
+    components: { VanSkeleton },
+    data() {
+
+      let startDate = new Date();
+      startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * 7);
+      startDate = moment(startDate).format('YYYY-MM-DD');
+      let endDate = moment().format('YYYY-MM-DD');
+
+      let today = new Date();
+      let minDate = new Date();
+      minDate.setTime(today.getTime() - 3600 * 1000 * 24 * 30 * 6);
+      let maxDate = new Date(today.getFullYear(),today.getMonth(),1);
+      maxDate.setMonth(maxDate.getMonth() + 1);
+      maxDate.setDate(0);
+
+      return {
+        skeletonLoad: true,
+        keyword: '',
+        examineList: [],
+        filterExamineList: [],
+        pullonThePanel: false,
+
+        columns: [
+          {
+            value: "-1",
+            name: "全部",
+            text: "全部"
+          },
+          {
+            value: "0",
+            name: "自定义",
+            text: "自定义"
+          },
+          {
+            value: "1",
+            name: "年度",
+            text: "年度"
+          },
+          {
+            value: "2",
+            name: "半年度",
+            text: "半年度"
+          },
+          {
+            value: "3",
+            name: "季度",
+            text: "季度"
+          },
+          {
+            value: "4",
+            name: "月度",
+            text: "月度"
+          }
+        ],
+        selectPftiTheEcho: [0, 0], // 选项回显
+        dateParameter: {
+          cycleType: '-1',
+          name: '全部'
+        },
+        showCalendar: false,
+        minDate: minDate,
+        maxDate: maxDate,
+        timeScope: [new Date(startDate),new Date(endDate)],
+
+        userInfo: this.$userInfo(),
+        timeStr: "选择时间",
+        from: "me",
+
+        statusList: [
+          {
+            id: 0, text: "全部", value: "-1"
+          },
+          {
+            id: 1, text: "进行中", value: "0"
+          },
+          {
+            id: 2, text: "已结束", value: "1"
+          },
+        ],
+        showStatus: false,
+        statusId: 0,
+        statusName: "状态",
+        params: {
+          keyword: '',
+          page: 1,
+          pageSize: 15,
+          cateId: '',
+          startDate: '',
+          endDate: '',
+          employeeId: '',
+        },
+      }
+    },
+
+    beforeDestroy() {
+      this.params = {
+        keyword: '',
+        page: 1,
+        pageSize: 15,
+        cateId: '',
+        startDate: '',
+        endDate: '',
+        employeeId: '',
+      };
+      this.from = 'me'
+      this.timeStr = "选择时间";
+      // this.timeScope = [new Date(startDate),new Date(endDate)];
+    },
+
+    created() {
+      this.params.employeeId = this.$route.query.employeeId
+      this.params.employeeId = this.params.employeeId ? this.params.employeeId : this.$userInfo().id
+      this.from = this.$route.query.from || 'me'
+      this.getExamineList();
+    },
+
+    methods: {
+
+      goHomePage() {
+        if(this.from == 'me') this.$router.push("/home")
+        else this.$router.push("/orgExamine")
+      },
+
+      // 周期选择事件
+      handleCellClick(e) {
+        console.log(e.currentTarget.id)
+      },
+
+
+      // 搜索
+      keyVal: _debounce(function() {
+        this.pullDown();
+        // console.log(123)
+      }),
+
+      handleChooseItem(item) {
+        if(this.from == 'me') this.goMePage(item)
+        else this.goOrgExaminePage(item)
+      },
+
+      goOrgExaminePage(item) {
+        this.$router.push({ path: "/orgExamine", query: { reviewId: item.reviewId } })
+      },
+
+      goMePage(item) {
+        this.$router.push({ path: "/newMe", query: { reviewId: item.reviewId, employeeId:  item.employeeId } })
+      },
+
+      // 获取考核表列表
+      getExamineList(is, callback) {
+        let that = this;
+        let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
+        let requestdata;
+        if (that.dateParameter.cycleType == '-1') requestdata = { ...that.params }
+        else requestdata = { ...that.params, cycleType: that.dateParameter.cycleType }
+
+        let hasMore = false
+        is ? '' : that.params.page = 1;
+        that.$axiosUser('get', url, requestdata).then(res => {
+          this.skeletonLoad = false;
+          let { data: { data: { list, total }, code } } = res;
+          if (code == 1) {
+            if (requestdata.page === 1) {
+              that.examineList = list
+            } else {
+              that.examineList = that.examineList.concat(list)
+            }
+
+            hasMore = list.length !== 10
+            callback && callback(hasMore)
+          } else {
+            that.examineList = [];
+          }
+          that.filterExamineList = that.examineList;
+        });
+      },
+
+      // 打开周期选择弹框
+      openPanel(){
+        this.pullonThePanel = true;
+        this.$nextTick(() => {
+          this.theEchoVanPicker()
+        })
+      },
+
+      // 回显
+      theEchoVanPicker() {
+        this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+      },
+
+      //  确认周期选择-考核包搜索
+      onConfirm (data, value) {
+        // let columns = this.columns[list[0]];
+        // let options = this.cycleTypeArr[list[1]]
+        // this.selectPftiTheEcho = list
+        this.dateParameter = {
+          cycleType: data.value,
+          name: data.name
+        };
+        // console.log(this.dateParameter);
+        this.pullDown();
+        this.pullonThePanel = false
+      },
+
+      // 上拉刷新
+      refresh (done) {
+        this.getExamineList(false, done)
+      },
+
+      // 下拉加载
+      infinite (done) {
+        this.params.page ++;
+        this.getExamineList(true, done)
+      },
+
+      pullDown(){
+        setTimeout(() => {
+          this.$refs.scroller.triggerPullToRefresh();
+        }, 50);
+      },
+
+      // 日期选择
+      changeDateGetList() {
+        if(this.timeScope && this.timeScope.length > 0) {
+          this.params.startDate = moment(this.timeScope[0]).format('YYYY-MM-DD')
+          this.params.endDate = moment(this.timeScope[1]).format('YYYY-MM-DD')
+          this.timeStr = this.params.startDate + "<br/>" + this.params.endDate
+          this.getExamineList();
+        }
+
+      },
+
+      // 本周
+      timeScopeThisWeek(){
+        this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
+        this.showCalendar= false
+        this.changeDateGetList()
+      },
+      // 上周
+      timeScopeLastWeek(){
+        this.timeScope = [new Date(moment().subtract(1,'week').startOf('week').format('YYYY-MM-DD')),new Date(moment().subtract(1,'week').endOf('week').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+      // 本月
+      timeScopeThisMoth(){
+        this.timeScope = [new Date(moment().startOf('month').format('YYYY-MM-DD')),new Date(moment().endOf('month').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+      // 上周
+      timeScopeLastMonth(){
+        this.timeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+
+
+      calendarOpen(){
+        this.showCalendar = true;
+      },
+
+      calendarClose(){
+        this.showCalendar = false;
+      },
+
+      calendarConfirm(event){
+        const [start,end] = event;
+        this.timeScope = [start, end];
+        this.showCalendar = false;
+        this.changeDateGetList();
+      },
+
+
+      handleConfirm() {
+        if(this.statusId !== '-1') this.filterExamineList = this.examineList.filter(item => item.status == this.statusId)
+        else this.filterExamineList = this.examineList
+        this.statusName = this.statusList.find(item => item.value == this.statusId).text || '状态'
+        this.showStatus = false
+      },
+
+      handleCancel() {
+        this.showStatus = false
+      }
+
+    }
+  }
+
+
+</script>
+
+<style lang="less" scoped>
+
+  /deep/ .van-calendar__header-subtitle {
+    width: 100%;
+    font-size: 0.28rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .cycle-select-box {
+    width: 100%;
+    padding: 0.2rem 0.1rem;
+    box-sizing: border-box;
+    background-color: #fff;
+    box-sizing: border-box;
+    .icon {
+      margin-right: 6px;
+      width: 0.32rem;
+      height: 0.32rem;
+    }
+    .cycle-name {
+      margin: 0 6px;
+      font-size: 0.3rem;
+    }
+  }
+
+  .search-box {
+    background-color: white;
+    border-top: 1px solid #f1f1f1;
+    border-bottom: 1px solid #f1f1f1;
+    margin-bottom: 0.2rem;
+  }
+
+
+  .scroller-box {
+    height: calc(100% - 3rem) !important;
+    position: relative !important;
+    background-color: #f5f7fa;
+    padding-bottom: 0.5rem;
+    box-sizing: border-box;
+
+    .examine-list {
+      width: 100%;
+      .examine-item {
+        width: 100%;
+        height: 1rem;
+        padding: 0 0.2rem;
+        background-color: #fff;
+        box-sizing: border-box;
+        display: flex;
+        align-items: center;
+        border-bottom: 1px solid #f1f1f1;
+        &-status{
+          padding:0.01rem 0.1rem;
+          color: #fff;
+          border-radius: 2px;
+          font-size: 0.26rem;
+          background-color: #67c23a;
+          margin-right: 0.14rem;
+        }
+
+        &-info {
+          font-size: 0.26rem;
+        }
+      }
+    }
+
+
+  }
+</style>
+

+ 644 - 0
src/newPerformance/view/navhome/organizationExamine.vue

@@ -0,0 +1,644 @@
+<template>
+  <div class="all" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="组织考核" left-text="返回" @click-left="goHomePage" :right-text="right_text" @click-right="multi_option" left-arrow>
+    </van-nav-bar>
+    <van-notice-bar
+      left-icon="volume-o"
+      text="默认显示每个人的最新考核数据,可选择人员添加考核数据,也可以移除某个人员的考核数据,或点击人员姓名替换某条考核数据"
+    />
+
+    <div class="search-box flex-box-ce">
+      <div class="flex-1 flex-box-ce flex-center-center fontColorC" @click="openPanel">
+        周期选择 <van-icon name="arrow-down" size="12" style="margin-left: 0.2rem;" />
+      </div>
+      <div class="flex-1 flex-box-ce flex-center-center fontColorC" @click="openPanel2">
+        部门选择
+        <van-icon name="arrow-down" size="12" style="margin-left: 0.2rem;" />
+      </div>
+    </div>
+
+
+    <div class="overall">
+      <VanSkeleton :skeLoad="skeletonLoad">
+        <scroller>
+          <div style="padding-bottom: 1rem;">
+
+            <div class="list-box" v-for="(item, index) in employeeList" :key="item.employeeId">
+              <van-checkbox v-if="multi" v-model="item.selected" shape="square" style="margin-bottom: 0.1rem;" />
+              <div class="flex-box-ce" style="margin-bottom: 0.2rem;"  @click="chooseExamineInfo(index, item.employeeId)">
+                <div class="flex-box-ce">
+                  <div>
+                    <userImage class="about-me__avatar" :id="item.userInfo.id" :img_url="item.userInfo.img_url"  :user_name="item.userInfo.name"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+                  </div>
+                  <div class="user-info">
+                    <div style="margin-bottom: 0.05rem; color: #000;">{{ item.employeeName }}</div>
+                    <template v-if="item.deptList && item.deptList.length > 0">
+                      <span v-for="(dept, index) in item.deptList" :key="index">{{ dept }}&nbsp;</span>
+                    </template>
+                  </div>
+                </div>
+                <div v-if="item.status == 1" class="examine-item-status" style="background-color: #FF9600;">
+                  已结束
+                </div>
+                <div v-if="item.status == 0" class="examine-item-status" >
+                  进行中
+                </div>
+
+              </div>
+
+              <div class="examine-info">
+                <div class="info-item flex-box-ce">
+                  <div>
+                    考核周期:
+                  </div>
+                  <div class="cycle-type">{{ item.cycleType | formatCycleType }}</div>
+                </div>
+                <div class="info-item">
+                  <div class="flex-box-ce">
+                    <van-icon name="calendar" />考核时间:
+                  </div>
+                  {{ item.startTime | formatDate }} 至 {{ item.endTime | formatDate }}
+                </div>
+                <div class="info-item">
+                  <div>
+                    考核等级:
+                  </div>
+                  <span style="color: #ff9600;">{{ item.levelName || '-' }}</span>
+                </div>
+                <div class="info-item">
+                  <div>
+                    考核评分:
+                  </div>
+                  <span style="color: #ff9600;">{{ item.score == undefined  || item.score == null || item.score == '' ? '-' : item.score }}</span>
+                </div>
+                <div class="info-item">
+                  <div>
+                    较上次:
+                  </div>
+
+                  <span v-if="item.levelChange && item.levelChange > 0" style="color: #67c23a !important;">
+                    {{ item.levelChange }}
+                  </span>
+                  <span v-else-if="item.levelChange && item.levelChange < 0"  style="color: #f56c6c !important;">
+                    {{ item.levelChange }}
+                  </span>
+                  <span v-else class="gray" style="color: #999;">
+                    --
+                  </span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </scroller>
+      </VanSkeleton>
+    </div>
+
+    <footer class="footer">
+      <div v-if="multi" class="flex-box-ce" style="justify-content: space-around;">
+        <div class="flex-box-ce" style="margin: 0 0.2rem; font-size: 0.28rem;" >
+          <van-checkbox v-model="selectAll" shape="square" style="margin-right: 0.2rem;" />
+          全选
+        </div>
+        <div class="btn flex-1 danger" @click="handleDelete()">删除人员</div>
+      </div>
+
+      <div v-else class="flex-box-ce" style="justify-content: space-around;">
+        <div class="btn" @click="openUserSelector()">添加人员</div>
+        <!-- <div class="btn">删除人员</div> -->
+        <div class="btn plain" @click="resetData()">重置数据</div>
+      </div>
+    </footer>
+
+
+    <!-- 周期选择弹框 -->
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel = false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+      </div>
+    </van-action-sheet>
+
+    <!-- 部门选择 -->
+    <EmployeeSelector
+      :can_select_employee="false"
+      :dept_multi="true"
+      @confirm="confirmDept"
+      :visible.sync="show_dept_selector"
+      :selected.sync="selected_dept_data"
+      :isShowDepts="true"
+    ></EmployeeSelector>
+
+
+    <!-- 人员选择 -->
+    <EmployeeSelector title="人员"
+      :visible.sync="show_user_selector"
+      @confirm="confirmCreator"
+      :selected.sync="selected_user_all"
+      :can_select_dept="false"
+      :dept_multi="false"
+      :append_body="true"
+      :isShowDepts="false"
+      :employee_not_select="selectEmployeeIds"
+      :max='30'
+    />
+
+    <!-- 考核信息选择 -->
+    <van-popup v-model:show="isShowMore" round position="bottom" :style="{ height: '80%' }">
+      <More v-if="isShowMore" @onConfirm="chooseExamineItem" :employeeId="currentEmployeeId" />
+    </van-popup>
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { NoticeBar } from 'vant';
+import VanSkeleton from '@/newPerformance/components/public/VanSkeleton';
+import More from '@/newPerformance/components/public/More';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import moment from 'moment';
+
+Vue.use(NoticeBar)
+  export default {
+    components: {
+      VanSkeleton,
+      More,
+      EmployeeSelector
+    },
+
+    data() {
+      return {
+        skeletonLoad: true,
+        isShowMore: false,
+        employeeList: [],
+        // 周期类型 0-自定义 1-年度 2-半年度 3-季度 4-月度
+        cycleType: '-1',
+        right_text: "批量",
+        columns: [
+          {
+            value: "-1",
+            name: "全部",
+            text: "全部"
+          },
+          {
+            value: "0",
+            name: "自定义",
+            text: "自定义"
+          },
+          {
+            value: "1",
+            name: "年度",
+            text: "年度"
+          },
+          {
+            value: "2",
+            name: "半年度",
+            text: "半年度"
+          },
+          {
+            value: "3",
+            name: "季度",
+            text: "季度"
+          },
+          {
+            value: "4",
+            name: "月度",
+            text: "月度"
+          }
+        ],
+
+        currentValue: '-1', // 选项回显
+        currentEmployeeId: '',
+        pullonThePanel: false,
+        dept_id: 0,
+        show_dept_selector: false,
+        show_user_selector: false,
+
+        selected_dept_data: { dept: [], employee: [] },
+
+        selected_user_all: { dept: [], employee: [] }, //选择人员
+
+        multi: false,
+        reviewId: '', // 选择的考核信息ID
+        params: {
+          deptIds: '',
+          employeeIds: '',
+          cateId: '',
+          pages: 1,
+          pageSize: 10
+        },
+      }
+    },
+
+    computed: {
+      selectEmployeeIds() {
+        let selectEmployeeIds = this.employeeList.map(item => item.employeeId)
+        selectEmployeeIds = Array.from(
+            new Set(selectEmployeeIds.map(item => JSON.stringify(item)))
+        ).map(item => JSON.parse(item));
+        return selectEmployeeIds
+      },
+
+      selectEmployees() {
+
+        let selectEmployees = this.employeeList.map(item => item.userInfo)
+        selectEmployees = Array.from(
+            new Set(selectEmployees.map(item => JSON.stringify(item)))
+        ).map(item => JSON.parse(item));
+        return selectEmployees
+      },
+
+      // 全选 / 全不选
+      selectAll: {
+        get() {
+          // 所有都选中 → 全选按钮 true
+          return this.employeeList.every(item => item.selected);
+        },
+        set(val) {
+          // 点击全选按钮时,一键同步到所有
+          this.employeeList.forEach(item => (item.selected = val));
+        }
+      }
+    },
+
+    filters: {
+      filterNodeStatus(v) {
+        if (v === 'start') return '开始'
+        if (v === 'target_confirm') return '确认目标'
+        if (v === 'result_input') return '录入结果值'
+        if (v === 'score_self') return '自评'
+        if (v === 'score_each_other') return '互评'
+        if (v === 'score') return '评分'
+        if (v === 'review') return '审批'
+        if (v === 'cc') return '抄送'
+        if (v === 'end') return '结束'
+      },
+
+      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 '--'
+      },
+    },
+
+    // watch: {
+    //   // 路由参数变化(浏览器返回/前进、query 变化)也会再次执行
+    //   '$route'(to, from) {
+    //     this.getExamineInfo()
+    //   }
+    // },
+
+    created() {
+      // this.show_dept_selector = true
+      this.getList()
+
+    },
+    methods: {
+
+      goHomePage() {
+        this.$router.push("/home")
+      },
+
+      // 批量操作
+      multi_option () {
+        if (this.multi) {
+          this.multi = false
+          this.right_text = '批量'
+        } else {
+          this.multi = true
+          this.right_text = '取消'
+        }
+      },
+
+      // 获取数据
+      getList() {
+        this.skeletonLoad = true;
+        let url = `/performance/statistics/review/last/${this.$userInfo().site_id}`
+        let requestdata
+        if (this.cycleType == '-1') requestdata = { ...this.params }
+        else {
+            requestdata = { ...this.params, cycleType: this.cycleType }
+        }
+        delete requestdata['employeeIds'] // 删除部门字段
+        this.$axiosUser('get', url, requestdata).then(res => {
+          this.skeletonLoad = false;
+          let { data: { data: { list, total }, code } } = res
+          if (code == 1) {
+              if(list && list.length > 0) {
+                list.forEach(item => {
+                  item.selected = false
+                  item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+                })
+              }
+              this.employeeList = list;
+              // this.total = total
+            }
+        });
+      },
+
+      /* 添加的人员请求考核数据 */
+      getListByPerson() {
+        let url = `/performance/statistics/review/last/${this.$userInfo().site_id}`
+        // this.selected_dept_ids = []
+        // this.params.deptIds = ''
+        // this.params.employeeIds = this.params.employeeIds && this.params.employeeIds.length > 0 ? this.params.employeeIds.toString() : ''
+
+        this.$axiosUser('get', url, this.params).then(res => {
+            // this.loading = false;
+            let { data: { data: { list, total }, code } } = res
+            if (code == 1) {
+                let contactList = [...this.employeeList, ...list];
+                // 去重
+                contactList = Array.from(
+                  new Set(contactList.map(item => JSON.stringify(item)))
+                ).map(item => JSON.parse(item));
+                // this.total = this.tableData.length
+                contactList.forEach(item => {
+                  item.selected = false
+                  item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+                })
+                this.employeeList = contactList
+                this.cycleType = '-1';
+            }
+        });
+      },
+
+      // 获取考核信息
+      getExamineInfo() {
+        let url = `/performance/statistics/review/info/${this.$userInfo().site_id}/${this.reviewId}`
+        this.$axiosUser('get', url).then(res => {
+          let { data, code } = res.data
+          if (code == 1) {
+            if (data) {
+              delete data['deptList'] // 删除部门字段
+              let replaceData = {
+                ...this.employeeList[this.currentIndex],
+                ...data
+              }
+              this.employeeList.splice(this.currentIndex, 1, replaceData);
+            }
+          }
+        });
+      },
+
+
+      // 打开周期选择弹框
+      openPanel(){
+        this.pullonThePanel = true;
+        // 等 DOM 渲染完成后设置索引
+        this.$nextTick(() => {
+          const index = this.columns.findIndex(item => item.value == this.currentValue);
+          // 单列只传一个索引
+          this.$refs.van_picker.setIndexes([index]);
+        });
+
+      },
+
+      openPanel2() {
+        this.show_dept_selector = true
+        console.log(this.show_dept_selector)
+      },
+
+      //  确认周期选择
+      onConfirm (data, value) {
+        console.log(data)
+        console.log(value)
+        this.cycleType = data.value
+        this.currentValue = data.value
+        this.getList()
+        this.pullonThePanel = false
+      },
+
+      confirmDept(val){
+        console.log(val)
+
+        this.selected_dept_data = val;
+        if(val.dept.length > 0){
+          this.params.deptIds = val.dept.map(dept => dept.dept_id).toString()
+        }else{
+          this.params.deptIds = ''
+        }
+        this.getList();
+      },
+
+      openUserSelector() {
+        // this.selected_user_all.employee = this.selectEmployees
+        this.show_user_selector = true
+      },
+
+      resetData() {
+        let url = `/performance/statistics/review/last/${this.$userInfo().site_id}`
+        let requestdata
+        this.cycleType = '-1';
+        this.params = {
+            deptIds: '',
+            employeeIds: '',
+            cateId: '',
+            pages: 1,
+            pageSize: 10
+        }
+        // this.selected_dept_ids = []
+        requestdata = { ...this.params }
+        if ('deptIds' in requestdata) delete requestdata['deptIds'] // 删除部门字段
+        this.$axiosUser('get', url, requestdata).then(res => {
+            // this.loading = false;
+            let { data: { data: { list, total }, code } } = res
+            if (code == 1) {
+              if(list && list.length > 0) {
+                list.forEach(item => {
+                  item.selected = false
+                  item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+                })
+              }
+              this.employeeList = list;
+            }
+        });
+      },
+
+      confirmCreator(arr){
+        if(!(arr.employee && arr.employee.length > 0)) return
+        let target_ids = arr.employee.map(item=>{
+          return item.id
+        }).filter(item => !this.selectEmployeeIds.includes(item)).toString();
+        // target_ids = target_ids.filter(target => )
+        console.log(target_ids)
+        this.params.employeeIds = target_ids;
+        this.getListByPerson();
+        // let data = {
+        //   employeeId: this.$userInfo().id,
+        //   targetIds: target_ids
+        // }
+
+      },
+
+      handleDelete() {
+        this.employeeList = this.employeeList.filter(item => !item.selected)
+      },
+
+      chooseExamineInfo(index, employeeId) {
+        this.currentIndex = index
+        this.currentEmployeeId = employeeId
+        this.isShowMore = true
+        // this.$router.push({ path: "/more", query: { employeeId, from: "orgExamine" } })
+      },
+
+      chooseExamineItem(data) {
+        this.isShowMore = false
+        this.reviewId = data.reviewId
+        this.getExamineInfo()
+      }
+    }
+  }
+</script>
+
+<style scoped lang="less">
+  .all {
+    width: 100%;
+    height: 100%;
+    position: relative !important;
+    background-color: #f5f7fa;
+    box-sizing: border-box;
+    .search-box {
+      width: 100%;
+      height: 0.8rem;
+      background: #fff;
+      font-size: 0.28rem;
+    }
+    .overall {
+      height: calc(100% - 2.52rem) !important;
+      position: relative;
+      overflow-y: scroll;
+
+      .list-box {
+        width: 96%;
+        padding: 0.24rem;
+        font-size: 0.32rem;
+        background-color: #fff;
+        border-radius: 5px;
+        box-sizing: border-box;
+        margin: 0.24rem auto;
+        position: relative;
+        .examine-item-status {
+          position: absolute;
+          top: 0.2rem;
+          right: 0.1rem;
+          padding: 0.01rem 0.1rem;
+          color: #fff;
+          border-radius: 2px;
+          font-size: 0.26rem;
+          background-color: #67c23a;
+          margin-right: 0.14rem;
+        }
+        .add-task-title {
+          font-weight: 600;
+          font-size: 0.32rem;
+        }
+
+        .user-info {
+          font-size: 0.28rem;
+          color: #89919F !important;
+          margin: 0 0 0 0.2rem;
+        }
+
+        .cycle-type {
+          padding: 0.08rem;
+          border-radius: 0.1rem;
+          color: #26a2ff;
+          box-sizing: border-box;
+          background-color: #ecf5ff;
+        }
+
+        .examine-info {
+          font-size: 0.28rem;
+          position: relative;
+
+          .tips {
+            position: absolute;
+            top: 0.1rem;
+            right: -0.2rem;
+            .tip-item {
+              padding: 0.1rem;
+              border-top-left-radius: 0.1rem;
+              border-bottom-left-radius: 0.1rem;
+              color: #26a2ff;
+              z-index: 999;
+              box-sizing: border-box;
+              background-color: #ecf5ff;
+              margin-bottom: 0.1rem;
+            }
+          }
+          .info-item {
+            margin-bottom: 0.2rem;
+            color: #89919F !important;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            .info-item-title {
+              width: 1.4rem;
+              color: #000;
+            }
+            .review-node {
+              padding: 0.01rem 0.1rem;
+              color: #fff;
+              border-radius: 2px;
+              font-size: 0.26rem;
+              background-color: #67c23a;
+              margin-left: 0.14rem;
+            }
+          }
+
+          .line {
+            width: 100%;
+            margin: 0.5rem auto;
+            height: 1px;
+            background-color: #f1f1f1;
+          }
+        }
+
+
+      }
+    }
+  }
+
+
+  .footer {
+    width: 100%;
+    padding: 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+    box-sizing: border-box;
+    .btn {
+      width: 48%;
+      padding: 0.2rem;
+      // border: 0.02rem solid #26A2FF;
+      color: #fff;
+      text-align: center;
+      background: #26A2FF;
+      font-size: 0.28rem;
+      box-sizing: border-box;
+    }
+    .danger {
+      background-color: transparent;
+      color: rgb(245, 108, 108);
+      border: 1px solid rgb(245, 108, 108);
+    }
+    .plain {
+      background-color: transparent;
+      color: #26A2FF;
+      border: 1px solid #26A2FF;
+    }
+  }
+</style>

+ 195 - 0
src/newPerformance/view/navhome/perAttentionList.vue

@@ -0,0 +1,195 @@
+<template>
+  <div style="width: 100%; height: 100%; display: flex; flex-direction: column;">
+    <van-nav-bar left-text="返回" @click-left="$route_back" :title="'关注的人'"></van-nav-bar>
+
+    <header class="flex-box-ce" style="padding: 0.2rem 0.32rem; background-color: #fff; box-sizing: border-box;">
+      <div class="flex-1 fontColorB">人员</div>
+      <div class="blue" @click="selectUserAll = true"><van-icon name="plus" /> 添加</div>
+    </header>
+
+    <div class="scroller">
+      <scroller ref="scroller_com">
+          <div class="employee_item"  v-for="(item,key) in employee_list " :key="key">
+            <van-cell class="employee_cell" :title="item.name">
+              <template slot="icon">
+                <img :src="item.imgUrl" width="30" height="30" class="imgUrl" v-if="item.imgUrl">
+                <div class="imgUrl" v-else style="background: #238DFA; color: #fff;">{{item.name.substring(item.name.length - 2)}}</div>
+              </template>
+              <template slot="right-icon">
+                  <span class="blue flex-box flex-h-ce" style="font-size: 0.28rem;" @click="qxAttention(item)">{{ '取消关注' }}</span>
+              </template>
+            </van-cell>
+          </div>
+          <div v-if="employee_list.length == 0" style="text-align: center; margin-top: 2rem;" class="fontColorC">
+              <span>暂无数据</span>
+          </div>
+          <div style="height: 1rem;"></div>
+      </scroller>
+    </div>
+
+    <!-- @人员 -->
+    <EmployeeSelector title="人员"
+      :visible.sync="selectUserAll"
+      @confirm="confirmCreator"
+      :selected.sync="selected_user_all"
+      :can_select_dept="false"
+      :dept_multi="false"
+      :append_body="true"
+      :isShowDepts="false"
+      :max='20'
+    />
+  </div>
+
+</template>
+
+<script type="text/javascript">
+import EmployeeSelector from '@/components/EmployeeSelector'
+export default {
+  name: 'attentionList',
+  components:{EmployeeSelector},
+  data () {
+    return {
+      employee_list: [],
+      selectUserAll:false,
+      selected_user_all: { dept: [], employee: [] },//参与人员
+      index:1,
+    }
+  },
+  mounted() {
+    this.index = this.$route.query.index;
+    this.getUserList()
+  },
+  methods: {
+    getUserList(){
+      this.$axiosUser('get', `/performance/follow/employees/${this.$userInfo().site_id}`).then(res => {
+        this.employee_list = res.data.data.list;
+        this.selected_user_all.employee = this.employee_list;
+      });
+    },
+
+    qxAttention (item) {
+      let str= '取消关注'
+      this.$dialog.confirm({message: `确定${str}吗?`, title: '提示'}).then(() => {
+       let data={
+         employeeId: this.$userInfo().id,
+         targetIds: item.id
+       }
+       this.$axiosUser('post', `/performance/follow/remove/employee/${this.$userInfo().site_id}`, data, 'contentTypeJson').then(res => {
+          this.$toast("已取消关注")
+          this.getUserList();
+        });
+      }).catch(() => {})
+    },
+
+    confirmCreator(arr){
+      console.log(arr)
+      let target_ids = arr.employee.map(item=>{
+        return item.id
+      }).toString();
+      let data = {
+        employeeId: this.$userInfo().id,
+        targetIds: target_ids
+      }
+      this.$axiosUser('post', `/performance/follow/bind/employee/${this.$userInfo().site_id}`, data, 'contentTypeJson').then(res => {
+          this.$toast("已设置关注")
+          this.getUserList();
+      });
+    },
+
+  }
+}
+</script>
+<style scoped>
+  .scroller {
+    position: relative;
+    flex: 1;
+  }
+
+
+  .van-cell__label{
+    max-width: 4rem;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    margin-top: 0;
+  }
+  .imgUrl{
+  	border-radius: 50%;
+  	height: 0.9rem;
+  	width: 0.9rem;
+  	box-sizing: border-box;
+  	text-align: center;
+  	line-height: 0.9rem;
+  	font-size: 0.32rem;
+    margin-right: 0.24rem;
+  }
+
+
+
+
+  .employee_cell {
+    z-index:0;
+  }
+  .employee_cell .message_department{
+    width:0.9rem;
+    height:0.9rem;
+    margin-right: 0.24rem;
+    color:#238dfa;
+  }
+  .employee_cell .message_newinvit{
+    width:0.9rem;
+    height:0.9rem;
+    margin-right: 0.24rem;
+    color:#FFCC00;
+  }
+  .employee_cell .message_newmember{
+    width:0.9rem;
+    height:0.9rem;
+    margin-right: 0.24rem;
+    color:#FF9600;
+  }
+  .employee_cell .van-cell__title {
+    /* line-height: 0.9rem; */
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-flex-flow: column;
+    flex-flow: column !important;
+    justify-content: center;
+    -webkit-justify-content: center;
+    -webkit-box-pack: center;
+    color: #323233;
+  }
+
+  .employee_cell .van-cell__title span{
+    font-size: 0.34rem;
+  }
+  .employee_cell .van-cell__right-icon{
+    line-height: 0.9rem;
+    color: #E4E7ED;
+  }
+
+  .van-hairline--top-bottom:after, .van-hairline-unset--top-bottom:after{
+    border:none;
+  }
+
+  .employee_item{
+    position: relative;
+    z-index: 0;
+  }
+
+  .employee_item:before{
+    position: absolute;
+    left: 0rem;
+    right: 0rem;
+    top:0rem;
+    box-sizing: border-box;
+    content: ' ';
+    pointer-events: none;
+    border-bottom: 0.02rem solid #ebedf0;
+    -webkit-transform: scaleY(.5);
+    transform: scaleY(.5);
+    z-index: 1;
+  }
+</style>

+ 1177 - 0
src/newPerformance/view/navhome/resultAnalysis.vue

@@ -0,0 +1,1177 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="结果分析" left-text="返回" left-arrow @click-left="$route_back" />
+    <VanSkeleton :skeLoad="skeletonLoad" v-if="isYou">
+      <template>
+        <header>
+
+          <div style="border-bottom: 1px solid #f1f1f1;" class="selector flex-box-ce flex-center-center" @click="openPanel()">
+            <icon name="YMPicker_item_icon" style="margin-right: 6px;width: 0.3rem;height: 0.3rem;" class="fontColorC"></icon>
+            <div>{{ paramsText }}</div>
+            <van-icon name="arrow-down" />
+          </div>
+        </header>
+
+        <scroller ref="me_scroller" class="all">
+          <div style="padding-bottom: 1.5rem;">
+
+            <div class="statementFoot">
+              <van-tabs v-model="active" @change="statementTabs">
+                <van-tab v-for="(item, index) in statementVanTabs" :key="index" :title="item.name"></van-tab>
+              </van-tabs>
+              <!-- 等级分布 -->
+              <div class="statmentAnalysePie" v-show="active == 0">
+                <div style="width: 7.5rem; height: 5rem;" id="statmentAnalysePie" ref="statmentAnalysePie"></div>
+                <div class="PiePropNum">
+                  <div>总人数</div>
+                  <div>{{ userTotal }}人</div>
+                </div>
+              </div>
+
+
+              <!-- 正态分布 -->
+              <div v-show="active == 1">
+                <div class="statementHnum">
+                  <div class="Hnumvfor">
+                    <span class="smHnLtit">总人数</span>
+                    <br />
+                    <span class="smHnLnum">{{ userTotal }}</span>
+                    <br />
+                    <span{{ userComplete }}人已完成</span>
+                  </div>
+                  <div v-for="(item, index) in scoreList" class="Hnumvfor" :key="index">
+                    <span class="smHnLtit">{{ item.name }}</span>
+                    <br />
+                    <span class="smHnLnum">{{users.filter(user => user.scoreResult === item.name).length}}</span>
+                    <br />
+                  </div>
+
+                </div>
+               </div>
+
+              <div>
+
+              <div>
+
+                <!-- <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" /> -->
+                <div class="flex-box-ce" style="border-bottom: 0.02rem solid #f1f1f1;">
+                  <div class="selectItem flex-1 font-flex-word fontColorC" style="border-right: 0.02rem solid #f1f1f1;"  @click="showDept = true">
+                    <span>{{ deptName }}</span>
+                    <van-icon name="arrow-down" size="12"/>
+                  </div>
+                  <div class="selectItem flex-1 font-flex-word fontColorC" @click="showStatus = true">
+                    <span>{{ statusName }}</span>
+                    <van-icon name="arrow-down" size="12"/>
+                  </div>
+                </div>
+
+                  <ol v-if="filterUsers && filterUsers.length > 0">
+                    <li @click="openDetail(item)" v-for="(item, index) in filterUsers" :key="index" class="flex-ce-box flex-d-center statmentperson" :style="index != 0 ? 'border-top: 0.02rem solid #e6e6e6;' : ''">
+
+                      <div class="flex-1 flex-box" style="align-items: center; justify-content: space-between;">
+                        <!-- <div class="score-result">{{ item.scoreResult }}</div> -->
+                        <div class="flex-box-ce flex-1">
+                          <userImage :id="item.employeeId" :user_name="item.employeeName" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-top:.08rem;"></userImage>
+                          <div style="padding-left:.2rem;">
+                            <span style="font-size:.3rem;">{{ item.employeeName }}</span>
+                            <br />
+                            <span class="font-flex-word" style="width: 3.8rem;display:inline-block;" v-if="item.dept_list && item.dept_list.length > 0">
+                              <span style="font-size:.25rem;" v-for="(arr, att) in item.dept_list" :key="att">
+                                {{ arr.dept_name }}
+                                <span v-if="item.dept_list.length - att > 1">,</span>
+                              </span>
+                            </span>
+                          </div>
+                        </div>
+                        <div style="display: flex; align-items: center; flex-direction: column;">
+                          <div v-if="item.status == 0" class="review-status">进行中</div>
+                          <div v-if="item.status == 1" class="review-status" style="background-color: #FF9600;">已结束</div>
+                          <div style="display: flex; align-items: center; white-wrap: no-wrap; font-size:.26rem; text-align:center; overflow: hidden;">
+
+                            <span>{{ item.score == undefined || item.score == null || item.score == ''  ? '-' : item.score }}</span>
+                            /
+                            <span v-if="active == 1" style="color:#ffad67;">{{ item.scoreResult || '-' }}</span>
+                            <span v-if="active == 0" style="color:#ffad67;">{{ item.level ? item.level : '--'}}</span>
+                          </div>
+                        </div>
+                      </div>
+
+                    </li>
+                  </ol>
+                  <noData v-else content="无考核记录"></noData>
+
+
+                </div>
+
+              </div>
+
+            </div>
+
+            <template>
+
+
+
+            <div class="indicator-list-title">指标分析</div>
+
+            <div class="indicator-list">
+              <div class="indicator-item" v-for="(item, index) in tableData2" :key="index">
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">指标名称</div>
+                  <div class="indicator-info-value">{{ item.title }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">目标</div>
+                  <div class="indicator-info-value">{{ item.target }} {{ item.unit ? item.unit : '' }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">均值</div>
+                  <div class="indicator-info-value">{{ item.avgResult }} {{ item.unit ? item.unit : '' }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">超出目标比例</div>
+                  <div v-if="parseInt(item.standardResultRate) > 0"  class="color-green">{{ item.standardResultRate }}</div>
+                  <div v-else-if="parseInt(item.standardResultRate) < 0"  class="color-red">{{ item.standardResultRate }}</div>
+                  <div v-else class="color-gray">{{ item.standardResultRate }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">达标数</div>
+                  <div class="indicator-info-value">{{ item.standardCount }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">达标率</div>
+                  <div v-if="parseInt(item.standardRate) > 0" class="color-green" >{{ item.standardRate }}</div>
+                  <div v-else-if="parseInt(item.standardRate) < 0" class="color-red" >{{ item.standardRate }}</div>
+                  <div v-else class="color-gray" >{{ item.standardRate }}</div>
+
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">平均分</div>
+                  <div class="indicator-info-value">{{ item.avgScore }}</div>
+                </div>
+
+              </div>
+            </div>
+
+            </template>
+          </div>
+        </scroller>
+      </template>
+    </VanSkeleton>
+    <noData content="无考核记录" v-else></noData>
+
+    <!-- 周期选择 -->
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="cycleOptions" @cancel="pullonThePanel = false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+      </div>
+    </van-action-sheet>
+
+
+    <!-- 部门搜索 -->
+    <van-dialog v-model="showDept" width="300" confirm-button-text="确定" @confirm="handleConfirm" @cancel="handleCancel" :show-confirm-button="true" closeOnClickOverlay>
+       <div style="max-height: 8rem; overflow: auto;" class="scroll-bar">
+         <div class="dept-list">
+           <div class="checkbox-wrapper" v-for="(item, index) in department_list" :key="index">
+             <input type="checkbox" :id="'dept' + (index+1)" class="hidden-checkbox" v-model="item.select">
+             <label :for="'dept' + (index+1)" class="custom-checkbox"></label>
+             <label :for="'dept' + (index+1)" class="checkbox-label">
+               {{ item.dept_name }}
+             </label>
+           </div>
+         </div>
+       </div>
+    </van-dialog>
+
+
+
+    <!-- 状态 -->
+    <van-dialog v-model="showStatus" title="" width="300" confirm-button-text="确定" @confirm="handleStatusConfirm" @cancel="handleStatusCancel"  :show-confirm-button="true" closeOnClickOverlay>
+      <van-radio-group v-model="statusId">
+        <div v-for="(item, index) in statusList" :key="index">
+          <van-radio :name="item.value" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.text }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+  </div>
+</template>
+
+
+<script>
+import Vue from 'vue';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import { Picker, ActionSheet, Circle, Tab, Tabs, Skeleton, DropdownMenu, DropdownItem, Progress, Calendar } from 'vant';
+import { _debounce } from '@/utils/auth';
+import _ from "lodash"
+
+Vue.use(Picker)
+  .use(ActionSheet)
+  .use(Circle)
+  .use(Tab)
+  .use(Tabs)
+  .use(Skeleton)
+  .use(DropdownMenu)
+  .use(DropdownItem)
+  .use(Progress)
+  .use(Calendar);
+export default {
+  data() {
+    return {
+      isYou: true,
+      skeletonLoad: true, // 骨架屏
+      statementtabshow: false,
+      statementperson: [],
+      statementResult: [],
+      allStatementResult: [],
+      statementVanTabs: [{ name: '等级分布' }, { name: '正态分布' }],
+      active: 0,
+      detailInfo: null,
+      startTime: "",
+      endTime: "",
+      deptIds: [],
+      rank: "",
+      rankList: [],
+      deptList: [],
+      scoreList: [],
+      users: [], //考核人员列表
+      filterUsers: [],
+      tableData1: [], // 考核中的指标列表,
+      tableData2: [], // 按单位/目标/聚合指标列表,
+      filterTableData1: [],
+      filterTableData2: [],
+      distributionId: '',
+      userTotal: 0,
+      userComplete: 0,
+      userIncomplete: 0,
+      infos: [],
+      paramsText: '',
+      selectPftiTheEcho: [0, 0], // 选项回显
+      pullonThePanel: false, // 选项面板
+
+      keyword: "",
+      deptName: '全部部门',
+      department_list: [],
+      showDept: false,
+
+      statusList: [
+        {
+          id: 0, text: "全部", value: "-1"
+        },
+        {
+          id: 1, text: "进行中", value: "0"
+        },
+        {
+          id: 2, text: "已结束", value: "1"
+        },
+      ],
+      showStatus: false,
+      statusId: "-1",
+      statusName: "状态",
+
+      recordList: [],
+      userInfo: this.$userInfo(),
+      gradeLevels: [], // 全局等级配置
+
+      cycleOptions: [
+        { name: "月度", value: "4", id: "4", text: "月度", children: [], className: 'column-1' },
+        { name: "季度", value: "3", id: "3", text: "季度", children: [], className: 'column-2' },
+        { name: "半年度", value: "2", id: "2", text: "半年度", children: [], className: 'column-3' },
+        { name: "年度", value: "1", id: "1", text: "年度", children: [], className: 'column-4' },
+        { name: "自定义", value: "0", id: "0", text: "自定义", children: [], className: 'column-5' },
+      ],
+      headValue: [],
+      isYou: true,
+    };
+  },
+
+
+  components: { VanSkeleton },
+
+  watch: {
+    detailInfo(v) {
+      this.$nextTick(() => {
+        this.initData();
+      })
+    },
+    headValue(v) {
+      let value = ''
+      if (this.headValue[0] && this.headValue[0] == '0') value = "自定义 / "
+      if (this.headValue[0] && this.headValue[0] == '1') value = "年度 / "
+      if (this.headValue[0] && this.headValue[0] == '2') value = "半年度 / "
+      if (this.headValue[0] && this.headValue[0] == '3') value = "季度 / "
+      if (this.headValue[0] && this.headValue[0] == '4') value = "月度 / "
+      let currentOption = this.cycleOptions.find(item => item.value == this.headValue[0])
+      let optionIndex = this.cycleOptions.findIndex(item => item.value == this.headValue[0])
+      let childIndex = 0
+      if(currentOption.children && currentOption.children.length > 0) {
+        childIndex = currentOption.children.findIndex(child => child.value == this.headValue[1])
+        value += currentOption.children.find(child => child.value == this.headValue[1]).text;
+      }
+      // value += this.cycleOptions.find(item => item.value == this.headValue[1]).label || ''
+      this.paramsText = value;
+      this.selectPftiTheEcho = [optionIndex, childIndex] // 周期选项回显
+      this.getResultAnalyze();
+    }
+  },
+
+
+  methods: {
+
+    openDetail(item){
+      this.$router.push({ path: '/newMe', query: { reviewId: item.reviewId, employeeId: item.employeeId } });
+    },
+
+    async initData() {
+      // this.activeName = '1'
+      this.deptName = '全部部门'
+      this.deptIds = [];
+      this.department_list = [];
+      this.users = [];
+      this.filterUsers = [];
+      this.tableData1 = [];
+      this.tableData2 = [];
+      this.filterTableData1 = [];
+      this.filterTableData2 = [];
+      let { indicators, startTime, endTime, distribution: { items }, users } = this.detailInfo
+      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 => {
+        this.users.forEach(user => {
+          if (user.employeeId == item.employeeId) {
+            item.departments = user.departments
+          }
+        })
+        if (item.target && item.result) {
+          item.difference = item.result - item.target
+        } else {
+          item.difference = '--'
+        }
+      })
+      this.filterTableData1 = this.tableData1;
+      if(this.tableData1 && this.tableData1.length > 0) {
+        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: '',
+              departments: [],
+              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; // 单位
+              group.departments = indicator.departments; // 单位
+              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;
+            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);
+            this.filterTableData2 = this.tableData2;
+          })
+      }
+
+
+      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)
+      })
+
+      if (this.users && this.users.length > 0) {
+        this.isYou = true;
+          this.users.forEach(user => {
+            this.userTotal++;
+            this.userComplete += user.status === 1 ? 1 : 0;
+            user.level = this.findGrade(user.score, this.gradeLevels);
+            // this.rankList.push(user.level || '未评分')
+            if(user.score !== null ) {
+              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 => {
+            item.dept_list = this.$getEmployeeMapItem(item.employeeId).employee_detail.dept_list
+            if(item.dept_list && item.dept_list.length > 0) {
+              item.dept_list.forEach(dept => {
+                dept.id = dept.dept_id
+                item.select = false
+                this.department_list.push(dept)
+              })
+
+              this.department_list = Array.from(
+                  new Set(this.department_list.map(item => JSON.stringify(item)))
+              ).map(item => JSON.parse(item));
+            }
+            scoreResult.forEach(result => {
+              if (result.scores.includes(item.score)) {
+                item.scoreResult = result.level
+              }
+            })
+          })
+
+          // 按分数排序
+          this.users = this.users.slice().sort((a, b) => b.score - a.score);
+
+          // this.filterUsers = cloneDeep(this.users)
+          this.filterUsers = this.users
+          // this.getResult();
+          let pieData = []
+
+          if(this.users && this.users.length > 0) {
+            pieData = this.gradeLevels.map(item => ({
+              name: item.name + '   ' + this.users.filter(user => user.level === item.name).length + '人',
+              value: this.users.filter(user => user.level === item.name).length
+            }))
+
+            this.statmentAnalysesPie(pieData)
+          }
+      }else {
+        this.isYou = false;
+      }
+    },
+
+    statmentAnalysesPie(data) {
+
+      let colors = ['rgb(38, 162, 255)', '#f36f2a', '#fecb09', '#00b6bd', '#e85d53', '#fecb09'];
+      let legendDataLeng = data.length;
+      if (legendDataLeng > colors.length) {
+        let colorsLeng = colors.length;
+        for (let i = 0; i <= legendDataLeng - colorsLeng; i++) {
+          colors.push('rgb(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ')');
+        }
+      }
+
+      // 是否全部 0
+      const isEmpty = data.every(v => v.value == 0)
+
+      if(isEmpty) {
+        data.forEach(item => item.itemStyle = { color: '#E5E5E5' })
+      }
+
+      const chart = this.$refs.statmentAnalysePie;
+      if (chart) {
+        const myChart = this.$echarts.init(chart);
+        const option = {
+          legend: [
+            {
+              type: 'scroll',
+              orient: 'vertical',
+              icon: 'square',
+              left: '55%',
+              align: 'left',
+              top: 'center',
+              itemGap: 20,
+              itemWidth: 5, // 图形宽度。
+              itemHeight: 5, // 图形高度。
+              // bottom:'50%',
+              textStyle: {
+                fontSize: 14,
+                color: 'rgb(48, 49, 51)'
+              }
+              // data: Name
+            }
+          ],
+          color: colors,
+          emphasis: {
+            scale: true,
+            scaleSize: 10,
+            label: {
+              formatter: '总人数',
+              show: true,
+              fontSize: '20'
+            }
+          },
+          series: [
+            {
+              type: 'pie',
+              radius: ['43%', '53%'],
+              center: ['30%', '50%'],
+              avoidLabelOverlap: false,
+              itemStyle: {
+                borderRadius: 10,
+                borderColor: '#fff',
+                borderWidth: 2
+              },
+              label: {
+                show: false,
+                position: 'center'
+              },
+              labelLine: {
+                show: false
+              },
+              data: data.reverse()
+            }
+          ]
+        };
+        myChart.setOption(option);
+        setTimeout(() => {
+          myChart.resize();
+        }, 200);
+      }
+    },
+
+
+
+    // 查找分数对应的等级
+    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 [];
+        // 是否全部 0
+        const isEmpty = sortedScores.every(v => v == 0 || v == null)
+        if(isEmpty) 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
+          };
+        });
+
+    },
+
+
+    statementTabs() {},
+
+
+    openPanel(){
+      this.pullonThePanel = true;
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+
+    // 考核包搜索
+    onConfirm (data, list) { // 确认
+      this.selectPftiTheEcho = list
+      let cycle = this.cycleOptions[list[0]].value
+      let time = this.cycleOptions[list[0]].children[list[1]].value
+      this.headValue = [cycle, time]
+      this.pullonThePanel = false
+    },
+
+    // 获取全局等级设置
+    async getAllLevelSet() {
+      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;//最大值
+      let colorList = ['#5F7294', '#08EEA1', '#f56c6c', '#0887EE', '#92EE08', '#f56c6c']
+      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 };//当不是第一个等级时,最小值为上一个的最大值
+          }
+          obj.color = colorList[index]
+          max = item.value;
+          gradeLevels.push(obj);
+        })
+        this.gradeLevels = gradeLevels;
+      }
+    },
+
+    // 获取结果分析数据
+    getResultAnalyze() {
+      let url = `/performance/statistics/cycle/${this.$userInfo().site_id}/${this.headValue[0]}`
+      if (!this.headValue[1]) return
+      this.$axiosUser("get", url, { value: this.headValue[1] }).then(res => {
+        this.detailInfo = res.data.data
+        this.skeletonLoad = false
+      })
+    },
+
+    getRecords(cycle) {
+      if (cycle < 0) {
+        cycle = 0
+        return
+      }
+      // 周期种类 0-自定义 1-年度 2-半年度 3-季度 4-月度
+      let url = `/performance/statistics/cycle/info/${this.$userInfo().site_id}/${cycle}`
+      this.$axiosUser("get", url, {}).then(res => {
+        let { data: { data: { items, cycleType } } } = res
+        if (items && items.length > 0) {
+          items.forEach(item => {
+            item.name = item.remark
+            item.text = item.remark
+            item.id = item.value
+          })
+          let index = parseInt(4 - cycle)
+          this.cycleOptions[index].children = items
+
+          this.headValue = [cycle + '', this.cycleOptions[index].children[[0]].value]
+          // if (this.headValue[1]) this.placeholder = this.options[parseInt(cycle)].children[[0]].label || ''
+        } else {
+          this.getRecords(parseInt(cycle) - 1) // 递归周期类型,获取考核数据,优先按月,季,半年度,年度来调用
+        }
+      })
+  },
+
+
+
+    theEchoVanPicker() {
+      // 回显
+      this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+    },
+
+    onCancel() {
+      // 取消
+      this.pullonThePanel = false;
+    },
+
+
+    keyVal: _debounce(function() {
+      if(!this.keyword) this.filterUsers = this.recordList
+      // let filterUsers = []
+      if(this.recordList && this.recordList.length > 0) {
+        this.filterUsers = this.recordList.filter(item => item.employeeName.includes(this.keyword.trim()))
+      }
+    }),
+
+    handleConfirm() {
+      this.deptIds = this.department_list.filter(item => item.select).map(item => item.dept_id)
+      if(this.deptIds && this.deptIds.length > 0) {
+        this.deptName = ''
+        this.department_list.filter(item => item.select).forEach(dept => {
+          this.deptName += dept.dept_name + ","
+        })
+        this.deptName = this.deptName.substring(0, this.deptName.length - 1)
+        // this.filterUsers = this.users.filter((item) => {
+        //   const departmentMatch = this.deptIds.length === 0 || this.deptIds.some((depId) => item.departments.some(dep => dep.id == depId));
+        //   return departmentMatch;
+        // });
+      }else {
+        this.deptName = '全部部门'
+      }
+
+      this.filteredData()
+      this.showDept = false;
+    },
+
+
+    // 实时过滤后数据
+    filteredData() {
+
+      this.filterUsers = this.users.filter((item) => {
+        // 部门筛选:如果选了部门,则过滤;没选则不过滤
+        const departmentMatch = this.deptIds.length === 0 || this.deptIds.some((depId) => item.departments.some(dep => dep.id == depId));
+
+        // 状态筛选:如果选了“全部”,则不过滤;否则按状态过滤
+        const statusMatch = this.statusId == '-1' || item.status == this.statusId;
+        return departmentMatch && statusMatch;
+      });
+
+    },
+
+    handleCancel() {
+      this.showDept = false;
+    },
+
+
+    handleStatusConfirm() {
+      this.filteredData();
+      this.statusName = this.statusList.find(item => item.value == this.statusId).text || '状态'
+      this.showStatus = false
+    },
+
+    handleStatusCancel() {
+      this.showStatus = false;
+    },
+
+    getColumnsInfo(cycle) {
+      if (cycle < 0) {
+        cycle = 0
+        return
+      }
+      // this.loading = true
+      // 周期种类 0-自定义 1-年度 2-半年度 3-季度 4-月度
+      let url = `/performance/statistics/cycle/info/${this.$userInfo().site_id}/${cycle}`
+      this.$axiosUser("get", url, {}).then(res => {
+          // this.loading = false;
+          let { data: { data: { items, cycleType } } } = res
+          let index = parseInt(4 - cycle)
+          this.cycleOptions[index].children = items
+          if (items && items.length > 0) {
+              items.forEach(item => {
+                item.name = item.remark
+                item.text = item.remark
+                item.id = item.value
+              })
+
+              let cycle = this.cycleOptions[index].value
+              let time = this.cycleOptions[index].children[[0]].value
+          } else {
+            this.cycleOptions[index].children = [
+              {name: '', text: '', value: '', id: ''}
+            ]
+          }
+      })
+    },
+
+  },
+
+  mounted() {
+    this.$nextTick(async () => {
+      // 获取全局等级
+      await this.getAllLevelSet();
+
+      // 获取周期列表数据
+      await this.getColumnsInfo(4); // 月度
+      await this.getColumnsInfo(3);
+      await this.getColumnsInfo(2);
+      await this.getColumnsInfo(1);
+      await this.getColumnsInfo(0);
+
+      this.getRecords(4);
+    })
+  },
+
+  created() {
+
+
+  }
+};
+</script>
+
+<style scoped lang="less">
+
+  /* 父容器:垂直居中的关键 */
+  .checkbox-wrapper {
+    display: flex;
+    align-items: center;      /* 垂直居中 */
+    gap: 8px;                 /* 图标与文字间距 */
+    margin-bottom: 0.2rem;
+    font-size: 0.28rem;
+    color: #89919F;
+  }
+
+  /* 隐藏原生的 checkbox */
+  .hidden-checkbox {
+    position: absolute;
+    opacity: 0;
+    width: 0;
+    height: 0;
+  }
+
+  /* 自定义 checkbox 框 */
+  .custom-checkbox {
+    position: relative;
+    width: 14px;
+    height: 14px;
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    cursor: pointer;
+    transition: all .2s;
+    flex-shrink: 0;           /* 防止被压缩 */
+  }
+
+  /* 选中背景 */
+  .hidden-checkbox:checked + .custom-checkbox {
+    background: #409eff;
+    border-color: #409eff;
+  }
+
+  /* 选中对勾 */
+  .hidden-checkbox:checked + .custom-checkbox::after {
+    content: "";
+    position: absolute;
+    left: 0.06rem;
+    top: 0.02rem;
+    width: 5px;
+    height: 8px;
+    border: solid #fff;
+    border-width: 0 2px 2px 0;
+    transform: rotate(45deg);
+  }
+
+  /* label 文字样式(可选) */
+  .checkbox-label {
+    cursor: pointer;
+    user-select: none;
+    line-height: 1.4;
+  }
+
+  .van-action-sheet__content /deep/ .van-picker-column.column-1 {
+    flex: 0 0 240px !important;
+    max-width: 240px !important;
+  }
+
+  .color-red {
+    padding: 0.05rem 0.2rem;
+    box-sizing: border-box;
+    background-color: #fef0f0;
+    border: 0.02rem solid #fde2e2;
+    color: #f56c6c !important;
+  }
+
+  .color-green {
+    padding: 0.05rem 0.2rem;
+    box-sizing: border-box;
+    background-color: #f0f9eb;
+    border: 0.02rem solid #e1f3d8;
+    color: #67c23a !important;
+  }
+
+  .color-gray {
+    padding: 0.05rem 0.2rem;
+    box-sizing: border-box;
+    background-color: #f4f4f5;
+    border: 0.02rem solid #e9e9eb;
+    color: #909399 !important;
+  }
+
+  .dept-list {
+    padding: 0.2rem;
+    box-sizing: border-box;
+    .dept-item {
+      box-sizing: border-box;
+      padding-left: 0.3rem;
+      height: 0.8rem;
+      &-name {
+        font-size: 0.28rem;
+        color: #89919F;
+      }
+    }
+  }
+
+  .statementHnum {
+    display: flex;
+    flex-wrap: wrap;
+    width: 100%;
+    padding: 0 0.2rem;
+    margin-top: 0.2rem;
+    .Hnumvfor {
+      flex: 0 0 calc((100% - 1rem) / 4);
+      position: relative;
+      background-color: #ECF5FF;
+      border-radius: 3px;
+      text-align: center;
+      margin: 0 0.2rem 0.2rem 0;
+      padding: 0.1rem 0.2rem;
+      box-sizing: border-box;
+      &:nth-child(4n) {
+        /* 去除第5n个的margin-right */
+        margin-right: 0;
+      }
+      .smHnLnum {
+        font-size: 0.42rem;
+        color: #00a1ff;
+      }
+      .smHnLtit {
+        font-size: 0.26rem;
+        color: #8a8a8a;
+      }
+    }
+  }
+
+.selectItem {
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  border-top: 0.02rem solid #f1f1f1;
+  text-align: center;
+  font-size: 0.28rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+  }
+}
+
+header {
+  .selector {
+    z-index: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 0.8rem;
+    line-height: 0.8rem;
+    background-color: #fff;
+    text-align: center;
+    font-size: 0.28rem;
+    i {
+      margin: 0 0 0 0.1rem;
+      color: #c3c3c3;
+    }
+    span {
+      max-width: 3.5rem;
+      overflow: hidden;
+    }
+  }
+}
+
+.all {
+  height: calc(100% - 1.92rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+  .statementHead {
+    width: 100%;
+    text-align: center;
+    // padding-top: 0.35rem;
+    background-color: #fff;
+    .statementpropnum {
+      background-color: #f5f7fa;
+      padding: 0.3rem 0 0.1rem;
+      .propnumrel1 {
+        /deep/ .van-progress__pivot {
+          margin-left: -0.11rem;
+        }
+      }
+      .propnumrel {
+        position: relative;
+        padding: 0 0.15rem;
+        /deep/ .van-progress {
+          border-radius: 0.5rem;
+          .van-progress__portion {
+            border-radius: 0.14rem;
+            .van-progress__pivot {
+              border-radius: 50%;
+              min-width: 0.33rem !important;
+              height: 0.33rem;
+              right: 0;
+              // margin-left: -.11rem;
+            }
+          }
+        }
+        .propnumcol {
+          position: absolute;
+          top: 0;
+          right: 0.4rem;
+          font-size: 0.25rem;
+          color: #fff;
+        }
+        .numelzi {
+          font-size: 0.26rem;
+          margin: 0.25rem 0;
+          .numelzh {
+            color: #000000;
+          }
+          .numelzl {
+            color: #0597ff;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            i {
+              margin: 0.06rem 0 0 0.02rem;
+            }
+          }
+        }
+      }
+    }
+    .circle {
+      margin-top: 0.7rem;
+      .circletit {
+        font-size: 0.24rem;
+        color: #6f6f6f;
+      }
+      .circleclic {
+        color: #4ba0f1;
+        .circleclics1 {
+          font-size: 0.42rem;
+          display: inline-block;
+          margin: 0.1rem 0;
+        }
+        .circleclics2 {
+          font-size: 0.25rem;
+          display: flex;
+          justify-content: center;
+          i {
+            margin: 0.06rem 0 0 0.02rem;
+          }
+        }
+      }
+    }
+
+  }
+  .statementFoot {
+    background-color: #fff;
+    margin-top: 0.2rem;
+    .statmentperson {
+      padding: 0.25rem 0.2rem;
+      font-size: 0.32rem;
+      box-sizing: border-box;
+      .score-result {
+        width: 0.4rem;
+        height: 0.4rem;
+        border: 0.02rem solid #409EFF;
+        color: #409EFF;
+        border-radius: 50%;
+        font-size: 0.26rem;
+        text-align: center;
+        line-height: 0.4rem;
+        margin-right: 0.1rem;
+      }
+    }
+  }
+}
+
+.takI {
+  font-size: 0.27rem;
+  color: #f7b461;
+  i {
+    margin: 0.1rem 0.05rem 0 0;
+  }
+}
+
+.statmentAnalysePie {
+  position: relative;
+  .PiePropNum {
+    width: 1.5rem;
+    text-align: center;
+    position: absolute;
+    left: 20%;
+    top: 42%;
+    font-size: 0.3rem;
+  }
+}
+
+.review-status {
+  // padding: 0.01rem 0.1rem;
+  width: 1.2rem;
+  height: 0.4rem;
+  text-align: center;
+  line-height: 0.4rem;
+  color: #fff;
+  border-radius: 2px;
+  font-size: 0.26rem;
+  background-color: #67c23a;
+  margin-right: 0.14rem;
+  margin-bottom: 0.1rem;
+}
+
+.indicator-list-title {
+  padding: 0.2rem 0.2rem 0 0.2rem;
+  box-sizing: border-box;
+  font-size: 0.28rem;
+}
+
+.indicator-list {
+  padding: 0.2rem;
+  box-sizing: border-box;
+  .indicator-item {
+    background-color: white;
+    margin-bottom: 0.2rem;
+    padding: 0.2rem;
+    box-sizing: border-box;
+    border-radius: 8px;
+    .indicator-item-info {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      font-size: 0.28rem;
+      margin-bottom: 0.2rem;
+      .indicator-info-label {
+        width: 2rem;
+        color: black;
+      }
+      .indicator-info-value {
+        flex: 1;
+        text-align: right;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        color: #89919F;
+      }
+
+    }
+  }
+}
+
+
+.van-picker__columns  .van-picker-column:nth-child(2) {
+  background-color: red !important;
+}
+</style>

+ 963 - 0
src/newPerformance/view/navhome/statement.vue

@@ -0,0 +1,963 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="过程跟踪" left-text="返回" left-arrow @click-left="$route_back">
+      <!-- <div slot="right" @click="isShowPopup = true" style="color: #fff;">筛选<van-icon name="list-switch" /></div> -->
+    </van-nav-bar>
+    <header>
+      <div style="border-bottom: 1px solid #f1f1f1;" class="selector flex-box-ce flex-center-center fontColorC" @click="isShowPopup = true">
+        <icon name="YMPicker_item_icon" style="margin-right: 6px; width: 0.3rem; height: 0.3rem;" class="fontColorC"></icon>
+        <div v-show='cycleId == "4"' style="margin-right: 6px;">月度</div>
+        <div v-show='cycleId == "3"' style="margin-right: 6px;">季度</div>
+        <div v-show='cycleId == "2"' style="margin-right: 6px;">半年度</div>
+        <div v-show='cycleId == "1"' style="margin-right: 6px;">年度</div>
+        <div v-show='cycleId !== "0"'>{{ yearId }}年</div>
+        <div v-show='cycleId == "4"' style="margin: 0 6px;">{{ monthId }}月</div>
+        <div v-show='cycleId == "3"' style="margin: 0 6px;">第{{ quarterId }}季度</div>
+        <div v-show='cycleId == "2"' style="margin: 0 6px;">
+          {{ halfYearId == 1 ? "上半年" : "下半年" }}
+        </div>
+        <div v-show='cycleId == "0"' style="margin: 0 6px;">
+          自定义&nbsp;{{ timeStr }}
+        </div>
+        <van-icon class="fontColorC" name="arrow-down" size="12" />
+      </div>
+    </header>
+
+
+    <VanSkeleton :skeLoad="skeletonLoad" v-if="isYou">
+      <template>
+        <scroller ref="me_scroller" class="all">
+          <div style="padding-bottom: 1.5rem;">
+            <div class="statementHead">
+              <div class="statementpropnum">
+                <div class="propnumrel" :class="{ propnumrel1: theProgressOf.complete != 0 }">
+                  <van-progress
+                    :percentage="rate"
+                    stroke-width="16"
+                    pivot-text="''"
+                    :show-pivot="theProgressOf.complete != theProgressOf.theTotalNum"
+                    pivot-color="#FFF"
+                    track-color="#26a2ff"
+                    color="rgb(255, 173, 103)"
+                  />
+                  <div class="propnumcol"></div>
+                  <div class="flex-box flex-d-center numelzi">
+                    <span class="numelzh">
+                      考核进度:
+                      <span style="color: rgb(255, 173, 103);">{{ theProgressOf.complete }}人</span>
+                      /
+                      <span style="color: #26a2ff;">{{ theProgressOf.theTotalNum }}人</span>
+                    </span>
+                  </div>
+                </div>
+              </div>
+              <div class="statementHnum">
+
+                <!-- <div v-for="(item, index) in generalizeList" class="Hnumvfor" :key="index">
+                  <span class="smHnLtit">{{ item.name }}</span>
+                  <br />
+                  <span class="smHnLtit"></span>
+                  <br />
+                  <span class="smHnLnum">{{ item.val }}</span>
+                </div> -->
+
+                <div v-for="(item, index) in gradeLevels" class="Hnumvfor" :key="index">
+                  <span class="smHnLtit">{{ item.name }}</span>
+                  <br />
+                  <span class="smHnLtit">({{ item.min }}~{{ item.max }})</span>
+                  <br />
+                  <span class="smHnLnum">{{ recordList.filter(user => user.levelName === item.name).length }}</span>
+                </div>
+              </div>
+            </div>
+
+            <div class="statementFoot">
+
+              <div>
+                <div>
+                  <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+                  <div class="flex-box-ce" style="margin-bottom: 0.2rem;">
+                    <div class="selectItem flex-1 font-flex-word fontColorC"  @click="showDept = true">
+                      <span>{{ deptName }}</span>
+                      <van-icon name="arrow-down" size="12" />
+                    </div>
+
+                    <div class="selectItem flex-1 font-flex-word fontColorC" @click="showStatus = true">
+                      <span>{{ '状态' }}</span>
+                      <van-icon name="arrow-down" size="12" />
+                    </div>
+                  </div>
+                  <ol v-if="filterUsers && filterUsers.length > 0" style=" background-color: #f5f7fa;">
+                    <li @click="openDetail(item)" v-for="(item, index) in filterUsers" :key="item.reviewId" class="flex-ce-box flex-d-center statmentperson">
+
+                      <div class="flex-1 flex-box" style="align-items: center; justify-content: space-between;">
+
+                        <div class="flex-box-ce flex-1">
+                          <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-top:.08rem;"></userImage>
+                          <div style="padding-left:.2rem;">
+                            <span style="font-size:.3rem;">{{ item.userInfo.name }}</span>
+                            <br />
+                            <span class="font-flex-word" style="width: 3.8rem;display:inline-block;" v-if="item.dept_list && item.dept_list.length > 0">
+                              <span style="font-size:.25rem;" v-for="(arr, att) in item.dept_list" :key="att">
+                                {{ arr.dept_name }}
+                                <span v-if="item.dept_list.length - att > 1">,</span>
+                              </span>
+                            </span>
+                          </div>
+                        </div>
+
+                        <div style="display: flex; align-items: center; flex-direction: column;">
+                          <div v-if="item.status == 0" class="review-status">进行中</div>
+                          <div v-if="item.status == 1" class="review-status" style="background-color: #FF9600;">已结束</div>
+                          <div style="display: flex; align-items: center; white-wrap: no-wrap; font-size:.26rem; text-align:center; overflow: hidden;">
+
+                            <span>{{ item.score == undefined || item.score == null || item.score == ''  ? '-' : item.score }}</span>
+                            &nbsp;/&nbsp;
+                            <span style="color:#ffad67;">{{ item.levelName ? item.levelName : '--'}}</span>
+                          </div>
+                        </div>
+                      </div>
+                      <div class="flex-box-ce fontColorC" style="font-size: 0.28rem;">
+                        <van-icon name="clock-o" size="16" style="margin-right: 0.16rem;"/>
+                        {{ item.startTime | formatDate }} - {{ item.endTime | formatDate }}
+                      </div>
+
+                    </li>
+                  </ol>
+                  <noData v-else content="无考核记录"></noData>
+                </div>
+              </div>
+            </div>
+          </div>
+        </scroller>
+      </template>
+    </VanSkeleton>
+    <noData content="无考核记录" v-else></noData>
+
+
+
+    <!-- 部门搜索 -->
+    <van-dialog v-model="showDept" width="300" confirm-button-text="确定" @confirm="handleConfirm" @cancel="handleCancel" :show-confirm-button="true" closeOnClickOverlay>
+       <div style="max-height: 8rem; overflow: auto; " class="scroll-bar">
+         <div class="dept-list">
+
+           <div class="checkbox-wrapper" v-for="(item, index) in department_list" :key="index">
+             <input type="checkbox" :id="'dept' + (index+1)" class="hidden-checkbox" v-model="item.select">
+             <label :for="'dept' + (index+1)" class="custom-checkbox"></label>
+             <label :for="'dept' + (index+1)" class="checkbox-label">
+               {{ item.dept_name }}
+             </label>
+           </div>
+         </div>
+       </div>
+    </van-dialog>
+
+
+
+    <van-popup v-model="isShowPopup" position="right" style="height: 100%; left: 15%;">
+      <div style="position: relative;height: 100%;">
+        <div style="font-size: 16px;font-weight: 700;height: 0.92rem;line-height: 0.92rem;padding: 0 0.2rem;"></div>
+
+        <div style="padding: 0.1rem;">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">周期类型</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in cycleOptions" :key="index" :class="cycleId == item.id ? 'searchActive' : ''" @click="cycleId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId !== '0'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">年度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in yearOptions" :key="index" :class="yearId == item.id ? 'searchActive' : ''" @click="yearId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '2'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">半年度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in halfYearOptions" :key="index" :class="halfYearId == item.id ? 'searchActive' : ''" @click="halfYearId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '3'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">季度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in quarterOptions" :key="index" :class="quarterId == item.id ? 'searchActive' : ''" @click="quarterId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '4'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">月度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in monthOptions" :key="index" :class="monthId == item.id ? 'searchActive' : ''" @click="monthId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '0'">
+          <div style="margin-bottom: 15px; font-size: 0.3rem;">自定义时间</div>
+            <div class="flex-box-ce blue">
+              <span @click="calendarOpen()" style="font-size: 0.28rem;">{{ timeStr }}</span>
+              <van-icon name="arrow-down" size="12"/>
+            </div>
+        </div>
+
+        <div style="position: fixed;bottom: 0.2rem;left: 0.2rem;right: 0.2rem;">
+          <div class="search-btn" @click="doSearch()">确认</div>
+        </div>
+      </div>
+    </van-popup>
+
+
+
+
+    <!-- 日期选择框 -->
+    <van-calendar
+      v-model="showCalendar"
+      type="range"
+      :allow-same-day="true"
+      :min-date="minDate"
+      :max-date="maxDate"
+      :default-date="timeScope"
+      :show-confirm="false"
+      color="#26A2FF"
+      @close="calendarClose"
+      @confirm="calendarConfirm"
+    >
+      <template v-slot:title>
+        <van-row>
+          <van-col span="20">
+            <van-row type="flex" justify="space-between" style="height: 1rem;">
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeThisWeek">本周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeLastWeek">上周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeThisMoth">本月</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeLastMonth">上月</van-tag>
+              </van-col>
+            </van-row>
+          </van-col>
+        </van-row>
+      </template>
+    </van-calendar>
+
+
+
+
+    <!-- 状态 -->
+    <van-dialog v-model="showStatus" title="" width="300" confirm-button-text="确定" @confirm="handleStatusConfirm" @cancel="handleStatusCancel"  :show-confirm-button="true" closeOnClickOverlay>
+      <van-radio-group v-model="statusId">
+        <div v-for="(item, index) in statusList" :key="index">
+          <van-radio :name="item.value" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.text }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import { Picker, ActionSheet, Circle, Tab, Tabs, Skeleton, DropdownMenu, DropdownItem, Progress, Calendar } from 'vant';
+import moment from 'moment';
+import { _debounce } from '@/utils/auth';
+
+Vue.use(Picker)
+  .use(ActionSheet)
+  .use(Circle)
+  .use(Tab)
+  .use(Tabs)
+  .use(Skeleton)
+  .use(DropdownMenu)
+  .use(DropdownItem)
+  .use(Progress)
+  .use(Calendar);
+export default {
+  name: "newStatement",
+  data() {
+
+    let startDate = new Date();
+    startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * 7);
+    startDate = moment(startDate).format('YYYY-MM-DD');
+    let endDate = moment().format('YYYY-MM-DD');
+
+    let today = new Date();
+    let minDate = new Date();
+    minDate.setTime(today.getTime() - 3600 * 1000 * 24 * 30 * 6);
+    let maxDate = new Date(today.getFullYear(), today.getMonth(), 1);
+    maxDate.setMonth(maxDate.getMonth() + 1);
+    maxDate.setDate(0);
+
+
+    return {
+      skeletonLoad: true, //
+      isShowPopup: false,
+      timeStr: "请选择时间",
+      showCalendar: false,
+
+      generalizeList: [
+        { name: '考核人数', val: 0, color: '#FF9600' },
+        { name: '已结束', val: 0, color: '#409EFF' },
+        { name: '进行中', val: 0, color: '#67c23a' },
+      ],
+
+      minDate: minDate,
+      maxDate: maxDate,
+      timeScope: [new Date(startDate), new Date(endDate)],
+
+      cycleId: '4',
+      cycleOptions: [
+        { name: "月度", text: "月度", value: '4', id: '4' },
+        { name: "季度", text: "季度", value: '3', id: '3' },
+        { name: "半年度", text: "半年度", value: '2', id: '2' },
+        { name: "年度", text: "年度", value: '1', id: '1' },
+        { name: "自定义", text: "自定义", value: '0', id: '0' }
+      ],
+
+      yearId: '2025',
+      yearOptions: [
+        { name: "2020", text: "2020", value: '2020', id: '2020' },
+        { name: "2021", text: "2021", value: '2021', id: '2021' },
+        { name: "2022", text: "2022", value: '2022', id: '2022' },
+        { name: "2023", text: "2023", value: '2023', id: '2023' },
+        { name: "2024", text: "2024", value: '2024', id: '2024' },
+        { name: "2025", text: "2025", value: '2025', id: '2025' },
+        { name: "2026", text: "2026", value: '2026', id: '2026' },
+        { name: "2027", text: "2027", value: '2027', id: '2027' },
+        { name: "2028", text: "2028", value: '2028', id: '2028' },
+        { name: "2029", text: "2029", value: '2029', id: '2029' },
+        { name: "2030", text: "2030", value: '2030', id: '2030' }
+      ],
+
+      halfYearId: '1',
+      halfYearOptions: [
+        { name: "上半年", text: "上半年", id: '1' },
+        { name: "下半年", text: "上半年", id: '2' }
+      ],
+
+      quarterId: '1',
+      quarterOptions: [
+        {name: "第一季度", text: "第一季度", id: '1'},
+        {name: "第二季度", text: "第二季度", id: '2'},
+        {name: "第三季度", text: "第三季度", id: '3'},
+        {name: "第四季度", text: "第四季度", id: '4'},
+      ],
+
+      monthId: '1',
+      monthOptions: [
+        {name: "一月", text: "一月", id: '1'},
+        {name: "二月", text: "二月", id: '2'},
+        {name: "三月", text: "三月", id: '3'},
+        {name: "四月", text: "四月", id: '4'},
+        {name: "五月", text: "五月", id: '5'},
+        {name: "六月", text: "六月", id: '6'},
+        {name: "七月", text: "七月", id: '7'},
+        {name: "八月", text: "八月", id: '8'},
+        {name: "九月", text: "九月", id: '9'},
+        {name: "十月", text: "十月", id: '10'},
+        {name: "十一月", text: "十一月", id: '11'},
+        {name: "十二月", text: "十二月", id: '12'}
+      ],
+
+      dateParameter: {
+        year: this.$moment().format('YYYY'),
+        cycle_type: 0,
+        dateId: 1,
+        name: '全部周期'
+      },
+
+      theProgressOf: {
+        complete: 0,
+        theTotalNum: 0
+      },
+      currentRate: 0,
+      rate: 0,
+      keyword: '',
+      deptName: '全部部门',
+      department_list: [],
+      showDept: false,
+      deptId: '',
+
+      statusList: [
+        {
+          id: 0, text: "全部", value: "-1"
+        },
+        {
+          id: 1, text: "进行中", value: "0"
+        },
+        {
+          id: 2, text: "已结束", value: "1"
+        },
+      ],
+      showStatus: false,
+      statusId: "-1",
+      statusName: "状态",
+
+      recordList: [],
+      filterUsers: [],
+      userInfo: this.$userInfo(),
+      gradeLevels: [], // 全局等级配置
+      isYou: true,
+      params: {
+        cycleType: 1,
+        startDate: '',
+        endDate: '',
+        deptIds: '',
+        year: 2025
+      },
+
+    };
+  },
+
+  components: { VanSkeleton },
+
+  filters: {
+
+    formatDate(val) {
+      if (val) return moment(val).format('YYYY-MM-DD')
+      else return "--"
+    },
+
+  },
+
+  methods: {
+
+    // 本周
+    timeScopeThisWeek(){
+      this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
+      this.showCalendar= false
+    },
+    // 上周
+    timeScopeLastWeek(){
+      this.timeScope = [new Date(moment().subtract(1,'week').startOf('week').format('YYYY-MM-DD')),new Date(moment().subtract(1,'week').endOf('week').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+    // 本月
+    timeScopeThisMoth(){
+      this.timeScope = [new Date(moment().startOf('month').format('YYYY-MM-DD')),new Date(moment().endOf('month').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+    // 上周
+    timeScopeLastMonth(){
+      this.timeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+
+
+    calendarOpen(){
+      this.showCalendar = true;
+    },
+
+    calendarClose(){
+      this.showCalendar = false;
+    },
+
+    calendarConfirm(event){
+      const [start, end] = event;
+      this.timeScope = [start, end];
+      this.params.startDate = moment(this.timeScope[0]).format('YYYY-MM-DD')
+      this.params.endDate = moment(this.timeScope[1]).format('YYYY-MM-DD')
+      if(start && end)  this.timeStr = this.params.startDate + "-" + this.params.endDate;
+      else this.timeStr = "请选择时间"
+      this.showCalendar = false;
+    },
+
+
+    openDetail(item){
+      this.$router.push({ path: '/newMe', query: { reviewId: item.reviewId, employeeId: item.employeeId } });
+    },
+
+    // 搜索 - 关注的人
+    keyVal: _debounce(function() {
+      this.filteredData();
+      // if(!this.keyword) this.filterUsers = this.recordList
+      // // let filterUsers = []
+      // if(this.recordList && this.recordList.length > 0) {
+      //   this.filterUsers = this.recordList.filter(item => item.employeeName.includes(this.keyword.trim()))
+      // }
+    }),
+
+    handleConfirm() {
+      this.deptId = this.department_list.filter(item => item.select).map(item => item.dept_id).toString()
+      if(this.deptId && this.deptId.length > 0) {
+        this.deptName = ''
+        this.department_list.filter(item => item.select).forEach(dept => {
+          this.deptName += dept.dept_name + ","
+        })
+        this.deptName = this.deptName.substring(0, this.deptName.length - 1)
+      }else {
+        this.deptName = '全部部门'
+      }
+      this.showDept = false;
+      this.getData(true);
+    },
+
+
+
+    handleCancel() {
+      this.showDept = false;
+    },
+
+    handleStatusConfirm() {
+      this.filteredData();
+      this.statusName = this.statusList.find(item => item.value == this.statusId).text || '状态'
+      this.showStatus = false
+    },
+
+    handleStatusCancel() {
+      this.showStatus = false;
+    },
+
+
+
+    // 获取全局等级设置
+    async getAllLevelSet() {
+      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;//最大值
+      let colorList = ['#5F7294', '#08EEA1', '#f56c6c', '#0887EE', '#92EE08', '#f56c6c']
+      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 };//当不是第一个等级时,最小值为上一个的最大值
+            }
+            obj.color = colorList[index]
+            max = item.value;
+            gradeLevels.push(obj);
+          })
+          this.gradeLevels = gradeLevels
+        }
+    },
+
+    getData(byDept = false) {
+      let url = `/performance/statistics/reviews/${this.userInfo.site_id}`;
+      let params = {
+        cycleType: this.cycleId,
+        startDate: '',
+        endDate: '',
+        deptIds: this.deptId,
+        cycleValue: 7,
+        year: this.yearId
+      }
+
+      // 月度
+      if(this.cycleId == '4') params.cycleValue = this.monthId
+      // 季度
+      if(this.cycleId == '3') params.cycleValue = this.quarterId
+      // 半年度
+      if(this.cycleId == '2') params.cycleValue = this.halfYearId
+      // 年度,自定义
+      if(this.cycleId == '1' || this.cycleId == '0') {
+        delete params.cycleValue
+
+      }
+      if(this.cycleId == '0') {
+        params.startDate = this.params.startDate
+        params.endDate = this.params.endDate
+      }
+
+      this.$axiosUser("get", url, params).then(res => {
+        if (res.data.code == 1) {
+          let recordList = res.data.data.list;
+          if(recordList.length == 0) {
+            this.isYou = false
+            return false
+          } else {
+            this.isYou = true
+            let theOf = this.theProgressOf;
+            theOf.complete = recordList.filter(item => item.status == 1).length || 0 // 已完成人数
+            theOf.theTotalNum = res.data.data.total; // 总人数
+            let rate = (theOf.complete / theOf.theTotalNum) * 100; // 进度条百分比
+            if(!isNaN(rate)){
+              this.rate = rate; // 进度条百分比
+            }
+            this.deptName = '全部部门'
+            if(!byDept) this.department_list = []
+            recordList.forEach(item => {
+              item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+              item.dept_list = this.$getEmployeeMapItem(item.employeeId).employee_detail.dept_list;
+              if(!byDept && item.dept_list && item.dept_list.length > 0) {
+                item.dept_list.forEach(dept => {
+                  item.select = false
+                  this.department_list.push(dept)
+                })
+                this.department_list = Array.from(
+                    new Set(this.department_list.map(item => JSON.stringify(item)))
+                ).map(item => JSON.parse(item));
+              }
+            })
+
+
+            this.generalizeList[0].val = recordList.length // 总人数
+            this.generalizeList[1].val = recordList.filter(item => item.status == 1).length // 已结束人数
+            this.generalizeList[2].val = recordList.filter(item => item.status == 0).length // 进行中人数
+
+          }
+          // 按分数排序
+          recordList = recordList.slice().sort((a, b) => b.score - a.score);
+          this.recordList = recordList
+          this.filterUsers = recordList
+          this.skeletonLoad = false
+        }
+      })
+
+    },
+
+
+    // 实时过滤后数据
+    filteredData() {
+      const keyword = this.keyword.trim();
+      this.filterUsers = this.recordList.filter((item) => {
+        const keywordMatch = !keyword || item.employeeName.includes(keyword);
+        // 状态筛选:如果选了“全部”,则不过滤;否则按状态过滤
+        const statusMatch = this.statusId == '-1' || item.status == this.statusId;
+        return keywordMatch && statusMatch;
+      });
+
+    },
+
+    doSearch() {
+      this.isShowPopup = false;
+      this.getData()
+    },
+
+  },
+
+
+
+  async created() {
+    this.monthId = new Date().getMonth() + 1; // 默认当月
+    await this.getAllLevelSet();
+    await this.getData();
+  }
+
+};
+</script>
+
+<style scoped lang="less">
+  /* 父容器:垂直居中的关键 */
+  .checkbox-wrapper {
+    display: flex;
+    align-items: center;      /* 垂直居中 */
+    gap: 8px;                 /* 图标与文字间距 */
+    margin-bottom: 0.2rem;
+    font-size: 0.28rem;
+    color: #89919F;
+  }
+
+  /* 隐藏原生的 checkbox */
+  .hidden-checkbox {
+    position: absolute;
+    opacity: 0;
+    width: 0;
+    height: 0;
+  }
+
+  /* 自定义 checkbox 框 */
+  .custom-checkbox {
+    position: relative;
+    width: 14px;
+    height: 14px;
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    cursor: pointer;
+    transition: all .2s;
+    flex-shrink: 0;           /* 防止被压缩 */
+  }
+
+  /* 选中背景 */
+  .hidden-checkbox:checked + .custom-checkbox {
+    background: #409eff;
+    border-color: #409eff;
+  }
+
+  /* 选中对勾 */
+  .hidden-checkbox:checked + .custom-checkbox::after {
+    content: "";
+    position: absolute;
+    left: 0.06rem;
+    top: 0.02rem;
+    width: 5px;
+    height: 8px;
+    border: solid #fff;
+    border-width: 0 2px 2px 0;
+    transform: rotate(45deg);
+  }
+
+  /* label 文字样式(可选) */
+  .checkbox-label {
+    cursor: pointer;
+    user-select: none;
+    line-height: 1.4;
+  }
+
+
+/deep/ .van-calendar__header-subtitle {
+  width: 100%;
+  font-size: 0.28rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+
+.selectItem {
+  height: 0.6rem;
+  line-height: 0.6rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.28rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+  }
+}
+
+header {
+  .selector {
+    z-index: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 0.8rem;
+    line-height: 0.8rem;
+    background-color: #fff;
+    text-align: center;
+    font-size: 0.28rem;
+    i {
+      margin: 0 0 0 0.1rem;
+      color: #c3c3c3;
+    }
+    span {
+      max-width: 3.5rem;
+      overflow: hidden;
+    }
+  }
+}
+
+.all {
+  height: calc(100% - 1.92rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+  .statementHead {
+    width: 100%;
+    text-align: center;
+    // padding-top: 0.35rem;
+    background-color: #fff;
+    .statementpropnum {
+      background-color: #f5f7fa;
+      padding: 0.3rem 0 0.1rem;
+      .propnumrel1 {
+        /deep/ .van-progress__pivot {
+          margin-left: -0.11rem;
+        }
+      }
+      .propnumrel {
+        position: relative;
+        padding: 0 0.15rem;
+        /deep/ .van-progress {
+          border-radius: 0.5rem;
+          .van-progress__portion {
+            border-radius: 0.14rem;
+            .van-progress__pivot {
+              border-radius: 50%;
+              min-width: 0.33rem !important;
+              height: 0.33rem;
+              right: 0;
+              // margin-left: -.11rem;
+            }
+          }
+        }
+        .propnumcol {
+          position: absolute;
+          top: 0;
+          right: 0.4rem;
+          font-size: 0.25rem;
+          color: #fff;
+        }
+        .numelzi {
+          font-size: 0.26rem;
+          margin: 0.25rem 0;
+          .numelzh {
+            color: #000000;
+          }
+          .numelzl {
+            color: #0597ff;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            i {
+              margin: 0.06rem 0 0 0.02rem;
+            }
+          }
+        }
+      }
+    }
+    .circle {
+      margin-top: 0.7rem;
+      .circletit {
+        font-size: 0.24rem;
+        color: #6f6f6f;
+      }
+      .circleclic {
+        color: #4ba0f1;
+        .circleclics1 {
+          font-size: 0.42rem;
+          display: inline-block;
+          margin: 0.1rem 0;
+        }
+        .circleclics2 {
+          font-size: 0.25rem;
+          display: flex;
+          justify-content: center;
+          i {
+            margin: 0.06rem 0 0 0.02rem;
+          }
+        }
+      }
+    }
+
+    .statementHnum {
+
+        display: flex;
+        flex-wrap: wrap;
+        width: 100%;
+        padding: 0.2rem 0.2rem 0 0.2rem;
+        .Hnumvfor {
+          flex: 0 0 calc((100% - 1rem) / 4);
+          position: relative;
+          background-color: #ECF5FF;
+          border-radius: 3px;
+          text-align: center;
+          margin: 0 0.2rem 0.2rem 0;
+          padding: 0.1rem 0.2rem;
+          box-sizing: border-box;
+          &:nth-child(4n) {
+            /* 去除第5n个的margin-right */
+            margin-right: 0;
+          }
+          .smHnLnum {
+            font-size: 0.42rem;
+            color: #00a1ff;
+          }
+          .smHnLtit {
+            font-size: 0.26rem;
+            color: #8a8a8a;
+          }
+        }
+
+    }
+  }
+  .statementFoot {
+    background-color: #fff;
+    margin-top: 0.2rem;
+    .statmentperson {
+      width: 96%;
+      margin: 0.2rem auto 0 auto;
+      padding: 0.25rem 0.2rem;
+      font-size: 0.32rem;
+      box-sizing: border-box;
+      border-radius: 8px;
+      background-color: #fff;
+    }
+  }
+}
+
+.takI {
+  font-size: 0.27rem;
+  color: #f7b461;
+  i {
+    margin: 0.1rem 0.05rem 0 0;
+  }
+}
+
+.statmentAnalysePie {
+  position: relative;
+  .PiePropNum {
+    width: 1.5rem;
+    text-align: center;
+    position: absolute;
+    left: 20%;
+    top: 42%;
+    font-size: 0.3rem;
+  }
+}
+
+.review-status {
+  // padding: 0.01rem 0.1rem;
+  width: 1.2rem;
+  height: 0.4rem;
+  text-align: center;
+  line-height: 0.4rem;
+  color: #fff;
+  border-radius: 2px;
+  font-size: 0.26rem;
+  background-color: #67c23a;
+  margin-right: 0.14rem;
+  margin-bottom: 0.1rem;
+}
+
+
+.search-item {
+  padding: 0.06rem 0.1rem;
+  background-color: #F7F8FA;
+  color: #89919F;
+  width: 1.2rem;
+  text-align: center;
+  margin-right: 0.1rem;
+  margin-bottom: 0.2rem;
+  border-radius: 3px;
+  font-size: 0.3rem;
+}
+
+
+.searchActive{
+  color: #26A2FF;
+  background-color: #E9F0FD;
+}
+.search-btn{
+  background-color: #26A2FF;
+  color: #fff;
+  text-align: center;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  border-radius: 25px;
+}
+
+.dept-list {
+  padding: 0.2rem;
+  box-sizing: border-box;
+  .dept-item {
+    box-sizing: border-box;
+    padding-left: 0.3rem;
+    height: 0.8rem;
+    &-name {
+      font-size: 0.28rem;
+      color: #89919F;
+    }
+  }
+}
+</style>

+ 782 - 0
src/newPerformance/view/navhome/workbench.vue

@@ -0,0 +1,782 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar :title="$getRole(3) || $getRole(4) ? '我的' : '工作台'" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all" style="position: relative;">
+      <header class="workHeader">
+        <van-row>
+          <van-col span="12" @click="backlog" class="headcol">
+            <span class="headicon">
+              <van-icon name="certificate" size=".4rem" />
+              <span>待办事项</span>
+            </span>
+            <em v-if="informNum.commission > 0" class="cunt" :class="{ cunts: informNum.commission > 99 }">
+              <i v-if="informNum.commission < 100">{{ informNum.commission }}</i>
+              <i v-else>99+</i>
+            </em>
+          </van-col>
+          <van-col span="12" @click="notification" class="headcol">
+            <span class="headicon">
+              <van-icon name="chat-o" size=".4rem" />
+              <span>消息通知</span>
+            </span>
+            <em v-if="informNum.information > 0" class="cunt" :class="{ cunts: informNum.information > 99 }">
+              <i v-if="informNum.information < 100">{{ informNum.information }}</i>
+              <i v-else>99+</i>
+            </em>
+          </van-col>
+        </van-row>
+      </header>
+      <van-tabs v-model="typeIndex">
+        <van-tab :title="item.title" :name="item.value" v-for="(item, index) in titles" :key="index"></van-tab>
+      </van-tabs>
+      <template v-if="typeIndex=='1'||typeIndex=='2'">
+          <div class="flex-box-ce">
+            <div class="selectItem " @click="statementTIme" style="width: 4.8rem;">
+              <template v-if="selectGlKgpText">
+                <span>{{ selectGlKgpText }}</span>
+                <van-icon name="arrow-down" />
+              </template>
+            </div>
+            <div class="selectItem" style="width: 3.2rem;" @click="selectGl=true">
+              <span>{{ selectGlText }}</span>
+              <van-icon name="arrow-down" />
+            </div>
+          </div>
+          <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+          <div class="event-list__content">
+            <scroller ref="perScroller" :on-refresh="refresh_two" :on-infinite="infinite_two" noDataText="我也是有底线的" :list="glDataList">
+              <van-cell-group>
+                  <div class="flex-box-ce list-item flex-d-wrap"  v-for="(item, index) in glDataList" :key="index"  @click="openDetail(item)">
+                    <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" :img_url="item.userInfo.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                    <div class="flex-1" style="margin-left: 0.24rem;">
+                       <div style="margin-bottom: 0.1rem;">{{item.userInfo.name}}</div>
+                       <div class="fontColorC font-flex-word" style="font-size: 0.28rem;width: 3.5rem;" v-if="item.dept_list.length>0">
+                           <span v-for="item2 in item.dept_list" :key="item2.dept_id">{{ item2.dept_name }}</span>
+                       </div>
+                    </div>
+                    <div>
+                      <div  style="font-size: 0.28rem;margin-bottom: 0.1rem;" class="flex-box-end">
+                        <template v-if="typeIndex==1">
+                          <span  class="green" v-if="item.count_record">{{item.count_record}}条管理记录</span>
+                          <span  class="fontColorC" v-else>无管理记录</span>
+                        </template>
+                        <template v-else>
+                          <span v-if="item.status==0" class="orange">未到评分节点</span>
+                          <span v-if="item.status==1" class="blue">待我评分</span>
+                          <span v-if="item.status==2" class="green">我已评分</span>
+                          <span v-if="item.status==3" class="green">已被其他管理评分</span>
+                        </template>
+                      </div>
+                      <div class="flex-box-end">
+                        <template v-if="typeIndex==1">
+                           <van-button plain type="info" size="small" v-if="!item.has_finish" @click.stop="complete(item)">填写管理记录</van-button>
+                           <span v-else class="yellow">已归档</span>
+                        </template>
+                        <van-button plain type="info" size="small" v-else>查看详情</van-button>
+                      </div>
+                    </div>
+                    <div style="width: 100%;" v-if="typeIndex=='1'">
+                      <template v-if="item.action_update">
+                         <div v-if="returnStr(item.action_update).indexOf('今天')>=0" class="orange" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else-if="returnStr(item.action_update).indexOf('昨天')>=0" class="green" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else-if="returnStr(item.action_update).indexOf('前天')>=0" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                      </template>
+
+
+                    </div>
+                  </div>
+              </van-cell-group>
+              <van-empty description="暂无内容" v-if="glDataList.length == 0" />
+            </scroller>
+          </div>
+      </template>
+
+      <template v-else>
+        <span v-if="$getRole(1) || $getRole(2)">
+          <div class="selector" @click="selectPfTIme">
+            <span>{{ selectPftiText.label }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+          <div class="event-list__content2">
+            <scroller ref="perScroller" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="performanceList">
+              <van-cell-group>
+                <div
+                  v-for="(item, index) in performanceList"
+                  :key="index"
+                  class="performanceList workbench_list"
+                  :style="'z-index:' + (performanceList.length - index)"
+                  @click="$router.push({ name: 'workList_details', query: { bagId: item.id, bagName: item.name } })"
+                >
+                  <div>{{ item.name }}</div>
+                  <span class="iconColor">
+                    <van-icon name="underway-o" />
+                    {{ item.date }}
+                  </span>
+                  <span>
+                    <van-icon name="friends-o" />
+                    {{ item.employee_num }}人参与
+                  </span>
+                </div>
+              </van-cell-group>
+              <van-empty :description="'暂无' + (selectPftiText.value == 0 ? '' : selectPftiText.label) + '绩效考核数据'" v-if="performanceList.length == 0" />
+            </scroller>
+          </div>
+        </span>
+        <div :class="[$getRole(3) || $getRole(4) ? 'meAll' : '']" v-else>
+          <scroller ref="me_scroller" class="all" :on-refresh="refresh1">
+            <footer style="padding-bottom:1rem;">
+              <div style="height:.2rem;background-color:#f5f7fa;"></div>
+              <van-empty description="暂无绩效考核数据" v-if="meList.length == 0" />
+              <div
+                v-else
+                class="me_list performanceList"
+                v-for="(item, index) in meList"
+                :key="index"
+                :style="'z-index:' + (meList.length - index)"
+                @click="$router.push({ name: 'performanceDetails', query: { id: item.id, Tit: item.package_name } })"
+              >
+                <div class="me_list_img">
+                  <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                </div>
+                <div class="me_list_content">
+                  <div class="me_list_tit">{{ item.package_name }}</div>
+                  <span v-if="item.current_node == 'result' || !item.current_node" class="me_list_result">
+                    <span v-if="item.result">
+                      <span class="me_list_col">绩效结果:</span>
+                      {{ item.result }}
+                      <br />
+                    </span>
+                    <span v-if="item.grade">
+                      <span class="me_list_col">绩效等级:</span>
+                      {{ item.grade }}
+                      <br />
+                    </span>
+                    <span class="me_list_resultTit">考核结束</span>
+                  </span>
+                  <div v-else class="me_list_course">
+                    {{
+                      item.current_node == 'target'
+                        ? '目标制定'
+                        : item.current_node == 'confirm'
+                        ? '目标确定'
+                        : item.current_node == 'execution'
+                        ? '执行中'
+                        : item.current_node == 'result_value'
+                        ? '结果值录入'
+                        : item.current_node == 'score' || item.current_node == 'special_scorer'
+                        ? '评分'
+                        : item.current_node == 'review'
+                        ? '审批'
+                        : ''
+                    }}
+                  </div>
+                </div>
+              </div>
+            </footer>
+          </scroller>
+        </div>
+      </template>
+    </div>
+
+    <van-dialog v-model="selectpfdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectpradio">
+          <van-radio v-for="(item, index) in selectpfList" :key="index" :name="item.value" @click="clickpfTime(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.label }}</span>
+          </van-radio>
+      </van-radio-group>
+    </van-dialog>
+    <!-- 管理记录筛选 -->
+    <van-dialog v-model="selectGl" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectGlVal">
+        <div v-for="(item, index) in selectGlType" :key="index">
+          <van-radio :name="item.value" @click="clickGlConfirm(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.label }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="onCancel" value-key="name" @confirm="onConfirm" confirm-button-text="确定" />
+      </div>
+    </van-action-sheet>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import {Tab, Tabs,Search} from 'vant'
+import moment from 'moment';
+import { _debounce, _throttle } from '@/utils/auth';
+Vue.use(Tabs).use(Tab).use(Search);
+export default {
+  data() {
+    return {
+      informNum: { commission: 0, information: 0 }, // 待办事项消息数
+      selectpfdlg: false, // 选择时间弹窗开关
+      selectpfList: [
+        // 选择时间选项
+        { value: 0, label: '全部' },
+        { value: 2, label: '月度' },
+        { value: 3, label: '季度' },
+        { value: 4, label: '半年度' },
+        { value: 5, label: '年度' },
+        { value: 1, label: '天' },
+        { value: 6, label: '自定义' }
+      ],
+      titles:[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}],
+      // 列表
+      performanceList: [], // 绩效列表
+      assessData: {
+        cycle_type: 0, // 周期类型
+        keywords: '', // 搜索字
+        page: 1, // 当期页
+        page_size: 10, // 一页多少数据
+        is_manage_scope: 1
+      },
+      selectpradio: 0, // 选中的时间选项
+      selectPftiText: { value: 0, label: '全部' }, // 默认值
+      meList: [],
+
+      typeIndex:'1',
+      selectGl:false,
+      selectGlVal:0,
+      selectGlText:'全部',
+      selectGlType: [
+        // 选择时间选项
+        { value: 0, label: '全部' },
+        { value: 1, label: '我的下级' },
+        { value: 2, label: '我协助管理的' },
+      ],
+      pullonThePanel:false,
+      selectGlData: {}, // 当前选中项
+      selectGlKgpText:'',
+      columns: [], // 顶部选项
+      selectGlTheEcho:[],
+      keyword:'',
+      page:1,
+
+      //我评分的
+      glDataList:[{userInfo:{},dept_list:[]}],
+      isColumns:false,//是否请求完考核包列表
+
+      apList:[],
+      day: moment().format('YYYY-MM-DD')
+    };
+  },
+  created() {
+    if(this.$getRole(3)){
+      this.titles=[{title:'我的考核',value:'3'},{title:'我评分的',value:'2'},{title:'我管理的',value:'1'}];
+      this.typeIndex="3";
+    }else{
+      this.titles=[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}];
+    }
+  	this.doSthForSb(); // 代办
+  	this.cc(); // 抄送
+  },
+  mounted() {
+    this.assessData.page = 1;
+    this.assessData.cycle_type = 0;
+    // this.perScrollerFun();//请求 列表数据
+  },
+  activated() {
+  	this.doSthForSb(); // 代办
+  	this.cc(); // 抄送
+    this.perScrollerFun();//请求 列表数据
+  },
+  watch:{
+    typeIndex(val){
+      this.page=1;
+      this.selectGlVal=0;
+      this.selectGlText='全部';
+      this.keyword='';
+      if(this.columns.length>0){
+        this.selectGlData = this.columns[0].children[0]
+        this.selectGlKgpText = this.columns[0].children[0].name
+        this.selectGlTheEcho = [0, 0]
+      }
+      if(val=='1'){
+          this.selectGlType=[
+          { value: 0, label: '全部' },
+          { value: 1, label: '我的下级' },
+          { value: 2, label: '我协助管理的' },
+        ]
+        this.$nextTick(()=>{
+          this.getManagement();
+        })
+      }else if(val=='2'){
+        this.selectGlType=[
+          { value: 0, label: '全部' },
+          { value: 1, label: '我的下级' },
+          { value: 2, label: '我协助评分的' },
+        ]
+        this.$nextTick(()=>{
+          this.getScorerRecord();
+        })
+      }
+    }
+  },
+  methods: {
+    returnStr(time){
+      let date=`${time}000`
+      let res = moment(Number(date)).format('YYYY/MM/DD HH:mm');
+      return this.fnTime(res);
+    },
+    fnTime( time ){
+        let staer=time.slice(0,11);
+        let ptime = new Date(time).getTime()
+        const twentyFourHours = 24 * 60 * 60 * 1000;
+        const fortyEightHours = 24 * 60 * 60 * 1000 * 2;
+        const today = moment().format('YYYY/MM/DD');
+        const todayTime = new Date(today).getTime();
+        const yesterdayTime = new Date(todayTime - twentyFourHours).getTime();
+        const lastYesterdayTime = new Date(todayTime - fortyEightHours).getTime();
+
+        if( ptime >= todayTime ){
+            return '今天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < todayTime && yesterdayTime <= ptime ){
+            return '昨天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < yesterdayTime && lastYesterdayTime <= ptime ){
+            return '前天 '+time.split(' ')[1]+' 更新了执行计划';
+        }else if(this.dateSum(this.day,staer)>30){
+            return '近30天无计划更新';
+        } else{
+            return time+' 更新了执行计划';
+        }
+    },
+    dateSum(sDate1, sDate2){   //sDate1和sDate2是2008-12-13格式
+        var aDate, oDate1, oDate2, iDays
+        aDate = sDate1.split("-")
+        oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])   //转换为12-13-2008格式
+        aDate = sDate2.split("-")
+        oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
+        iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 /24)   //把相差的毫秒数转换为天数
+        return iDays
+    },
+    complete(item) {
+      this.employeeDet(item.record_id, (recordMemberIds) => {
+        let data={
+            know: 'admnin',
+            apList: this.apList,
+            packId: item.record_id,
+            assessID: item.employee_id,
+            recordMemberIds:recordMemberIds||[]
+        }
+        this.$setCache('actionplanList',data);
+        this.$router.push({
+          name: 'actionplanList'
+          // query: {
+          //   know: 'admnin',
+          //   apList: this.apList,
+          //   packId: item.record_id,
+          //   assessID: item.employee_id,
+          //   recordMemberIds:recordMemberIds||[],
+          // }
+        })
+        this.isTrack = true;
+      });
+    },
+    employeeDet(id,callBack) {
+      this.staffLoad = true;
+      this.$axiosUser('get', '/api/pro/per/package/employee/info', { id: id })
+        .then(res => {
+          let data = res.data.data;
+          this.apList = JSON.stringify(data.dimension);
+          callBack && callBack(data.record_member_ids);
+        })
+        .finally(() => {
+          this.staffLoad = false;
+        });
+    },
+    openDetail(item){
+      let data={
+        id: item.record_id,
+        Tit: item.package_name
+      }
+      this.$router.push({name:'performanceDetails', query:data});
+    },
+    // 下拉刷新
+    refresh_two(done) {
+      this.page = 1;
+      if(this.isColumns){
+         this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+      }else{
+        this.columnList(()=>{
+          this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+        });
+      }
+    },
+    // 上拉加载
+    infinite_two(done) {
+      this.page++;
+      this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+    },
+    //管理记录列表
+    getManagement(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/management_record', { package_id: this.selectGlData.id, range:this.selectGlVal, name: this.keyword, page: this.page, page_size: 10 }).then(res => {
+          let list = res.data.data.list;
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list=this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          if (this.page === 1) {
+            this.glDataList = list;
+          } else {
+            this.glDataList = this.glDataList.concat(list);
+          }
+          hasMore = list.length !== 10;
+        })
+        .finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    //我评分的
+    getScorerRecord(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/score_record', { package_id: this.selectGlData.id, range:this.selectGlVal, name: this.keyword, page: this.page, page_size: 10 }).then(res => {
+          let list = res.data.data.list;
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list=this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          if (this.page === 1) {
+            this.glDataList = list;
+          } else {
+            this.glDataList = this.glDataList.concat(list);
+          }
+          hasMore = list.length !== 10;
+        })
+        .finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    onCancel () { // 取消
+      this.pullonThePanel = false
+    },
+    statementTIme () {
+      if(!this.selectGlKgpText){
+        return false
+      }
+      this.pullonThePanel = true
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+    theEchoVanPicker () { // 回显
+      this.$refs.van_picker.setIndexes(this.selectGlTheEcho)
+    },
+    // 考核包搜索
+    onConfirm (data, list) { // 确认
+      this.selectGlTheEcho = list// 回显
+      this.selectGlData = this.columns[list[0]].children[list[1]]// 当前选中项
+      this.selectGlKgpText = data[data.length - 1]// 选中的name
+      this.pullDown();
+      this.pullonThePanel = false
+    },
+    // 搜索
+    keyVal: _debounce(function() {
+      this.pullDown();
+    }),
+    // 管理记录筛选确定
+    clickGlConfirm(item){
+      this.selectGlText=item.label;
+      this.pullDown();
+      this.selectGl=false;
+    },
+    pullDown(){
+      this.page=1;
+      setTimeout(() => {
+        this.$refs.perScroller.triggerPullToRefresh();
+      }, 50);
+    },
+    columnList (callback) { // 绩效包树
+      this.$axiosUser('get', '/api/pro/per/package/tree').then((res) => {
+        if (res.data.code == 1) {
+          let data = res.data.data
+          let list = []
+          data.forEach((item) => {
+            if (item.list.length > 0) {
+              list.push(item)
+              item.children = item.list
+            }
+          })
+          if (list.length > 0) {
+            this.selectGlData = list[0].children[0]
+            this.selectGlKgpText = list[0].children[0].name
+            this.selectGlTheEcho = [0, 0]
+            this.columns = list
+          }
+        }
+      }).finally(()=>{
+        this.isColumns=true;
+        callback && callback()
+      })
+    },
+    // 上拉刷新
+    refresh(done) {
+      this.assessData.page = 1;
+      this.assessBagList(done);
+    },
+    // 下拉加载
+    infinite(done) {
+      this.assessData.page++;
+      this.assessBagList(done);
+    },
+    // 点击选择时间选项
+    clickpfTime(val) {
+      this.selectPftiText = val;
+      this.assessData.page = 1;
+      this.assessData.cycle_type = val.value;
+      this.selectpfdlg = false;
+      this.perScrollerFun();
+    },
+    assessBagList(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/list', this.assessData)
+        .then(res => {
+          if (res.data.code == 1) {
+            const { list } = res.data.data;
+            if (this.assessData.page === 1) {
+              this.performanceList = list;
+            } else {
+              this.performanceList = this.performanceList.concat(list);
+            }
+            hasMore = list.length !== 10;
+          }
+        }).finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    selectPfTIme() {
+      this.selectpfdlg = true;
+    },
+    backlog() {
+      this.$router.push({ name: 'backlog' });
+      // 待办事项
+    },
+    notification() {
+      this.$router.push({ name: 'messageInform' });
+    },
+    perScrollerFun() {
+      setTimeout(() => {
+        this.$refs.perScroller.triggerPullToRefresh();
+      }, 50);
+    },
+    doSthForSb() {
+      // 代办数量
+      let params = {status: 0,page: 0};
+      let axios= this.$axiosUser('get', '/api/pro/per/package/msg/agency', params,'v2')
+      let axios2= this.$axiosUser('get', '/api/pro/per/package/plc/list', {page:1,page_size:1,status:0})
+      Promise.all([axios,axios2]).then(res => {
+          let total=res[0].data.data.total;
+          let total2=res[1].data.data.total;
+          this.informNum.commission = total+total2
+      })
+    },
+    cc() {
+      // 抄送
+      let params = {
+        type: '1,2',
+        status: 0, // 未处理
+        page: 0
+      };
+      this.$axiosUser('get', '/api/pro/per/package/msg/cc', params).then(res => {
+        if (res.data.code == 1) {
+          this.informNum.information = res.data.data.total;
+        }
+      });
+    },
+    refresh1(done) {
+      if (this.$getRole(3) || this.$getRole(4)) {
+        // 员工权限
+        this.myPerformanceList(done); // 请求我的绩效接口
+      }
+    },
+    myPerformanceList(callback) {
+      let params = {
+        employee_id: this.$userInfo().id
+      };
+      this.$axiosUser('get', '/api/pro/per/package/employee/list', params)
+        .then(res => {
+          if (res.data.code == 1) {
+            let data = res.data.data.list;
+            this.meList = data;
+          }
+        })
+        .finally(() => {
+          callback && callback();
+        });
+    }
+  },
+};
+</script>
+
+<style scoped lang="less">
+.list-item{
+  padding: 0.24rem 0.32rem;
+  font-size: 0.32rem;
+  border-bottom: 1px solid #f1f1f1;
+}
+
+.selectItem{
+  margin-top: 0.2rem;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.32rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+
+.workHeader {
+  background-color: #fff;
+  height: 1.1rem;
+  font-size: 0.31rem;
+  line-height: 1.2rem;
+  margin-bottom: 0.2rem;
+  .headcol {
+    position: relative;
+    .headicon {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+      i {
+        margin: 0.4rem 0.1rem 0 0;
+      }
+    }
+  }
+}
+
+.selector {
+  display: flex;
+  justify-content: center;
+  margin-top: 0.2rem;
+  width: 100%;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.32rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+.cunt {
+  background-color: #f15532;
+  text-align: center;
+  line-height: 0.39rem;
+  width: 0.4rem;
+  height: 0.4rem;
+  border-radius: 50%;
+  position: absolute;
+  top: 0.4rem;
+  left: 2.9rem;
+  color: #fff;
+  font-size: 0.26rem;
+  font-style: normal;
+}
+.cunt i {
+  font-style: normal;
+}
+.cunts {
+  // padding: 0 0.04rem !important;
+  // max-width: 0.8rem;
+  // overflow: hidden;
+  // text-overflow: ellipsis;
+  // white-space: nowrap;
+  width: auto !important;
+  padding: 0 .04rem 0 .08rem !important;
+  border-radius: .8rem !important;
+}
+
+.all {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+  // background-color: #f5f7fa;
+  // padding-bottom: .5rem;
+  // height: 100%;
+  & .event-list__content {
+    position: relative;
+    height: calc(100% - 4.3rem);
+    & .van-hairline--top-bottom:after,
+    .body_com .van-hairline-unset--top-bottom:after {
+      border: none;
+    }
+  }
+  & .event-list__content2 {
+    position: relative;
+    height: calc(100% - 3.2rem);
+    & .van-hairline--top-bottom:after,
+    .body_com .van-hairline-unset--top-bottom:after {
+      border: none;
+    }
+  }
+}
+
+.workbench_list {
+  padding: 0.3rem 0.6rem;
+  div {
+    font-size: 0.33rem;
+  }
+  span {
+    padding-top: 0.1rem;
+    color: #737373;
+    font-size: 0.25rem;
+    display: flex;
+    i {
+      margin: 0.06rem 0.05rem 0 0;
+      color: #f7b461;
+    }
+  }
+}
+
+.meAll {
+  height: calc(100% - 1rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+.me_list {
+  background-color: #fff;
+  display: flex;
+  padding: 12px 16px;
+  .me_list_content {
+    padding-left: 0.3rem;
+    .me_list_tit {
+      font-size: 0.33rem;
+    }
+    .me_list_result {
+      font-size: 0.3rem;
+      .me_list_col {
+        color: #adadad;
+      }
+      .me_list_resultTit {
+        display: inline-block;
+        padding-bottom: 0.18rem;
+        color: #3bdf9a;
+      }
+    }
+    .me_list_course {
+      display: inline-block;
+      padding-bottom: 0.18rem;
+      font-size: 0.28rem;
+      color: #ff9439;
+    }
+  }
+}
+</style>

+ 173 - 0
src/newPerformance/view/navigation.vue

@@ -0,0 +1,173 @@
+<template>
+  <div>
+    <div class="user_index_scroller_com" :class="isIos? 'isIos':''"  v-show="!appNavJx">
+      <div class="height100p" v-if="active_index == 0" :class="{ hidden_right: active_index != 0 }"><Workbench/></div>
+      <div class="height100p" v-if="active_index == 1" :class="{ hidden_right: active_index != 1 }"><Statement></Statement></div>
+      <div class="height100p" v-if="active_index == 2" :class="{ hidden_right: active_index != 2 }"><Me></Me></div>
+      <!-- 导航 -->
+      <van-tabbar v-model="active_index" :class="isIos? 'padding-m':''" :fixed="false">
+        <van-tabbar-item>
+          <icon name="footer_nav_work" v-if="tabs != 0" class="footer_nav_work"></icon>
+          <icon name="footer_nav_work_press" v-if="tabs == 0" class="footer_nav_work_press active"></icon>
+          <span v-if="$getRole(3)||$getRole(4)">我的</span>
+          <span v-else>工作台</span>
+        </van-tabbar-item>
+        <van-tabbar-item v-show="statementif">
+          <icon name="statistics" v-if="tabs != 1" class="footer_nav_review"></icon>
+          <icon name="statistics_checked" v-if="tabs == 1" class="footer_nav_review active"></icon>
+          <span>报表</span>
+        </van-tabbar-item>
+        <van-tabbar-item v-show="$getRole(1)||$getRole(2)">
+          <icon name="footer_nav_me" v-if="tabs != 2" class="footer_nav_me"></icon>
+          <icon name="footer_nav_me_press" v-if="tabs == 2" class="footer_nav_me_press active"></icon>
+          <span>我的</span>
+        </van-tabbar-item>
+      </van-tabbar>
+    </div>
+    <div v-show="appNavJx" class="jxNav">
+      <img :src="'static/images/' + navList[navNew].image + '.png'" />
+      <van-button @click="navNew++" v-if="navNew < 1" type="primary" color="rgb(125 171 255)" block>下一步</van-button>
+      <van-button @click="appNavJx=false" v-else type="primary" color="rgb(125 171 255)" block>进入</van-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import Workbench from '@/performance/view/navhome/workbench'
+import Statement from '@/performance/view/navhome/statement'
+import Me from '@/performance/view/navhome/me'
+
+import Vue from 'vue'
+import { Overlay, Image as VanImage } from 'vant'
+Vue.use(Overlay).use(VanImage)
+export default {
+  data () {
+    return {
+      active_index: 0,
+      tabs: 0,
+      isIos: this.$getCache('iPhone'),
+      statementif: false,
+      appNavJx:false,
+      newNav: this.plusStoGet('newNav'),
+      navList: [{ image: 'newNav1' }, { image: 'newNav2' }],
+      navNew: 0
+    }
+  },
+  components: { Workbench, Statement, Me},
+  watch: {
+    active_index (val, old) {
+      this.tabs = val
+    },
+    appNavJx(val){
+      if(!val){
+         this.plusStoSet('newNav', 'true')
+      }
+    }
+  },
+  methods:{
+    plusStoGet(key) {
+      if (window.plus) {
+        return plus.storage.getItem(key);
+      } else {
+        return localStorage.getItem(key);
+      }
+    },
+    plusStoSet(key, val, fun = function() {}) {
+      if (window.plus) {
+        plus.storage.setItem(key, val);
+      } else {
+        localStorage.setItem(key, val);
+      }
+      fun();
+    },
+    setMent(){
+      // 报表显示隐藏
+      if (this.$userInfo().employee_detail.manage_dept_ids.length>0|| (this.$getRole(1) && this.$getPermis(16))) {
+        this.statementif = true
+      } else {
+        this.statementif = false
+      }
+      if (this.$getRole(3) || this.$getRole(2) || this.$getRole(1) && !this.$getPermis(16)) {
+        this.active_index = 0
+        this.tabs = 0
+      }
+      this.$nextTick(()=>{
+        if(this.$route.query.index){
+          this.active_index=this.$route.query.index
+        }
+      })
+    }
+  },
+  created () {
+    document.documentElement.style.backgroundColor = '#26A2FF';
+    if (window.plus) { // 下边横杠兼容
+      plus.navigator.setStatusBarStyle('light')
+    }
+    if (!this.newNav) {
+      this.appNavJx = true;
+    }
+    this.setMent();
+  },
+}
+</script>
+
+<style scoped lang="less">
+.jxNav {
+  width: 100%;
+  height: 100%;
+  img {
+    width: 100%;
+    margin-top: 50px;
+  }
+  button {
+    width: 90%;
+    margin: auto;
+    border-radius: 0.1rem;
+    position: fixed;
+    bottom: 0.2rem;
+    left: 5%;
+    z-index: 999;
+  }
+}
+.user_index_scroller_com {
+  height: calc(100% - 1rem);
+  position: relative;
+}
+/deep/ .isIos{
+  height: calc(100% - 1.4rem);
+}
+.padding-m{
+  padding-bottom: 0.4rem;
+}
+
+.hidden_right {
+  position: absolute;
+  top: -1000000px;
+  left: -100000px;
+}
+
+.height100p {
+  height: 100%;
+}
+
+.user_index_scroller_com /deep/ .van-tabbar-item {
+  text-align: center;
+  position: relative;
+}
+.user_index_scroller_com /deep/ .van-tabbar-item .svg-icon {
+  color: #606266;
+  height: 0.36rem;
+  margin-bottom: 0.08rem;
+}
+.user_index_scroller_com .footer_nav_add_press {
+  height: 0.8rem !important;
+}
+.user_index_scroller_com /deep/ .van-tabbar-item .active {
+  color: #238dfa;
+}
+.user_index_scroller_com /deep/ .van-tabbar-item span {
+  display: block;
+  font-size: 0.2rem;
+  margin-bottom: 0.08rem;
+}
+</style>

+ 495 - 0
src/newPerformance/view/performanceHome.vue

@@ -0,0 +1,495 @@
+<template>
+  <div class="all">
+
+    <div class="notice-bar" @click="toggelSystem()">
+      <div class="flex-box-ce flex-1">
+        <van-icon name="info-o"></van-icon>
+        <span>目前是新绩效系统</span>
+      </div>
+      <span class="blue">切换旧系统</span>
+    </div>
+
+    <div class="scroller">
+      <scroller ref="perScroller">
+
+        <header class="workHeader">
+          <van-grid :border="false" style="background-color: #fff;position: relative;" class="border-bottom">
+            <van-grid-item v-if="app.isShow" v-for="(app, index) in topMenuList" :dot="app.dot" :badge="app.badge" :key="app.code" @click="openUrl(app)" :text="app.code">
+              <template slot="icon">
+                <img :src="app.icon" style="-webkit-touch-callout: none;" />
+              </template>
+            </van-grid-item>
+          </van-grid>
+        </header>
+
+
+        <div class="list-box" v-if="examineInfo">
+          <div class="flex-box-ce flex-d-center">
+            <div class="title">
+              上次绩效
+            </div>
+            <div>
+              <span style="font-size: 0.28rem;" class="blue" @click="goDetailPage(examineInfo.reviewId, examineInfo.employeeId)">查看明细</span>
+              <i class="blue van-icon van-icon-arrow van-cell__right-icon" style="font-size: 0.28rem;"></i>
+            </div>
+          </div>
+          <div class="flex-box-ce" style="margin: 0.2rem 0;">
+            <div>
+              <userImage class="about-me__avatar" :id="examineInfo.userInfo.employeeId" :img_url="examineInfo.userInfo.img_url"  :user_name="examineInfo.userInfo.employeeName"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+            </div>
+            <div class="user-info">
+              <div style="color: black; font-size: 0.3rem;">{{ examineInfo.userInfo.name }}</div>
+              <span v-for="item in examineInfo.dept_list" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
+            </div>
+          </div>
+
+          <div>
+            <div style="font-size: 0.28rem; margin-bottom: 0.2rem;" class="fontColorC">
+              考核时间: &nbsp;&nbsp;&nbsp;{{ examineInfo.startTime }} - {{ examineInfo.endTime }}
+            </div>
+            <div style="font-size: 0.28rem; margin-bottom: 0.2rem;" class="fontColorC">
+              考核等级: &nbsp;&nbsp;&nbsp;<span style="color: rgb(255, 150, 0);">{{ examineInfo.levelName || '--' }}</span>
+            </div>
+            <div style="font-size: 0.28rem; "class="fontColorC">
+              考核评分: &nbsp;&nbsp;&nbsp;<span style="color: rgb(255, 150, 0);">{{ examineInfo.score !== null || examineInfo.score !== undefined || examineInfo.score !== '' ? examineInfo.score  : '--' }}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="my-attention-box" >
+          <div class="my-attention">
+            我关注的
+          </div>
+          <div class="flex-box-ce fontColorC" @click="goAttentionPage()">
+            <van-icon name="weapp-nav" style="margin-right: 5px;" />
+            <span style="font-size: 0.26rem;">设置</span>
+          </div>
+        </div>
+
+
+        <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+
+        <van-cell-group>
+            <div class="flex-box-ce list-item flex-d-wrap"  v-for="(item, index) in filterUsers" :key="index">
+              <userImage :id="item.id" :user_name="item.name" :img_url="item.imgUrl" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+              <div class="flex-1" style="margin-left: 0.24rem;">
+                 <div style="margin-bottom: 0.1rem;">{{item.name}}</div>
+                 <div class="fontColorC font-flex-word" style="font-size: 0.28rem; width: 3.5rem;" v-if="item.departments && item.departments.length > 0">
+                   <span v-for="dept in item.departments" :key="dept.id">{{ dept.name }}</span>
+                 </div>
+                 <div v-else class="fontColorC" style="font-size: 0.28rem; ">暂无部门</div>
+              </div>
+
+              <div style="font-size: 0.28rem; margin-bottom: 0.1rem;" class="flex-box-end">
+                <template>
+                  <van-button plain type="info" size="small" @click="goMorePage(item.id)">查看详情</van-button>
+                </template>
+              </div>
+            </div>
+        </van-cell-group>
+        <van-empty description="暂无内容" v-if="filterUsers.length == 0" />
+      </scroller>
+    </div>
+
+
+    <!-- 上次考核 -->
+    <!-- <div class="sidebar flex-box-ce">
+      <van-icon name="plus" size=".24rem" />
+      上次考核
+    </div> -->
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import {Tab, Tabs, Search} from 'vant'
+import moment from 'moment';
+import axios from 'axios';
+
+
+
+
+import { _debounce, _throttle } from '@/utils/auth';
+Vue.use(Tabs).use(Tab).use(Search);
+export default {
+  data() {
+    return {
+      isAndroid: navigator.userAgent.indexOf('Android') > 0,
+      topMenuList:[
+        {code:"待办", icon:"static/images/daiban.png", url:'newBacklog', badge: 0, isShow: true},
+        {code:"过程跟踪",icon:"static/images/guochenggenzong.png", url:'newStatement',isShow:this.$getRole(1) || this.$getRole(2)},
+        {code:"我的绩效",icon:"static/images/wodejixiao.png", url:'newMe', isShow: true},
+        {code:"结果分析",icon:"static/images/jieguofenxi.png", url:'resultAnalysis', isShow:this.$getRole(1) || this.$getRole(2)},
+        {code:"组织考核",icon:"static/images/jixiaoduibi.png", url:'orgExamine', isShow: this.$getRole(1) || this.$getRole(2)},
+      ],
+
+      glDataList: [],
+
+      titles: [{ title:'我关注的', value: '1' }],
+      userInfo: this.$userInfo(),
+
+      typeIndex:'1',
+
+      keyword:'',
+      day: moment().format('YYYY-MM-DD'),
+      filterUsers: [],
+
+      examineInfo: null, // 上次考核信息
+
+    };
+  },
+
+
+
+  computed: {
+    dept_list() {
+      return this.userInfo && this.userInfo.employee_detail && this.userInfo.employee_detail.dept_list || []
+    }
+  },
+
+  created() {
+    this.getMyExamineInfo(); // 获取上次考核信息
+    this.doSthForSb(); // 获取代办角标数量
+    this.getAttentionList();// 请求列表数据
+  },
+
+  activated() {
+    this.getMyExamineInfo(); // 获取上次考核信息
+    this.doSthForSb(); // 获取代办角标数量
+    this.getAttentionList();// 请求列表数据
+  },
+
+
+  methods: {
+
+    // 切换新系统
+    toggelSystem() {
+      this.$emit("changeSystem", "")
+      localStorage.setItem("chooseNew", false)
+    },
+
+    formatDate(val) {
+      if (val) return moment(val).format('YYYY-MM-DD')
+      else return "--"
+    },
+
+    goDetailPage(reviewId, employeeId) {
+      this.$router.push({path: '/newMe', query: { reviewId, employeeId } })
+    },
+
+    getMyExamineInfo() {
+      let that = this
+      let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
+      let requestdata = { employeeId: that.$userInfo().id }
+      that.$axiosUser('get', url, requestdata).then(res => {
+
+        let { data: { data: { list, total }, code } } = res;
+        // alert(res)
+        if (code == 1) {
+          if (list && list.length > 0) {
+            that.examineInfo = list.filter(item => item.status == 1)[0] || null; // 已结束的考核
+            if(that.examineInfo) {
+              that.examineInfo.startTime = that.formatDate(that.examineInfo.startTime)
+              that.examineInfo.endTime = that.formatDate(that.examineInfo.endTime)
+              that.examineInfo.userInfo = that.$getEmployeeMapItem(that.examineInfo.employeeId);
+              that.examineInfo.dept_list = that.$getEmployeeMapItem(that.examineInfo.employeeId).employee_detail.dept_list;
+            }
+          }
+        } else {
+            that.examineInfo = null;
+        }
+      }).catch(err => {
+        // 这里会收到上面 reject 的错误
+        console.log('错误已处理,继续执行其他逻辑');
+      })
+      .finally(() => {
+        // 关闭 loading
+      });
+    },
+
+    openUrl(item) {
+      this.$router.push({ name:item.url});
+    },
+
+    goAttentionPage() {
+      this.$router.push({ name: 'perAttentionList' })
+    },
+
+    goMorePage(employeeId) {
+      this.$router.push({ path: '/more', query: { employeeId } })
+    },
+
+
+
+    // 关注列表
+    getAttentionList() {
+      this.$axiosUser('get', `/performance/follow/employees/${this.$userInfo().site_id}`, ).then(res => {
+        let list = res.data.data.list;
+        if(list && list.length > 0) {
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          this.glDataList = list;
+          this.filterUsers = list;
+        }
+
+      })
+    },
+
+    // 搜索 - 关注的人
+    keyVal: _debounce(function() {
+      if(!this.keyword) this.filterUsers = this.glDataList
+      if(this.glDataList && this.glDataList.length > 0) {
+        this.filterUsers = this.glDataList.filter(item => item.name.includes(this.keyword.trim()))
+      }
+    }),
+
+
+    doSthForSb() {
+      let url = `/performance/review/job/employee/app/${this.$userInfo().site_id}/${this.$userInfo().id}`
+      // 代办数量
+      let params = {
+        siteId: this.$userInfo().site_id,
+        employeeId: this.$userInfo().id,
+        page: 1,
+        pageSize: 1,
+        type: 0
+      };
+      this.$axiosUser('get', url, params).then(res => {
+        this.topMenuList[0].badge = res.data.data.total || 0
+      })
+    },
+
+
+
+  },
+};
+</script>
+
+<style scoped lang="less">
+
+  .notice-bar {
+    width: 100%;
+    height: 0.8rem;
+    font-size: 0.28rem;
+    line-height: 0.8rem;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    color: #606266;
+    background: rgb(236, 249, 255);
+    padding: 0 0.2rem;
+    box-sizing: border-box;
+    i {
+      margin-right: 0.2rem;
+      font-size: 0.3rem;
+      color: rgb(25, 137, 250);
+    }
+  }
+
+  .list-box {
+    width: 96%;
+    padding: 0.24rem;
+    font-size: 0.32rem;
+    background-color: #fff;
+    border-radius: 5px;
+    box-sizing: border-box;
+    margin: 0.24rem auto;
+    position: relative;
+    .examine-item-status {
+      position: absolute;
+      top: 0.2rem;
+      right: 0.1rem;
+      padding: 0.01rem 0.1rem;
+      color: #fff;
+      border-radius: 2px;
+      font-size: 0.26rem;
+      background-color: #67c23a;
+      margin-right: 0.14rem;
+    }
+    .title {
+      font-size: 0.32rem !important;
+      font-weight: normal !important;
+    }
+
+    .user-info {
+      font-size: 0.28rem;
+      color: #89919F !important;
+      margin: 0 0 0 0.2rem;
+    }
+
+    .cycle-type {
+      padding: 0.08rem;
+      border-radius: 0.1rem;
+      color: #26a2ff;
+      box-sizing: border-box;
+      background-color: #ecf5ff;
+    }
+
+    .examine-info {
+      font-size: 0.28rem;
+      position: relative;
+
+      .tips {
+        position: absolute;
+        top: 0.1rem;
+        right: -0.2rem;
+        .tip-item {
+          padding: 0.1rem;
+          border-top-left-radius: 0.1rem;
+          border-bottom-left-radius: 0.1rem;
+          color: #26a2ff;
+          z-index: 999;
+          box-sizing: border-box;
+          background-color: #ecf5ff;
+          margin-bottom: 0.1rem;
+        }
+      }
+      .info-item {
+        margin-bottom: 0.2rem;
+        color: #89919F !important;
+        .info-item-title {
+          width: 1.4rem;
+          color: #000;
+        }
+        .review-node {
+          padding: 0.01rem 0.1rem;
+          color: #fff;
+          border-radius: 2px;
+          font-size: 0.26rem;
+          background-color: #67c23a;
+          margin-left: 0.14rem;
+        }
+      }
+
+      .line {
+        width: 100%;
+        margin: 0.5rem auto;
+        height: 1px;
+        background-color: #f1f1f1;
+      }
+    }
+
+
+  }
+
+.all {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  position: relative;
+
+
+  .scroller {
+    flex: 1;
+    position: relative;
+  }
+
+  .workHeader /deep/ .van-grid-item {
+    margin-bottom: 0.2rem;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content {
+    padding: 0 !important;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__text {
+    font-size: 0.28rem;
+    color: #606266;
+    line-height: 0.44rem;
+    width: 1.4rem;
+    text-align: center;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__icon-wrapper img {
+    width: 1rem;
+    height: 1rem;
+    border-radius: 0.42rem;
+  }
+
+  .workHeader {
+    background-color: #fff;
+    font-size: 0.31rem;
+    padding-top: 0.4rem;
+    box-sizing: border-box;
+    .headcol {
+      position: relative;
+      .headicon {
+        width: 100%;
+        display: flex;
+        justify-content: center;
+        i {
+          margin: 0.4rem 0.1rem 0 0;
+        }
+      }
+    }
+  }
+
+
+
+
+
+  .my-attention-box {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0.2rem;
+    box-sizing: border-box;
+    background: #fff;
+    border-bottom: 1px solid #f1f1f1;
+    .my-attention {
+      flex: 1;
+      box-sizing: border-box;
+      background-color: #fff;
+      font-size: 0.32rem;
+    }
+  }
+}
+
+
+
+
+
+
+
+.list-item {
+  padding: 0.24rem 0.32rem;
+  font-size: 0.32rem;
+  border-bottom: 1px solid #f1f1f1;
+}
+
+
+
+
+
+
+.sidebar {
+  width: 2.2rem;
+  height: 0.5rem;
+  position: fixed;
+  right: 0px;
+  bottom: 2rem;
+  font-size: 0.28rem;
+  padding: 0.1rem 0.25rem;
+  border-top-left-radius: 0.05rem;
+  border-bottom-left-radius: 0.05rem;
+  display: flex;
+  color: #26a2ff;
+  box-sizing: border-box;
+  z-index: 999;
+  background-color: #ecf5ff;
+  i {
+    // margin: 0.05rem 0.15rem 0 0;
+    margin-right: 0.15rem;
+    color: #26a2ff;
+  }
+}
+
+
+</style>

+ 571 - 0
src/newPerformance/view/performanceHome2.vue

@@ -0,0 +1,571 @@
+<template>
+  <div class="all">
+
+    <div class="notice-bar" @click="toggelSystem()">
+      <div class="flex-box-ce flex-1">
+        <van-icon name="info-o"></van-icon>
+        <span>目前是新绩效系统</span>
+      </div>
+      <span class="blue">切换旧系统</span>
+    </div>
+
+    <div class="scroller">
+      <scroller ref="perScroller">
+
+        <header class="workHeader">
+          <van-grid :border="false" style="background-color: #fff;position: relative;" class="border-bottom">
+            <van-grid-item v-if="app.isShow" v-for="(app, index) in topMenuList" :dot="app.dot" :badge="app.badge" :key="app.code" @click="openUrl(app)" :text="app.code">
+              <template slot="icon">
+                <img :src="app.icon" style="-webkit-touch-callout: none;" />
+              </template>
+            </van-grid-item>
+          </van-grid>
+        </header>
+
+
+        <div class="list-box" v-if="examineInfo">
+          <div class="flex-box-ce flex-d-center">
+            <div class="title">
+              上次绩效
+            </div>
+            <div>
+              <span style="font-size: 0.28rem;" class="blue" @click="goDetailPage(examineInfo.reviewId, examineInfo.employeeId)">查看明细</span>
+              <i class="blue van-icon van-icon-arrow van-cell__right-icon" style="font-size: 0.28rem;"></i>
+            </div>
+          </div>
+          <div class="flex-box-ce" style="margin: 0.2rem 0;">
+            <div>
+              <userImage class="about-me__avatar" :id="examineInfo.userInfo.employeeId" :img_url="examineInfo.userInfo.img_url"  :user_name="examineInfo.userInfo.employeeName"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+            </div>
+            <div class="user-info">
+              <div style="color: black; font-size: 0.3rem;">{{ examineInfo.userInfo.name }}</div>
+              <span v-for="item in examineInfo.dept_list" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
+            </div>
+          </div>
+
+          <div>
+            <div style="font-size: 0.28rem; margin-bottom: 0.2rem;" class="fontColorC">
+              考核时间: &nbsp;&nbsp;&nbsp;{{ examineInfo.startTime }} - {{ examineInfo.endTime }}
+            </div>
+            <div style="font-size: 0.28rem; margin-bottom: 0.2rem;" class="fontColorC">
+              考核等级: &nbsp;&nbsp;&nbsp;<span style="color: rgb(255, 150, 0);">{{ examineInfo.levelName || '--' }}</span>
+            </div>
+            <div style="font-size: 0.28rem; "class="fontColorC">
+              考核评分: &nbsp;&nbsp;&nbsp;<span style="color: rgb(255, 150, 0);">{{ examineInfo.score !== null || examineInfo.score !== undefined || examineInfo.score !== '' ? examineInfo.score  : '--' }}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="my-attention-box" >
+          <div class="my-attention">
+            我关注的
+          </div>
+          <div class="flex-box-ce fontColorC" @click="goAttentionPage()">
+            <van-icon name="weapp-nav" style="margin-right: 5px;" />
+            <span style="font-size: 0.26rem;">设置</span>
+          </div>
+        </div>
+
+
+        <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+
+        <van-cell-group>
+            <div class="flex-box-ce list-item flex-d-wrap"  v-for="(item, index) in filterUsers" :key="index">
+              <userImage :id="item.id" :user_name="item.name" :img_url="item.imgUrl" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+              <div class="flex-1" style="margin-left: 0.24rem;">
+                 <div style="margin-bottom: 0.1rem;">{{item.name}}</div>
+                 <div class="fontColorC font-flex-word" style="font-size: 0.28rem; width: 3.5rem;" v-if="item.departments && item.departments.length > 0">
+                   <span v-for="dept in item.departments" :key="dept.id">{{ dept.name }}</span>
+                 </div>
+                 <div v-else class="fontColorC" style="font-size: 0.28rem; ">暂无部门</div>
+              </div>
+
+              <div style="font-size: 0.28rem; margin-bottom: 0.1rem;" class="flex-box-end">
+                <template>
+                  <van-button plain type="info" size="small" @click="goMorePage(item.id)">查看详情</van-button>
+                </template>
+              </div>
+            </div>
+        </van-cell-group>
+        <van-empty description="暂无内容" v-if="filterUsers.length == 0" />
+      </scroller>
+    </div>
+
+
+    <!-- 上次考核 -->
+    <!-- <div class="sidebar flex-box-ce">
+      <van-icon name="plus" size=".24rem" />
+      上次考核
+    </div> -->
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import {Tab, Tabs, Search} from 'vant'
+import moment from 'moment';
+import axios from 'axios';
+import qs from 'qs'
+import { getToken, setToken, openError, _debounce, _throttle } from '@/utils/auth'
+
+const api = axios.create({
+  baseURL: process.env.BASE_API,
+  headers: {
+    'A-Token': getToken(),
+    'Content-Type': 'application/x-www-form-urlencoded'
+  }
+})
+
+api.interceptors.request.use(
+  config => {
+    alert(JSON.stringify(config))
+    config.data = qs.stringify(config.data)
+    // if (getToken()) {
+    //   config.headers['A-Token'] = getToken()
+    // }
+    return config
+  },
+  error => {
+    Promise.reject(error)
+  }
+)
+
+
+api.interceptors.response.use(response => {
+  alert(JSON.stringify(response))
+})
+
+// 后续调用自动带上头
+// api.get('/user/profile')
+
+// axios.interceptors.request.use(
+//     config => {
+//       config.data = qs.stringify(config.data);
+//       return config;
+//     },
+//     error => {
+//         // Do something with response error
+
+//         return Promise.reject(error);
+//     }
+// );
+
+Vue.use(Tabs).use(Tab).use(Search);
+export default {
+  data() {
+    return {
+      topMenuList:[
+        {code:"待办1", icon:"static/images/daiban.png", url:'newBacklog', badge: 0, isShow: true},
+        {code:"过程跟踪1",icon:"static/images/guochenggenzong.png", url:'newStatement',isShow:this.$getRole(1) || this.$getRole(2)},
+        {code:"我的绩效1",icon:"static/images/wodejixiao.png", url:'newMe', isShow: true},
+        {code:"结果分析1",icon:"static/images/jieguofenxi.png", url:'resultAnalysis', isShow:this.$getRole(1) || this.$getRole(2)},
+        {code:"组织考核1",icon:"static/images/jixiaoduibi.png", url:'orgExamine', isShow: this.$getRole(1) || this.$getRole(2)},
+      ],
+
+      glDataList: [],
+
+      titles: [{ title:'我关注的1', value: '1' }],
+      userInfo: this.$userInfo(),
+
+      typeIndex:'1',
+
+      keyword:'',
+      day: moment().format('YYYY-MM-DD'),
+      filterUsers: [],
+
+      examineInfo: null, // 上次考核信息
+
+    };
+  },
+
+
+
+  computed: {
+    dept_list() {
+      return this.userInfo && this.userInfo.employee_detail && this.userInfo.employee_detail.dept_list || []
+    }
+  },
+  created() {
+    // if(this.$getRole(3)){
+    //   this.titles=[{title:'我的考核',value:'3'},{title:'我评分的',value:'2'},{title:'我管理的',value:'1'}];
+    //   this.typeIndex="3";
+    // }else{
+    //   this.titles=[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}];
+    // }
+   //  this.getMyExamineInfo(); // 获取上次考核信息
+  	// this.doSthForSb(); // 获取代办角标数量
+   //  this.getAttentionList();// 请求列表数据
+  	// this.cc(); // 抄送
+  },
+
+  activated() {
+    this.getMyExamineInfo(); // 获取上次考核信息
+    this.doSthForSb(); // 获取代办角标数量
+    this.getAttentionList();// 请求列表数据
+  },
+
+
+  methods: {
+
+    // 切换新系统
+    toggelSystem() {
+      this.$emit("changeSystem", "")
+      localStorage.setItem("chooseNew", false)
+    },
+
+    formatDate(val) {
+      if (val) return moment(val).format('YYYY-MM-DD')
+      else return "--"
+    },
+
+    goDetailPage(reviewId, employeeId) {
+      this.$router.push({path: '/newMe', query: { reviewId, employeeId } })
+    },
+
+    getMyExamineInfo() {
+      let that = this
+      let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
+      let requestdata = { employeeId: that.$userInfo().id }
+      that.$axiosUser('get', url, requestdata).then(res => {
+
+        let { data: { data: { list, total }, code } } = res;
+        // alert(res)
+        if (code == 1) {
+          if (list && list.length > 0) {
+            that.examineInfo = list.filter(item => item.status == 1)[0] || null; // 已结束的考核
+            if(that.examineInfo) {
+              that.examineInfo.startTime = that.formatDate(that.examineInfo.startTime)
+              that.examineInfo.endTime = that.formatDate(that.examineInfo.endTime)
+              that.examineInfo.userInfo = that.$getEmployeeMapItem(that.examineInfo.employeeId);
+              that.examineInfo.dept_list = that.$getEmployeeMapItem(that.examineInfo.employeeId).employee_detail.dept_list;
+            }
+          }
+        } else {
+            that.examineInfo = null;
+        }
+      }).catch(err => {
+        // 这里会收到上面 reject 的错误
+        console.log('错误已处理,继续执行其他逻辑');
+      })
+      .finally(() => {
+        // 关闭 loading
+      });
+    },
+
+    openUrl(item) {
+      this.$router.push({ name:item.url});
+    },
+
+    goAttentionPage() {
+      this.$router.push({ name: 'perAttentionList' })
+    },
+
+    goMorePage(employeeId) {
+      this.$router.push({ path: '/more', query: { employeeId } })
+    },
+
+
+
+    // 关注列表
+    getAttentionList() {
+      this.$axiosUser('get', `/performance/follow/employees/${this.$userInfo().site_id}`, ).then(res => {
+        let list = res.data.data.list;
+        if(list && list.length > 0) {
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          console.log("关注用户列表")
+          console.log(list);
+          this.glDataList = list;
+          this.filterUsers = list;
+        }
+
+      }).catch(err => {
+    // 这里会收到上面 reject 的错误
+    console.log('错误已处理,继续执行其他逻辑');
+  })
+  .finally(() => {
+    // 关闭 loading
+  });
+    },
+
+    // 搜索 - 关注的人
+    keyVal: _debounce(function() {
+      if(!this.keyword) this.filterUsers = this.glDataList
+      // let filterUsers = []
+      if(this.glDataList && this.glDataList.length > 0) {
+        this.filterUsers = this.glDataList.filter(item => item.name.includes(this.keyword.trim()))
+      }
+    }),
+
+
+    doSthForSb() {
+      let url = `performance/review/job/employee/app/${this.$userInfo().site_id}/${this.$userInfo().id}`
+      let params = {
+        siteId: this.$userInfo().site_id,
+        employeeId: this.$userInfo().id,
+        page: 1,
+        pageSize: 1,
+        type: 0
+      };
+      api.get(url, { params, headers: {
+        'Content-Type': 'application/x-www-form-urlencoded'
+      } }).then(res => {
+        console.log(res.status)
+        alert("http状态码" + res.status)
+        this.topMenuList[0].badge = res.data.data.total || 0
+        // alert("获取角标数量" + "  " + this.topMenuList[0].badge)
+      })
+      // 代办数量
+      // let params = {
+      //   siteId: this.$userInfo().site_id,
+      //   employeeId: this.$userInfo().id,
+      //   page: 1,
+      //   pageSize: 1,
+      //   type: 0
+      // };
+      // this.$axiosUser('get', url, params).then(res => {
+      //   this.topMenuList[0].badge = res.data.data.total || 0
+      //   alert("获取角标数量" + "  " + this.topMenuList[0].badge)
+      // }).catch(err => {
+      //   // 这里会收到上面 reject 的错误
+      //   console.log('错误已处理,继续执行其他逻辑');
+      // })
+      // .finally(() => {
+      //   // 关闭 loading
+      // });
+    },
+
+
+
+  },
+};
+</script>
+
+<style scoped lang="less">
+
+  .notice-bar {
+    width: 100%;
+    height: 0.8rem;
+    font-size: 0.28rem;
+    line-height: 0.8rem;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    color: #606266;
+    background: rgb(236, 249, 255);
+    padding: 0 0.2rem;
+    box-sizing: border-box;
+    i {
+      margin-right: 0.2rem;
+      font-size: 0.3rem;
+      color: rgb(25, 137, 250);
+    }
+  }
+
+  .list-box {
+    width: 96%;
+    padding: 0.24rem;
+    font-size: 0.32rem;
+    background-color: #fff;
+    border-radius: 5px;
+    box-sizing: border-box;
+    margin: 0.24rem auto;
+    position: relative;
+    .examine-item-status {
+      position: absolute;
+      top: 0.2rem;
+      right: 0.1rem;
+      padding: 0.01rem 0.1rem;
+      color: #fff;
+      border-radius: 2px;
+      font-size: 0.26rem;
+      background-color: #67c23a;
+      margin-right: 0.14rem;
+    }
+    .title {
+      font-size: 0.32rem !important;
+      font-weight: normal !important;
+    }
+
+    .user-info {
+      font-size: 0.28rem;
+      color: #89919F !important;
+      margin: 0 0 0 0.2rem;
+    }
+
+    .cycle-type {
+      padding: 0.08rem;
+      border-radius: 0.1rem;
+      color: #26a2ff;
+      box-sizing: border-box;
+      background-color: #ecf5ff;
+    }
+
+    .examine-info {
+      font-size: 0.28rem;
+      position: relative;
+
+      .tips {
+        position: absolute;
+        top: 0.1rem;
+        right: -0.2rem;
+        .tip-item {
+          padding: 0.1rem;
+          border-top-left-radius: 0.1rem;
+          border-bottom-left-radius: 0.1rem;
+          color: #26a2ff;
+          z-index: 999;
+          box-sizing: border-box;
+          background-color: #ecf5ff;
+          margin-bottom: 0.1rem;
+        }
+      }
+      .info-item {
+        margin-bottom: 0.2rem;
+        color: #89919F !important;
+        .info-item-title {
+          width: 1.4rem;
+          color: #000;
+        }
+        .review-node {
+          padding: 0.01rem 0.1rem;
+          color: #fff;
+          border-radius: 2px;
+          font-size: 0.26rem;
+          background-color: #67c23a;
+          margin-left: 0.14rem;
+        }
+      }
+
+      .line {
+        width: 100%;
+        margin: 0.5rem auto;
+        height: 1px;
+        background-color: #f1f1f1;
+      }
+    }
+
+
+  }
+
+.all {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  position: relative;
+
+
+  .scroller {
+    flex: 1;
+    position: relative;
+  }
+
+  .workHeader /deep/ .van-grid-item {
+    margin-bottom: 0.2rem;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content {
+    padding: 0 !important;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__text {
+    font-size: 0.28rem;
+    color: #606266;
+    line-height: 0.44rem;
+    width: 1.4rem;
+    text-align: center;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__icon-wrapper img {
+    width: 1rem;
+    height: 1rem;
+    border-radius: 0.42rem;
+  }
+
+  .workHeader {
+    background-color: #fff;
+    font-size: 0.31rem;
+    padding-top: 0.4rem;
+    box-sizing: border-box;
+    .headcol {
+      position: relative;
+      .headicon {
+        width: 100%;
+        display: flex;
+        justify-content: center;
+        i {
+          margin: 0.4rem 0.1rem 0 0;
+        }
+      }
+    }
+  }
+
+
+
+
+
+  .my-attention-box {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0.2rem;
+    box-sizing: border-box;
+    background: #fff;
+    border-bottom: 1px solid #f1f1f1;
+    .my-attention {
+      flex: 1;
+      box-sizing: border-box;
+      background-color: #fff;
+      font-size: 0.32rem;
+    }
+  }
+}
+
+
+
+
+
+
+
+.list-item {
+  padding: 0.24rem 0.32rem;
+  font-size: 0.32rem;
+  border-bottom: 1px solid #f1f1f1;
+}
+
+
+
+
+
+
+.sidebar {
+  width: 2.2rem;
+  height: 0.5rem;
+  position: fixed;
+  right: 0px;
+  bottom: 2rem;
+  font-size: 0.28rem;
+  padding: 0.1rem 0.25rem;
+  border-top-left-radius: 0.05rem;
+  border-bottom-left-radius: 0.05rem;
+  display: flex;
+  color: #26a2ff;
+  box-sizing: border-box;
+  z-index: 999;
+  background-color: #ecf5ff;
+  i {
+    // margin: 0.05rem 0.15rem 0 0;
+    margin-right: 0.15rem;
+    color: #26a2ff;
+  }
+}
+
+
+</style>

+ 11 - 4
src/okr/components/public/Evolve.vue

@@ -2,18 +2,18 @@
   <div style="padding: 0.24rem;">
     <div>
       <div class="flex-box-end" style="margin-bottom: 0.2rem;" v-if="target_type!=5">
-        <div class="cursor add-task" @click="operation(1)" v-if="isOperation"><van-icon name="plus" /> 添加进展</div>
+        <div class="cursor add-task" @click="operation(1)" v-if="isOperation && !readonly"><van-icon name="plus" /> 添加进展</div>
       </div>
       <div class="flex-box-ce flex-d-center" style="margin-bottom: 0.2rem;" v-else>
         <div class="flex-1" style="font-size: 0.26rem;">进展记录</div>
-        <div class="cursor add-task2" @click="operation(1)" v-if="isOperation"><van-icon name="replay" /> 更新进展</div>
+        <div class="cursor add-task2" @click="operation(1)" v-if="isOperation  && !readonly"><van-icon name="replay" /> 更新进展</div>
       </div>
       <div v-for="(item, index) in krProcessList" :key="index" class="record-list">
         <div class="flex-box-ce record-date fontColorB">
           <userImage :user_name="item.userInfo.name" :img_url="item.userInfo.img_url" fontSize="0.26" width="0.6rem" height="0.6rem"></userImage>
           <div class="record-name">{{ item.userInfo.name }}</div>
           <span class="fontColorC flex-1">{{ item.create_time }} 添加了进展</span>
-          <span class="blue cursor" v-if="userId == item.userInfo.id" @click="operation(2, item)">编辑</span>
+          <span class="blue cursor" v-if="userId == item.userInfo.id  && !readonly" @click="operation(2, item)">编辑</span>
         </div>
         <div class="record-content">
           <pre class="pre fontColorA" style="font-size: 15px;" v-if="item.content">{{ item.content }}</pre>
@@ -100,6 +100,10 @@ export default {
       //是否可以操作
       type: Boolean,
       default: true
+    },
+    readonly: {
+      type: Boolean,
+      default: false
     }
   },
   data() {
@@ -258,7 +262,10 @@ export default {
     },
     //kr进展
     getProcess() {
-      this.$axiosUser('get', '/api/pro/okr/process/list', { target_type: this.target_type, target_id: this.target_id, page: 1, page_size: 100 }).then(res => {
+      let url;
+      if(!this.readonly) url = '/api/pro/okr/process/list'
+      else url = '/api/pro/okr/public/process/list'
+      this.$axiosUser('get', url, { target_type: this.target_type, target_id: this.target_id, page: 1, page_size: 100 }).then(res => {
         let list = res.data.data.list;
         list.forEach(item => {
           if(item.publisher_id){

+ 1 - 1
src/okr/view/project/projectDetail.vue

@@ -7,7 +7,7 @@
           <div class="flex-box">
             <span class="status" v-if="projectDetail.composite_state==3">已逾期</span>
             <div class="flex-1" style="font-weight: 600;padding: 0 0.2rem;padding-left: 0.1rem;">{{projectDetail.name}}</div>
-            <van-icon name="weapp-nav" class="fontColorB" v-if="isReturnPJ&&projectDetail.id" @click="isShowbelong=true"/>
+            <van-icon name="weapp-nav" class="fontColorB" v-if="isReturnPJ && projectDetail.id" @click="isShowbelong=true"/>
           </div>
           <div class="flex-box-ce" style="margin: 0.16rem 0;">
             <div class="progress"><div class="progress-inner" :class="{bjRed:projectDetail.composite_state==3}" :style="{width:projectDetail.process>100? '100%':projectDetail.process+'%'}"></div></div>

+ 2 - 2
src/okr/view/project/projectList.vue

@@ -26,7 +26,7 @@
       <template v-if="activeName=='c'||activeName=='d'">
         <div class="flex-box-ce" style="background-color: #fff;margin-bottom: 0.2rem;">
           <van-search style="border-radius: 25px;" class="flex-1" placeholder="请输入关键字" v-model="keyword" @input="keyVal()"/>
-          <div @click="show_dept_selector=true" class="dept-box flex-box-ce" :class="{isDept:dept_id}">
+          <div @click="show_dept_selector = true" class="dept-box flex-box-ce" :class="{isDept:dept_id}">
             <van-icon name="cluster-o"  class="dept-icon"/>
             <span style="font-size: 0.28rem;color: #606266;">部门</span>
           </div>
@@ -168,7 +168,7 @@ export default {
   },
   computed:{
     barColor(){
-      return function (item) { 
+      return function (item) {
         return item.day<0 ? (item.composite_state == 4?'#2879ff':'#f56c6c'):'#2879ff'
        }
     },

+ 3 - 3
src/okr/view/target/attentionList.vue

@@ -4,7 +4,7 @@
     <div class="work_body_com">
       <header class="flex-box-ce" style="padding: 0.2rem 0.32rem;background-color: #fff;">
         <div class="flex-1 fontColorB">人员</div>
-        <div class="blue" @click="selectUserAll=true"><van-icon name="plus" /> 添加</div>
+        <div class="blue" @click="selectUserAll = true"><van-icon name="plus" /> 添加</div>
       </header>
       <div class="scroller">
         <scroller ref="scroller_com">
@@ -55,7 +55,7 @@ export default {
     }
   },
   mounted() {
-    this.index=this.$route.query.index;
+    this.index = this.$route.query.index;
     this.getUserList()
   },
   methods: {
@@ -79,7 +79,7 @@ export default {
       }).catch(() => {})
     },
     confirmCreator(arr){
-      let target_ids=arr.employee.map(item=>{
+      let target_ids = arr.employee.map(item=>{
         return item.id
       }).toString();
       let data={

+ 10 - 5
src/okr/view/target/communication.vue

@@ -10,7 +10,7 @@
         </div>
         <div class="flex-1">
           <div class="name" style="margin-bottom: 5px;">{{detailData.name}}</div>
-          <div style="font-size: 0.26rem;" class="fontColorC">{{detailData.start_time||detailData.start_date}}~{{detailData.end_time||detailData.end_date}}</div>
+          <div style="font-size: 0.26rem;" class="fontColorC">{{detailData.start_time || detailData.start_date}}~{{detailData.end_time||detailData.end_date}}</div>
         </div>
       </header>
       <div class="main">
@@ -21,7 +21,7 @@
               <userImage  :id="item.publisher_id" width="0.7rem" height="0.7rem"></userImage>
               <div class="record-name">{{ $getEmployeeMapItem(item.publisher_id).name }}<span v-if="item.reply_employee_id"> <span style="font-weight: 500;" class="fontColorF">回复</span>{{ $getEmployeeMapItem(item.reply_employee_id).name }}</span> </div>
               <span class="fontColorC flex-1">{{item.create_time}}</span>
-              <van-popover placement="left" v-model="item.showPopover" trigger="click" :actions="actions" @select="onSelect($event,item)">
+              <van-popover v-if="!readonly" placement="left" v-model="item.showPopover" trigger="click" :actions="actions" @select="onSelect($event,item)">
                 <template #reference>
                   <van-icon name="ellipsis" class="fontColorC"/>
                 </template>
@@ -45,7 +45,7 @@
         <div v-else style="margin-top: 2rem;text-align: center;font-size: 0.3rem;" class="fontColorC">暂无沟通记录</div>
       </div>
     </div>
-    <footer class="footer" @click="isShowCommunication=true"><div class="fontColorC">有事沟通,可@Ta</div></footer>
+    <footer v-if="!readonly" class="footer" @click="isShowCommunication=true"><div class="fontColorC">有事沟通,可@Ta</div></footer>
 
     <van-popup v-model:show="isShowCommunication" round position="bottom" :style="{ height: '90%' }">
       <div class="content" style="">
@@ -95,6 +95,7 @@ export default {
   components:{Uploader,EmployeeSelector},
   data() {
     return {
+      readonly: false,
       showPopover:false,
       isShowCommunication:false,
       actions: [{ text: '回复' }, { text: '删除' }],
@@ -132,15 +133,19 @@ export default {
   },
   created(){
     if(this.$route.query.item){
-      this.detailData=JSON.parse(this.$route.query.item);
+      this.detailData = JSON.parse(this.$route.query.item);
       this.parameter.target_type=this.$route.query.target_type;
       this.parameter.target_id=this.detailData.id;
+      this.readonly = this.$route.query.readonly ? true : false;
       this.getList();
     }
   },
   methods: {
     getList(){
-       this.$axiosUser('get', '/api/pro/okr/feedback/list', {target_id:this.parameter.target_id,target_type:this.parameter.target_type,page:1,page_size:100}).then(res=>{
+      let url = ""
+      if(!this.readonly) url = '/api/pro/okr/feedback/list'
+      else url = "/api/pro/okr/public/feedback/list"
+       this.$axiosUser('get', url, {target_id:this.parameter.target_id,target_type:this.parameter.target_type,page:1,page_size:100}).then(res=>{
          let list=res.data.data.list;
          list.forEach(item=>{
            item.userInfo=this.$getEmployeeMapItem(item.publisher_id);

+ 23 - 16
src/okr/view/target/target.vue

@@ -15,6 +15,7 @@
           <van-tab v-for="(item,index) in tabs" :title="item.title" :name="item.name" :key="index" v-if="item.isShow"></van-tab>
         </van-tabs>
       </div>
+
       <template v-if="activeName=='a'">
         <div class="flex-box-ce flex-d-wrap" style="padding: 0 0.2rem;margin-top: 0.24rem;">
           <div class="search-item" style="border-radius: 25px;font-size: 0.28rem;" @click="targetType=item.id" v-for="(item, index) in targetTypeArr" :key="index" :class="item.id==targetType? 'searchActive':''">{{ item.name }}</div>
@@ -158,13 +159,14 @@
 
 <script>
 import Vue from 'vue';
-import {Picker,Popup,Circle,Icon,Tab, Tabs,} from 'vant';
+import {Picker, Popup, Circle, Icon,Tab, Tabs,} from 'vant';
 import { _debounce, _throttle } from '@/utils/auth';
 import { getBelongType,getColumns,cycleTypeArr} from '@/okr/utils/auth';
 
 import EmployeeSelector from '@/components/EmployeeSelector';
 import EmployeeDeptSelector from '@/components/EmployeeDeptSelector';
 Vue.use(Picker).use(Popup).use(Circle).use(Icon).use(Tabs).use(Tab)
+
 export default {
   components:{EmployeeSelector,EmployeeDeptSelector},
   name: 'Target',
@@ -180,7 +182,6 @@ export default {
       page_size:10,
       cycleTypeArr:cycleTypeArr(true),
       value:5,
-
       userId:this.$userInfo().id,
       userInfo: this.$userInfo(),
       dept_list:this.$userInfo().employee_detail.dept_list,
@@ -259,7 +260,7 @@ export default {
   },
   methods: {
     openGz(){
-      this.$router.push({name: 'attentionList',query:{index:1}})
+      this.$router.push({name: 'attentionList',query:{index: 1} })
     },
     getGzUserList(){
       this.$axiosUser('get', '/api/pro/okr/follow', { type:1 }).then(res=>{
@@ -310,7 +311,7 @@ export default {
     onConfirm (data, list) { // 确认
       let columns=this.columns[list[0]];
       let options=this.cycleTypeArr[list[1]]
-      this.selectPftiTheEcho=list
+      this.selectPftiTheEcho = list
       this.dateParameter={
         year: columns.value,
         cycle_type: options.cycle_type,
@@ -320,32 +321,34 @@ export default {
       this.pullDown();
       this.pullonThePanel = false
     },
+
     pullDown(){
       setTimeout(() => {
         this.$refs.scroller.triggerPullToRefresh();
       }, 50);
     },
+
     theEchoVanPicker() { // 回显
       this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
     },
 
-    getList(is,callback){
+    getList(is, callback){
       let hasMore = false
-      is? '':this.page=1;
+      is ? '' : this.page = 1;
       let params = {
-        page:is? this.page:1,
+        page: is ? this.page : 1,
         page_size: this.page_size,
-        cycle_type:this.dateParameter.cycle_type,
-        year:this.dateParameter.year,
-        belong_type:this.belong_type,
+        cycle_type: this.dateParameter.cycle_type,
+        year: this.dateParameter.year,
+        belong_type: this.belong_type,
         quarter:0,
         half_year:0,
         month:0,
         sort_ct:2
       };
 
-      if(this.activeName=='a'){ //我的目标
-        this.targetType==1? params.owner_id=this.userId:this.targetType==2? params.joiner_id=this.userId:params.follower_id=this.userId;
+      if(this.activeName=='a') { //我的目标
+        this.targetType==1 ? params.owner_id=this.userId:this.targetType==2? params.joiner_id=this.userId:params.follower_id=this.userId;
       }else if(this.activeName=='b'){//我的部门
         params.dept=this.deptInfo.dept_id;
         params.owner_id=this.ownerUserInfo.id;
@@ -396,12 +399,12 @@ export default {
     },
     // 上拉刷新
     refresh (done) {
-      this.getList(false,done)
+      this.getList(false, done)
     },
     // 下拉加载
     infinite (done) {
-      this.page++;
-      this.getList(true,done)
+      this.page ++;
+      this.getList(true, done)
     },
   },
   created() {
@@ -439,6 +442,9 @@ export default {
     line-height: .4rem;
     color: #89919f;
     border-radius: 2rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
 }
 .userName{
     font-size: 0.28rem;
@@ -571,7 +577,8 @@ export default {
   font-size: 0.28rem;
   margin-bottom: 0.2rem;
 }
-.search-item{
+
+.search-item {
   padding: 0.06rem 0.1rem;
   background-color: #F7F8FA;
   color: #89919F;

+ 10 - 10
src/okr/view/target/targetDetail.vue

@@ -451,16 +451,16 @@ export default {
     },
     //更新完成度
     updateProgress(){
-        let item=this.targetDetail;
-        this.progressData={
-          target_type:1,
-          id:item.id,
-          o_id:item.id,
-          process:Number(item.process),
-          risk_level:item.risk_level,
-          process_conf:item.process_conf,
-        }
-        this.isShwoUpdateProgress=true;
+      let item=this.targetDetail;
+      this.progressData={
+        target_type:1,
+        id:item.id,
+        o_id:item.id,
+        process:Number(item.process),
+        risk_level:item.risk_level,
+        process_conf:item.process_conf,
+      }
+      this.isShwoUpdateProgress=true;
     },
     //获取最新字段
     getProcess(){

+ 104 - 70
src/okr/view/task/taskDetail.vue

@@ -2,13 +2,13 @@
   <div style="height: 100%;">
     <van-nav-bar title="任务详情"  :left-text="isHome? '首页':'返回'" @click-left="routeBack" left-arrow />
     <div class="all-box" id="all-box">
-      <template v-if="taskDetail.visible==1">
+      <template v-if="taskDetail.visible == 1 || readonly">
         <header class="header">
           <div class="flex-box">
             <div class="flex-1" style="font-weight: 600;padding-right: 0.2rem;word-break:break-all;">
               <span class="status">{{taskStatus(taskDetail.composite_state).name}}</span>
               {{taskDetail.name}}</div>
-            <van-icon name="weapp-nav" class="fontColorB weapp" @click="isShowbelong = true" v-if="taskDetail.id"/>
+            <van-icon name="weapp-nav" class="fontColorB weapp" @click="isShowbelong = true" v-if="taskDetail.id && !readonly"/>
           </div>
           <div class="flex-box-ce fontColorC header-message" style="font-size: 0.26rem;margin-top:0.24rem">
             <span>{{$moment(taskDetail.start_date).format('MM/DD HH:mm')}}~{{$moment(taskDetail.end_date).format('MM/DD HH:mm')}}</span>
@@ -22,37 +22,37 @@
             <pre style="margin: 5px 0;">{{taskDetail.content}}</pre>
           </div>
           <div class="box">
-            <div class="flex-box-ce" @click="updateTaskData(1)">
+            <div class="flex-box-ce" @click="!readonly && updateTaskData(1)">
               <div class="label">任务进度</div>
               <div class="flex-1 fontColorA">{{taskDetail.process}}%
-                <span class="orange" style="padding-left: 0.1rem;font-size: 0.24rem;" v-if="taskDetail.quantify.target">请填写【实际值】,进度将自动更新</span>
+                <span class="orange" style="padding-left: 0.1rem;font-size: 0.24rem;" v-if="!readonly && taskDetail.quantify.target">请填写【实际值】,进度将自动更新</span>
               </div>
-              <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+              <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
             </div>
 
-            <div class="flex-box-ce" @click="updateTaskData(2)" v-if="taskDetail.quantify.target">
+            <div class="flex-box-ce" @click="!readonly && updateTaskData(2)" v-if="taskDetail.quantify.target">
               <div class="label">量化指标</div>
               <div class="flex-1 fontColorA">
                 目标值<span class="cyan" style="padding: 0 0.1rem;font-weight: 700;">{{taskDetail.quantify.target}}</span>{{taskDetail.quantify.unit}}&nbsp;&nbsp;
                 实际值<span class="cyan" style="padding: 0 0.1rem;font-weight: 700;">{{taskDetail.quantify.result}}</span>{{taskDetail.quantify.unit}}
               </div>
-              <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+              <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
             </div>
-            <div class="flex-box-ce" @click="updateTaskData(3)" v-if="taskDetail.feedback">
+            <div class="flex-box-ce" @click="!readonly && updateTaskData(3)" v-if="taskDetail.feedback">
               <div class="label">反馈时间</div>
               <div class="flex-1 fontColorA">{{feedbackData.feedbackTime}}</div>
-              <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+              <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
             </div>
-            <div class="flex-box-ce" @click="updateTaskData(4)" v-if="taskDetail.wh">
+            <div class="flex-box-ce" @click="!readonly && updateTaskData(4)" v-if="taskDetail.wh">
               <div class="label">预估时间</div>
               <div class="flex-1 fontColorA">{{taskDetail.wh}}小时</div>
-              <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+              <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
             </div>
 
-            <div class="flex-box-ce" @click="updateTaskData(5)">
+            <div class="flex-box-ce" @click="!readonly && updateTaskData(5)">
               <div class="label">可见范围</div>
               <div class="flex-1 fontColorA">{{taskDetail.visible_type==1? '全公司':taskDetail.visible_type==2? '相关成员':'指定部门'}}</div>
-              <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+              <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
             </div>
             <div class="flex-box-ce" v-if="taskDetail.visible_type==5">
               <div class="label"></div>
@@ -61,23 +61,23 @@
           </div>
         </header>
         <div v-if="isShow">
-          <div class="kuai" v-if="!taskDetail.quantify.target||!taskDetail.feedback||!taskDetail.wh">
+          <div class="kuai" v-if="!taskDetail.quantify.target || !taskDetail.feedback || !taskDetail.wh">
             <div class="flex-box flex-d-center"><div class="box-title">任务要求</div></div>
             <div class="box" style="padding: 0 0.24rem;">
-                <div class="flex-box-ce" @click="updateTaskData(2)" v-if="!taskDetail.quantify.target">
+                <div class="flex-box-ce" @click="!readonly && updateTaskData(2)" v-if="!taskDetail.quantify.target">
                   <div class="label">量化指标</div>
                   <div class="flex-1">设置量化指标</div>
-                  <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+                  <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
                 </div>
-                <div class="flex-box-ce" @click="updateTaskData(3)" v-if="!taskDetail.feedback">
+                <div class="flex-box-ce" @click="!readonly && updateTaskData(3)" v-if="!taskDetail.feedback">
                   <div class="label">反馈时间</div>
                   <div class="flex-1">选择反馈时间</div>
-                  <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+                  <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
                 </div>
-                <div class="flex-box-ce" @click="updateTaskData(4)" v-if="!taskDetail.wh">
+                <div class="flex-box-ce" @click="!readonly && updateTaskData(4)" v-if="!taskDetail.wh">
                   <div class="label">预估工时</div>
                   <div class="flex-1">暂无设置</div>
-                  <van-icon name="arrow" v-if="taskDetail.can_edit_normal"/>
+                  <van-icon name="arrow" v-if="!readonly && taskDetail.can_edit_normal"/>
                 </div>
             </div>
           </div>
@@ -85,7 +85,7 @@
           <div class="kuai">
             <div class="flex-box flex-d-center">
                 <div class="box-title">相关人员</div>
-                <div class="fontColorB" style="font-size: 0.28rem;padding-right: 0.2rem;" v-if="taskDetail.can_edit_normal"><span @click="isUpdate=!isUpdate">{{isUpdate==false? '编辑':'完成'}}</span></div>
+                <div class="fontColorB" style="font-size: 0.28rem;padding-right: 0.2rem;" v-if="!readonly && taskDetail.can_edit_normal"><span @click="isUpdate=!isUpdate">{{isUpdate==false? '编辑':'完成'}}</span></div>
             </div>
             <div style="padding: 0 0.24rem;">
               <div class="flex-box-ce" style="margin-top: 0.24rem;">
@@ -113,12 +113,12 @@
                   <div style="text-align: center;width: 1.06rem">
                     <userImage :img_url="taskDetail.r_userInfo.img_url" :user_name="taskDetail.r_userInfo.name" width="0.7rem" height="0.7rem"></userImage>
                     <div style="font-size: 0.26rem;padding: 0.1rem 0;" class="font-flex-word">{{ taskDetail.r_userInfo.name }}</div>
-                    <div class="zj2" v-if="isUpdate&&taskDetail.can_edit_reviewer" @click="deleteUser(1)">删除</div>
+                    <div class="zj2" v-if="!readonly && isUpdate &&taskDetail.can_edit_reviewer" @click="deleteUser(1)">删除</div>
                   </div>
-                  <div class="zj" v-if="isUpdate&&taskDetail.can_edit_reviewer" @click="openSelectUser(3)">转交</div>
+                  <div class="zj" v-if="!readonly && isUpdate && taskDetail.can_edit_reviewer" @click="openSelectUser(3)">转交</div>
                 </div>
                 <template v-else>
-                  <div class="addUser" v-if="isUpdate&&taskDetail.can_edit_reviewer" @click="openSelectUser(3)">+</div>
+                  <div class="addUser" v-if="!readonly && isUpdate && taskDetail.can_edit_reviewer" @click="openSelectUser(3)">+</div>
                   <div v-else style="font-size: 0.24rem;" class="fontColorD">暂无审批人</div>
                 </template>
 
@@ -130,12 +130,12 @@
                       <div class="flex-box-v" style="margin-right: 0.2rem;text-align: center;margin-bottom: 0.2rem;position: relative;"  v-for="(item, index) in taskDetail.joiner_employee_items"  :key="index" >
                         <userImage :img_url="item.img_url" :user_name="item.name" width="0.7rem" height="0.7rem"></userImage>
                         <div style="font-size: 0.26rem;padding: 0.1rem 0;width: 1.06rem" class="font-flex-word">{{ item.name }}</div>
-                        <div class="zj2" v-if="isUpdate" @click="joinerUpdate(false,item.id)">删除</div>
+                        <div class="zj2" v-if="!readonly && isUpdate" @click="joinerUpdate(false,item.id)">删除</div>
                       </div>
-                      <div class="addUser" v-if="isUpdate" @click="openSelectUser(4)">+</div>
+                      <div class="addUser" v-if="!readonly && isUpdate" @click="openSelectUser(4)">+</div>
                   </template>
                   <template v-else>
-                    <div class="addUser" v-if="isUpdate" @click="openSelectUser(4)">+</div>
+                    <div class="addUser" v-if="!readonly && isUpdate" @click="openSelectUser(4)">+</div>
                     <div v-else style="font-size: 0.24rem;" class="fontColorD">暂无参与人员</div>
                   </template>
                 </div>
@@ -145,20 +145,20 @@
           <div class="kuai">
             <div class="flex-box flex-d-center">
                 <div class="box-title">任务属性</div>
-                <div class="fontColorB" style="font-size: 0.28rem;padding-right: 0.2rem;" v-if="taskDetail.can_edit_normal"><span @click="isUpdate=!isUpdate">{{isUpdate==false? '编辑':'完成'}}</span></div>
+                <div class="fontColorB" style="font-size: 0.28rem;padding-right: 0.2rem;" v-if="!readonly && taskDetail.can_edit_normal"><span @click="isUpdate=!isUpdate">{{isUpdate==false? '编辑':'完成'}}</span></div>
             </div>
             <div class="box" style="padding: 0 0.24rem;">
               <div class="flex-box" style="margin-top: 0.24rem;">
                 <div class="label">母任务</div>
                 <div v-if="taskDetail.pid" class="flex-1">
-                    <div v-if="isUpdate" class="flex-box" style="margin-top: 0;">
+                    <div v-if="!readonly && isUpdate" class="flex-box" style="margin-top: 0;">
                         <span class="blue flex-1 clamp2" style="margin-right: 0.2rem;max-width: 4.9rem;" @click="isShwoTaskSearch=true">{{taskDetail.pname}}</span>
                         <van-icon name="clear" @click="relieveKr(3)"/>
                     </div>
                     <span class="fontColorA" v-else>{{taskDetail.pname}}</span>
                 </div>
                 <div v-else class="flex-1">
-                  <span v-if="isUpdate" class="blue" @click="isShwoTaskSearch=true">+ 添加</span>
+                  <span v-if="!readonly && isUpdate" class="blue" @click="isShwoTaskSearch=true">+ 添加</span>
                   <span v-else>暂无母任务</span>
                 </div>
 
@@ -167,7 +167,7 @@
                 <div class="label">所属KR/项目</div>
 
                 <div v-if="taskDetail.main.kr_id" class="flex-1">
-                    <div v-if="isUpdate" class="flex-box-ce" style="margin-top: 0;">
+                    <div v-if="!readonly && isUpdate" class="flex-box-ce" style="margin-top: 0;">
                         <div @click="openGlKr(1)" style="margin-right: 0.2rem;max-width: 4.9rem;">
                           <div class="blue flex-1 clamp">O -&nbsp;{{taskDetail.main.o_name}}</div>
                           <div class="blue flex-1 clamp">KR -&nbsp;{{taskDetail.main.kr_name}}</div>
@@ -181,7 +181,7 @@
                 </div>
 
                 <div v-else-if="taskDetail.main.milestone_id" class="flex-1">
-                    <div v-if="isUpdate" class="flex-box-ce" style="margin-top: 0;">
+                    <div v-if="!readonly && isUpdate" class="flex-box-ce" style="margin-top: 0;">
                         <div @click="openGlKr(1)" style="margin-right: 0.2rem;max-width: 4.9rem;">
                           <div class="blue flex-1 clamp">项目 -&nbsp;{{taskDetail.main.project_name}}</div>
                           <div class="blue flex-1 clamp">里程碑 -&nbsp;{{taskDetail.main.milestone_name}}</div>
@@ -195,7 +195,7 @@
                 </div>
 
                 <div v-else-if="taskDetail.main.project_id" class="flex-1">
-                    <div v-if="isUpdate" class="flex-box" style="margin-top: 0;">
+                    <div v-if="!readonly && isUpdate" class="flex-box" style="margin-top: 0;">
                         <span class="blue flex-1 clamp2" style="margin-right: 0.2rem;max-width: 4.9rem;" @click="openGlKr(1)">项目&nbsp;{{taskDetail.main.project_name}}</span>
                         <van-icon name="clear" @click="relieveKr(4)"/>
                     </div>
@@ -203,7 +203,7 @@
                 </div>
 
                 <div v-else class="flex-1">
-                  <span v-if="isUpdate" class="blue" @click="openGlKr(1)">+ 添加</span>
+                  <span v-if="!readonly && isUpdate" class="blue" @click="openGlKr(1)">+ 添加</span>
                   <span v-else>暂无</span>
                 </div>
               </div>
@@ -211,13 +211,14 @@
                 <div class="label">关联其他</div>
                 <div v-if="taskDetail.others.length>0" class="flex-1">
                     <div v-for="(item,index) in taskDetail.others" class="flex-box" style="margin-bottom: 0.2rem;">
-                      <span class="flex-1 font-flex-word fontColorA" style="margin-right: 0.2rem;max-width: 4.9rem;"><span class="blue">KR</span>-{{item.kr_name}}</span>
-                      <van-icon name="clear" @click="relieveKr(2,item)" v-if="isUpdate"/>
+                      <span class="flex-1 font-flex-word fontColorA" style="margin-right: 0.2rem;max-width: 4.9rem;">
+                        <span class="blue">KR</span>-{{item.kr_name}}</span>
+                      <van-icon name="clear" @click="relieveKr(2,item)" v-if="!readonly && isUpdate"/>
                     </div>
-                    <span v-if="isUpdate" class="blue" @click="openGlKr(2)">+ 添加关联</span>
+                    <span v-if="!readonly && isUpdate" class="blue" @click="openGlKr(2)">+ 添加关联</span>
                 </div>
                 <div v-else class="flex-1">
-                  <span v-if="isUpdate" class="blue" @click="openGlKr(2)">+ 添加关联</span>
+                  <span v-if="!readonly && isUpdate" class="blue" @click="openGlKr(2)">+ 添加关联</span>
                   <span v-else>暂无</span>
                 </div>
               </div>
@@ -226,13 +227,17 @@
           <div class="kuai">
             <div class="flex-box flex-d-center">
               <div class="box-title">其他属性</div>
-              <div class="fontColorB" style="font-size: 0.28rem;padding-right: 0.2rem;" v-if="taskDetail.can_edit_normal"><span @click="isUpdate=!isUpdate">{{isUpdate==false? '编辑':'完成'}}</span></div>
+              <div class="fontColorB" style="font-size: 0.28rem;padding-right: 0.2rem;" v-if="!readonly && taskDetail.can_edit_normal">
+                <span @click="isUpdate=!isUpdate">
+                  {{isUpdate==false? '编辑':'完成'}}
+                </span>
+              </div>
             </div>
             <div class="box" style="padding: 0 0.24rem;">
               <div class="flex-box" style="margin-top: 0.24rem;">
                 <div class="label">任务附件</div>
-                <template v-if="isUpdate&&taskDetail.can_edit_normal">
-                      <Uploader v-model="file" :limit="1" :max-count="1" :beforeRead="beforeRead2" :accept="accept"><span>添加附件</span></Uploader>
+                <template v-if="!readonly && isUpdate && taskDetail.can_edit_normal ">
+                  <Uploader v-model="file" :limit="1" :max-count="1" :beforeRead="beforeRead2" :accept="accept"><span>添加附件</span></Uploader>
                 </template>
               </div>
             </div>
@@ -245,7 +250,7 @@
                   <img v-else src="static/images/excel_icon.png" width="50" height="50" @click="downWgt(src.file)"/>
                   <div style="padding-left: 0.2rem;font-size: 0.26rem;max-width: 260px;overflow: hidden;" class="font-flex-word">{{src.name}}</div>
                 </div>
-                <van-icon name="clear" v-if="isUpdate" class="fontColorD" @click="deleteFlie(src.file)"/>
+                <van-icon name="clear" v-if="!readonly && isUpdate" class="fontColorD" @click="deleteFlie(src.file)"/>
               </div>
             </div>
           </div>
@@ -257,7 +262,7 @@
           <van-tabs v-model="tabActive" class="shadow">
             <van-tab :title="item" v-for="(item, index) in tabs" :key="index">
                 <template #title>
-                    <span v-if="item=='子任务'&&taskDetail.statistics.plan_total">{{item}}({{taskDetail.statistics.plan_total}})</span>
+                    <span v-if=" item=='子任务' && taskDetail.statistics.plan_total">{{item}}({{taskDetail.statistics.plan_total}})</span>
                     <span v-else>{{item}}</span>
                 </template>
             </van-tab>
@@ -271,7 +276,7 @@
                     <userImage  :id="item.publisher_id"  fontSize="0.28" width="0.7rem" height="0.7rem"></userImage>
                     <div class="record-name">{{ $getEmployeeMapItem(item.publisher_id).name }}<span v-if="item.reply_employee_id"><span style="font-weight: 500;" class="fontColorF">回复</span>{{ $getEmployeeMapItem(item.reply_employee_id).name }}</span></div>
                     <span class="fontColorC flex-1">{{item.create_time}}</span>
-                    <van-popover placement="left" v-model="item.showPopover" trigger="click" :actions="actions" @select="onSelect($event,item)">
+                    <van-popover v-if="!readonly" placement="left" v-model="item.showPopover" trigger="click" :actions="actions" @select="onSelect($event,item)">
                       <template #reference>
                         <van-icon name="ellipsis"  class="fontColorC"/>
                       </template>
@@ -297,13 +302,13 @@
           </template>
           <template v-if="tabActive==1">
             <div style="padding: 0.24rem;">
-              <div class="flex-box-end"><div class="blue" style="font-size: 0.26rem;margin-bottom: 0.24rem;" @click="addTask()" v-if="taskDetail.can_edit_normal">+ 添加子任务</div></div>
+              <div class="flex-box-end"><div class="blue" style="font-size: 0.26rem;margin-bottom: 0.24rem;" @click="addTask()" v-if="!readonly && taskDetail.can_edit_normal">+ 添加子任务</div></div>
               <div class="flex-box list-item" v-for="(item,index) in taskList" :key="index">
                 <van-icon :name="taskStatus(item.composite_state).icon" class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;" />
                 <div class="flex-1">
                   <div class="flex-box">
                       <div class="clamp2 flex-1" style="margin-bottom: 5px;font-size: 0.28rem;padding-right: 0.2rem;" @click="openDetail(item)">{{item.name}}</div>
-                      <template v-if="taskDetail.can_edit_normal">
+                      <template v-if="!readonly && taskDetail.can_edit_normal">
                         <van-popover placement="left" v-model="item.showPopover" trigger="click" :actions="[{ text: '取消关联' }]" @select="onSelect2($event,item)">
                           <template #reference>
                             <van-icon name="ellipsis"  class="fontColorC"/>
@@ -325,7 +330,9 @@
             </div>
           </template>
           <template v-if="tabActive==2">
-            <Evolve ref="evolve"
+            <Evolve
+              ref="evolve"
+              :readonly="readonly"
               @confirm="getTaskDateil"
               :isUpdateProcess.sync="isUpdateProcess"
               :isOperation="isOperation"
@@ -338,7 +345,7 @@
                     <div v-for="(item,index) in taskDetail.review_info" :key="index" style="margin-bottom: 0.2rem;font-size: 0.28rem;">
                       <div class="flex-box-ce">
                         <span class="status-btn" :class="{greenBj:item.status==1,redBj:item.status==2}">
-                          {{item.status==0? '审批中':item.status==1? '已通过':'已拒绝'}}
+                          {{item.status==0? '审批中' : item.status == 1? '已通过':'已拒绝'}}
                         </span>
                         <span class="fontColorC" style="padding-right: 10px;">
                             <template v-if="item.status==0">{{$moment(Number(item.event_time+'000')).format('YYYY-MM-DD HH:mm:ss')}}</template>
@@ -357,7 +364,7 @@
                         <div>理由: </div>
                         <div class="flex-1">{{item.refuse_content}}</div>
                       </div>
-                      <div v-if="item.status==0&&index==0&&item.reviewer_id==userInfo.id&&taskDetail.can_submit_review" class="flex-box-end" style="margin-top: 0.2rem;">
+                      <div v-if="!readonly && item.status==0&&index==0&&item.reviewer_id==userInfo.id&&taskDetail.can_submit_review" class="flex-box-end" style="margin-top: 0.2rem;">
                          <div class="btns btns2" @click="reviewT(2)">拒绝</div>
                          <div class="btns" @click="reviewT(1)">通过</div>
                       </div>
@@ -368,14 +375,14 @@
           </template>
           <template v-if="tabActive==4">
             <div style="padding: .24rem;">
-              <div class="flex-box-end" v-if="isOperation"><div class="blue" style="font-size: 0.26rem;margin-bottom: 0.24rem;" @click="openPlan()">+ 添加工时</div></div>
+              <div class="flex-box-end" v-if="!readonly && isOperation"><div class="blue" style="font-size: 0.26rem;margin-bottom: 0.24rem;" @click="openPlan()">+ 添加工时</div></div>
               <div class="flex-box-ce fontColorC" style="margin-bottom: 0.24rem;">
                  <span style="font-size: 14px;">任务工时总计</span>
                  <div style="padding-left: 10px;"><span class="time" style="margin: 0;">{{planSum}}h</span></div>
               </div>
               <div v-for="(item,index) in planList" :key="index">
                 <div class="flex-box-ce child-task-item" style="font-size: 13px;">
-                    <div class="flex-1 font-flex-word black" style="padding-right: 20px;" @click="openPlan(item)">{{item.name}}</div>
+                    <div class="flex-1 font-flex-word black" style="padding-right: 20px;" @click="!readonly && openPlan(item)">{{item.name}}</div>
                     <span class="time">{{item.time_format}}</span>
                     <span class="cursor fontColorC" style="padding-left: 0.2rem;" @click="item.isShow=!item.isShow">
                       <span v-if="item.isShow">收起 <van-icon name="arrow-up" /></span>
@@ -395,7 +402,7 @@
           </template>
         </div>
 
-        <footer class="footer">
+        <footer class="footer" v-if="!readonly">
           <div class="flex-box-ce" v-if="taskDetail.can_finish||taskDetail.can_start_review">
               <div class="btn flex-1" @click="activebelong({value:3})">完成任务</div>
               <van-icon name="chat-o" @click="isShowCommunication=true" style="font-size:0.6rem;margin-left: 0.2rem;" class="fontColorC"/>
@@ -406,6 +413,11 @@
           </div>
           <div v-else class="fontColorC gt" @click="isShowCommunication=true">有事沟通,可@Ta</div>
         </footer>
+        <!-- <footer class="footer" v-else>
+          <div class="flex-box-ce">
+            <van-icon name="chat-o" @click="isShowCommunication=true" style="font-size:0.6rem;margin-left: 0.2rem;" class="fontColorC"/>
+          </div>
+        </footer> -->
       </template>
       <van-row type="flex" justify="space-around" class="c" v-else>
          <van-col span="24">
@@ -588,6 +600,7 @@ export default {
   name: 'krDetail',
   data() {
     return {
+      readonly: false,
       minDate: new Date(2020, 0, 1),
       maxDate: new Date(2050, 10, 1),
       id:0,
@@ -696,7 +709,7 @@ export default {
       isUpdateProcess:false,
       // 量化配置
       target:0,//目标
-      unit:this.$getCache('unitList')[0].name,//单位
+      unit: this.$getCache('unitList')[0].name,//单位
       result:0,//结果值
       // 反馈时间
       feedbackData:{
@@ -732,8 +745,8 @@ export default {
     file(val){
       if(val.length>0){
         this.$axiosUser('post', '/api/pro/okr/plan/file',{plan_id:this.id,file:val[0]}).then(res => {
-            this.file=[];
-            this.getTaskDateil()
+          this.file=[];
+          this.getTaskDateil()
         })
       }
     },
@@ -779,6 +792,9 @@ export default {
     if(this.$route.query.id){
       this.id=this.$route.query.id;
     }
+    if(this.$route.query.readonly){
+      this.readonly = true
+    }
     if(this.$route.query.isHome){
        this.isHome = true;
     }else{
@@ -798,6 +814,7 @@ export default {
     }
   },
   methods: {
+
     routeBack(){
       this.isHome? this.$router.replace({ name: 'home' }):this.$route_back();
     },
@@ -873,7 +890,7 @@ export default {
     ActiveRelevanceTask(item){
       if(item.id){
         this.$axiosUser('POST', '/api/pro/okr/plan/relate/plan',{plan_id:this.id,target_plan_id:item.id}).then(res => {
-             this.getTaskDateil();
+         this.getTaskDateil();
         })
       }else{
         this.relieveKr(3)
@@ -975,7 +992,7 @@ export default {
           })
       }else{
         this.$axiosUser('post','api/pro/okr/plan/quantify',{plan_id:this.id,target:this.target,unit:this.unit}).then(res => {
-            this.getTaskDateil();
+          this.getTaskDateil();
         })
       }
       this.isShowAllocation=false;
@@ -1195,9 +1212,11 @@ export default {
       })
     },
     openDetail(item){
-      // this.id=item.id;
-        this.$router.push({ path: `/taskDetailId/${item.id}`, query: {id: item.id} }) // -> /user/eduardo
-        // this.$router.push({name: 'taskDetail', query: {id: item.id}})
+      let query = {
+        id: item.id
+      }
+      if(this.readonly) query.readonly = true
+        this.$router.push({ path: `/taskDetailId/${item.id}`, query }) // -> /user/eduardo
     },
     addTask(){
        let data={
@@ -1274,13 +1293,16 @@ export default {
     },
     getPlanList(){
       this.planSum=0;
-      this.$axiosUser('get', '/api/pro/okr/task_time/list/plan',{plan_id:this.id}).then(res => {
-           let list=res.data.data.list
-           list.forEach(item=>{
-             item.isShow=false;
-             this.planSum=this.floatAdd(this.planSum,parseFloat(item.time_format))
-           })
-           this.planList=list;
+      let url = '';
+      if(!this.readonly) url = '/api/pro/okr/task_time/list/plan'
+      else url = '/api/pro/okr/public/task_time/list/plan'
+      this.$axiosUser('get', url, {plan_id:this.id}).then(res => {
+        let list=res.data.data.list
+        list.forEach(item=>{
+          item.isShow=false;
+          this.planSum=this.floatAdd(this.planSum,parseFloat(item.time_format))
+        })
+        this.planList=list;
       })
     },
     floatAdd(arg1,arg2){ //解决JS精度问题
@@ -1321,7 +1343,10 @@ export default {
       if(!this.id){
         return false
       }
-     this.$axiosUser('get', '/api/pro/okr/plan/list/sub',{plan_id:this.id}).then(res => {
+      let url = ""
+      if(!this.readonly) url = '/api/pro/okr/plan/list/sub'
+      else url = '/api/pro/okr/public/plan/list/sub'
+     this.$axiosUser('get', url, {plan_id:this.id}).then(res => {
            let list=res.data.data.list
            list.forEach(item=>{
              item.showPopover=false;
@@ -1361,7 +1386,10 @@ export default {
       }
     },
     getFeedbackList(){
-       this.$axiosUser('get', '/api/pro/okr/feedback/list', {target_id:this.id,target_type:3,page:1,page_size:100}).then(res=>{
+      let url = ""
+      if(!this.readonly) url = '/api/pro/okr/feedback/list'
+      else url = '/api/pro/okr/public/feedback/list'
+       this.$axiosUser('get', url, {target_id:this.id,target_type:3,page:1,page_size:100}).then(res=>{
          let list=res.data.data.list;
          list.forEach(item=>{
            item.userInfo=this.$getEmployeeMapItem(item.publisher_id);
@@ -1387,6 +1415,7 @@ export default {
       }
       return isJPG;
     },
+
     // 返回布尔值
     beforeRead(file) {
       const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
@@ -1395,6 +1424,7 @@ export default {
       }
       return isJPG;
     },
+
     addGt(){
       let par={
         target_type:3,
@@ -1423,7 +1453,10 @@ export default {
     //任务详情
     getTaskDateil(){
        this.loading=true;
-       this.$axiosUser('get', '/api/pro/okr/plan/info',{plan_id:this.id}).then(res => {
+       let url = ""
+       if(!this.readonly) url = '/api/pro/okr/plan/info'
+       else url = '/api/pro/okr/public/plan/info'
+       this.$axiosUser('get', url, {plan_id:this.id}).then(res => {
             let data=res.data.data;
             data.day=this.$moment(data.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
             data.p_userInfo=this.$getEmployeeMapItem(data.publisher_id)//发布人
@@ -1613,6 +1646,7 @@ export default {
     bottom: 0;
     z-index: 999;
     box-shadow: 0px -3px 0.15rem #f7f8fa;
+    box-sizing: border-box;
   }
   .footer .gt {
     border-radius: 0.5rem;

+ 522 - 0
src/performance-07-19/components/actionplan/actionplanDetails.vue

@@ -0,0 +1,522 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar :title="detailsTIt" left-text="" left-arrow @click-left="$route_back" />
+    <!-- <scroller class="all" style="position: relative"> -->
+    <div  class="all">
+      <header class="performanceList">
+        <div style="padding:.05rem 0 .15rem 0;font-size:.32rem;">{{ apDetails.name }}</div>
+        <div class="intro" style="font-size:.26rem;">
+          <span style="color:rgb(171, 171, 171);">考核标准:</span>
+          <br />
+          <span class="line-feed" v-html="apDetails.per_remark"></span>
+          <br />
+          <span style="color:rgb(86, 153, 255);" @click="detailsshow = true">查看详情</span>
+        </div>
+      </header>
+      <div class="flex-box-ce flex-d-center" style="padding:.2rem .25rem;background-color: rgb(245, 245, 245);">
+        <span @click="isWt = true" class="flex-box-ce" style="font-size:.27rem;">
+          {{ detailsTIt }}
+          <van-icon style="padding-left: .12rem;font-size: 0.32rem;" name="question-o" />
+        </span>
+        <button
+          v-if="isShowAdd&&!has_finish"
+          style="width: 1.45rem;
+            height: .5rem;
+            border-radius: 1.45rem;
+            border: 1px solid #4c8df1;
+            font-size: 0.28rem;
+            color: #127cff;
+            background-color: rgb(255, 255, 255);
+            margin-top: .04rem;"
+          @click="save()"
+        >
+          <span style="font-size: 18px;line-height: 0px;"></span>
+          <span>保存</span>
+        </button>
+      </div>
+      <div class="planText" v-if="isShowAdd && !has_finish">
+        <van-cell-group style="margin-top: 0rem;">
+          <van-field :label="detailsTIt" v-model="titValue" rows="3" type="textarea" autosize maxlength="200" :placeholder="'请输入' + detailsTIt" show-word-limit />
+          <div></div>
+          <van-field label="备注" v-model="messageVal" rows="3" type="textarea" autosize maxlength="500" placeholder="选填,请输入备注" show-word-limit />
+          <van-cell><Uploader v-model="img_fileList" :max-count="3" :beforeRead="beforeRead" :accept="accept"/></van-cell>
+        </van-cell-group>
+      </div>
+      <div style="padding-bottom:2rem;">
+        <van-empty :description="'暂无' + detailsTIt" v-if="apdList.length == 0" />
+        <div v-else v-for="(item, index) in apdList" :key="index"  class="apdList flex-box" :class="{apdListMarTop: index == 0}">
+          <div style="margin: .24rem 0 0 .2rem;position: relative;">
+            <div class="apdDian"></div>
+            <div class="apdHeadBoeder" :class="{apdborderNO: index ==  apdList.length - 1 || apdList.length <= 1}"></div>
+          </div>
+          <div class="apdData" :class="{apdborderNO: apdList.length == index + 1}">
+            <div @click="addThePlan(item)">
+                <b class="line-feed" style="font-size:.3rem;color:block;">{{ item.title }}</b>
+                <br />
+                <span style="font-size:.24rem;color:#b7b7b7;">
+                  {{ item.date }} 更新
+                  <span v-if="knowFrom == 'admnin' && $getEmployeeMapItem(item.employee_id)">&nbsp; 记录人:{{ $getEmployeeMapItem(item.employee_id).name }}</span>
+                </span>
+                <br />
+                <span class="line-feed" style="font-size:.25rem;color:#505050;" v-html="item.remark"></span>
+            </div>
+            <template v-if="item.images">
+              <div class="flex-box-ce" style="margin: 10px 0;" v-if="item.images.length>0">
+                <van-image @click="openImg(item.images,index2)" v-for="(e,index2) in item.images" :key="index2" style="border-radius: 3px;margin-right: 10px;" width="100" height="100" :src="e.url"/>
+              </div>
+            </template>
+            <template v-if="item.append_name">
+              <div class="blue" style="margin: 10px 0;font-size: 0.28rem;" @click="downWgt(item.append,item.append_name)">{{item.append_name}}</div>
+            </template>
+          </div>
+        </div>
+
+      </div>
+      <div style="height: 1rem;"></div>
+    </div>
+    <!-- </scroller> -->
+    <van-popup v-model="isWt" :close-on-click-overlay="false" class="popup-all">
+      <div style="position: relative;">
+        <div class="tsAll">
+          <!-- <van-icon name="close" class="close" @click="closeWt()" /> -->
+          <article v-if="knowFrom == 'action'">
+            <div>
+              <icon style="width: .32rem;height: .32rem;" name="lamp"></icon>
+              <span style="font-size:.32rem;padding-left:.1rem;color:black;">执行计划用来做什么</span>
+            </div>
+            <span>1、可以填写如何达成指标的计划,并记录进展行动</span>
+            <br />
+            <span>2、填写的内容将给评分人作为参考</span>
+          </article>
+          <article v-else-if="knowFrom == 'admnin'">
+            <div>
+              <icon style="width: .32rem;height: .32rem;" name="lamp"></icon>
+              <span style="font-size:.32rem;padding-left:.1rem;color:black;">跟踪管理记录用来做什么</span>
+            </div>
+            <span>1、填写工作执行过程的实际情况、表现好坏及奖惩情况</span>
+            <br />
+            <span>2、填写管理指导的过程记录</span>
+            <br />
+            <span>3、填写的内容可以给评分人作为参考</span>
+          </article>
+        </div>
+        <div class="footer2 flex-box-ce"><div class="flex-1" @click="closeWt()">我知道了</div></div>
+      </div>
+    </van-popup>
+    <van-action-sheet v-model="detailsshow" :closeable="false" duration=".35">
+      <div class="vassheet">
+        <div class="vasHead">
+          <van-icon name="arrow-down" size=".3rem" @click.stop="detailsshow = false" />
+          <span>所属指标</span>
+        </div>
+        <div class="pullUpdel">
+          <div style="padding:.05rem 0 .15rem 0;font-size:.32rem;">{{ apDetails.name }}</div>
+          <div class="intro" style="font-size:.26rem;">
+            <span class="introcol">考核标准:</span>
+            <br />
+            <span class="line-feed" v-html="apDetails.per_remark"></span>
+            <br />
+            <span class="introcol intropad">权重(%):{{ apDetails.weight }}%</span>
+            <br />
+            <span class="introcol intropad">目标值:{{ apDetails.target }}{{ apDetails.unit }}</span>
+          </div>
+        </div>
+      </div>
+    </van-action-sheet>
+  </div>
+</template>
+<script>
+import Vue from 'vue';
+import { ActionSheet,ImagePreview } from 'vant';
+import Uploader from '@/components/OssUploader';
+Vue.use(ActionSheet).use(ImagePreview);
+export default {
+  components:{ Uploader},
+  data() {
+    return {
+      detailsshow: false,
+      apdList: [],
+      detailsTIt: '',
+      apDetails: {},
+      apList: [],
+
+      knowFrom: '',
+      packId: 0, // 记录id
+      assessID: 0, // 记录人
+      planIndex: [], // 维度下标,指标下标
+      isShowAdd: false, // 是否显示添加按钮
+
+      isWt: false,
+      titValue: '', // 执行计划名
+      messageVal: '', // 备注
+      bootBool: false ,// 防止多次请求
+      has_finish:0,
+
+      // 上传图标与附件
+      img_fileList: [], // 图片附件
+      images: [],
+      accept:'image/jpeg,image/png,image/jpg',
+    };
+  },
+  watch:{
+    img_fileList(val){
+      if(val.length>0){
+        let images=[];
+        val.forEach(item=>{
+          let name=item.split('/');
+          let obj={
+            name:name[name.length-1],
+            url:item,
+          }
+          images.push(obj)
+        })
+        this.images=images;
+      }else{
+        this.images=[];
+      }
+    }
+  },
+  methods: {
+    downWgt (url,name) {
+      let self = this
+      if(!window.plus){
+          window.open(url, '_blank');
+          return false
+      }
+      plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
+        function (d, status) {
+          if (status == 200) {
+            plus.runtime.openFile(d.filename,{},(err)=>{
+              console.log(JSON.stringify(err))
+            });
+          } else {
+            self.$toast.clear()
+            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
+          }
+        }
+      ).start()
+    },
+    // 返回布尔值
+    beforeRead(file) {
+      const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+      // const isLt2M = file.size / 1024 / 1024 < 2;
+      if (!isJPG) {
+        this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+      }
+      // if (!isLt2M) {
+      //   this.$toast('上传图片大小不能超过 2MB!');
+      // }
+      return isJPG;
+    },
+    openImg(imgs,index){
+      let imgArr=imgs.map(item=>{
+        return item.url
+      })
+      ImagePreview({
+        images:imgArr,
+        startPosition:index,
+      });
+    },
+    openUrl(url){
+      window.open(url)
+    },
+    // 返回时刷新列表数据
+    routeBack() {
+      let query = this.$getCache('actionplanList');
+      if(query){
+        let data = {
+          know: this.knowFrom,
+          apList: this.apList,
+          packId: this.packId,
+          assessID: this.assessID,
+          recordMemberIds: query.recordMemberIds ? query.recordMemberIds : []
+        };
+        this.$setCache('actionplanList', data);
+      }
+    },
+    save() {
+      // 保存
+      if (this.knowFrom == 'action') {
+        // 执行计划
+        this.saveAction('/api/pro/per/package/action');
+      } else if (this.knowFrom == 'admnin') {
+        // 管理记录
+        this.saveAction('/api/pro/per/package/track');
+      }
+    },
+    saveAction(urls) {
+      if (this.bootBool) {
+        return;
+      }
+      // 执行计划
+      if (!this.titValue && this.titValue == '') {
+        this.$toast.fail('请输入标题');
+        return;
+      }
+      let data = {
+        package_employee_id: this.packId,
+        index_id: this.apDetails.id,
+        title: this.titValue,
+        remark: this.messageVal,
+        dimension_xb: this.planIndex[0],
+        images: JSON.stringify(this.images),
+        append: '', //附件
+        appendName: '' //附件名称
+      };
+      this.bootBool = true;
+      this.$axiosUser('post', urls, data)
+        .then(res => {
+          if (res.data.code == 1) {
+            this.$toast.success('提交成功');
+            this.titValue = '';
+            this.messageVal = '';
+            this.img_fileList=[];
+            this.$nextTick(() => {
+              this.employeeDet();
+            });
+          }
+        })
+        .finally(() => {
+          setTimeout(() => {
+            this.bootBool = false;
+          }, 3000);
+        });
+    },
+    closeWt() {
+      localStorage.setItem('isWt', true);
+      this.isWt = false;
+    },
+    addThePlan(item) {
+      if(!this.isShowAdd||this.has_finish){
+        return false
+      }
+      let data = {
+        know: this.knowFrom,
+        keys: JSON.stringify(item) || null,
+        apList: JSON.stringify(this.apDetails),
+        packId: this.packId,
+        assessID: this.assessID,
+        planIndex: this.planIndex[0] //维度下标
+      };
+      this.$setCache('addthePlan', data);
+      // 添加
+      this.$router.push({ name: 'addthePlan' });
+    },
+    employeeDet() {
+	  if(!this.packId){
+		  return false
+	  }
+      let params = {
+        id: this.packId
+      };
+      this.$axiosUser('get', '/api/pro/per/package/employee/info', params)
+        .then(res => {
+          if (res.data.code == 1) {
+            let data = res.data.data;
+            this.has_finish=data.has_finish;
+            let dimension = data.dimension[this.planIndex[0]].index[this.planIndex[1]];
+            this.apList = JSON.stringify(data.dimension);
+            if (this.knowFrom == 'action') {
+              // 执行计划
+              if (dimension.schedule) {
+                this.apdList = dimension.schedule;
+              }
+            } else if (this.knowFrom == 'admnin') {
+              // 管理记录
+              if (dimension.mamage_record) {
+                this.apdList = dimension.mamage_record;
+              }
+            }
+          }
+        })
+        .finally(() => {
+          this.routeBack();
+        });
+    },
+    //获取指定人员上级列表
+    getSuperiors(employee_id){
+      return this.$axiosUser('get', 'api/pro/employee/superior', {employee_id:employee_id,platform:'3'}).then(res=>{
+        return res.data.data.list
+      })
+    },
+    async init() {
+      let query = this.$getCache('actionplanDetails');
+      this.knowFrom = query.know;
+      this.packId = query.packId; // 记录id
+      this.assessID = query.assessID; // 记录人id
+      let apList = JSON.parse(query.apList);
+      this.planIndex = apList.planIndex;
+      this.apDetails = apList;
+      if (this.knowFrom == 'action') {
+        if (this.assessID == this.$userInfo().id) {
+          this.isShowAdd = true;
+        }
+        // 执行计划
+        this.detailsTIt = '执行计划';
+      } else if (this.knowFrom == 'admnin') {
+        this.isShowAdd = apList.isOperation; //管理记录人判断
+        let superior_list=await this.getSuperiors(this.assessID);
+        superior_list.some(item => {
+          // 判断被考核人的上级是否包含登录者
+          if (item.id == this.$userInfo().id) {
+            this.isShowAdd = true;
+            return true;
+          }
+        });
+
+        if (this.$userInfo().is_per_manager) {
+          // 如果是绩效管理员也可以操作
+          this.isShowAdd = true;
+        }
+        if (this.$getPermis(3)) {
+          // 如果是子管理员并且管理范围权限为“全公司”
+          this.isShowAdd = true;
+        }
+
+        // 管理记录
+        this.detailsTIt = '管理记录';
+      }
+      this.$nextTick(() => {
+        this.employeeDet();
+      });
+    }
+  },
+  mounted() {
+    this.isWt = localStorage.getItem('isWt') ? false : true;
+  },
+  activated() {
+    this.$nextTick(() => {
+      this.init();
+	  this.employeeDet();
+    });
+  }
+};
+</script>
+
+<style scoped lang="less">
+.popup-all {
+  border-radius: 0.15rem;
+  background: #fff;
+  width: 80%;
+  font-size: 0.32rem;
+}
+.footer2 div {
+  color: #000;
+  padding: 0.24rem 0;
+  padding-right: 0.32rem;
+  text-align: right;
+  font-size: 0.28rem;
+}
+.tsAll {
+  border-radius: 0.15rem;
+  position: relative;
+  margin: 0.2rem;
+  background-color: #fff;
+  padding: 0.2rem;
+  margin-top: 0rem;
+  div {
+    font-size: 0.32rem;
+    margin: 0.1rem 0 0.15rem 0;
+  }
+  span {
+    font-size: 0.26rem;
+    color: #a0a0a0;
+  }
+}
+.close {
+  position: absolute;
+  padding: 0.1rem;
+  right: 0.2rem;
+  top: 0.2rem;
+  color: #f56c6c;
+}
+
+header {
+  background-color: #fff;
+  padding: 0.25rem;
+  .intro {
+    span {
+      display: inline-block;
+      padding: 0.05rem 0;
+    }
+  }
+}
+.apdList {
+  background-color: #fff;
+}
+.apdData{
+  width: 88%;
+  padding: .1rem 0;
+  margin: 0 0.3rem 0 .2rem;
+  border-bottom: 1px solid rgb(240, 240, 240);
+}
+.apdDian{
+  position: relative;
+  width: .25rem;
+  height: .25rem;
+  border-radius: 50%;
+  background-color: #d4d4d4;
+}
+.apdHeadBoeder{
+  position: absolute;
+  left: 0.11rem;
+  height: 100%;
+  width: 0.02rem;
+  border-left: 0.02rem solid #d4d4d4;
+}
+.apdborderNO{
+  border: 0 !important;
+}
+.apdListMarTop{
+  margin: 0.15rem 0 0 0;
+}
+
+.vassheet {
+  background-color: rgb(245, 245, 245);
+  .vasHead {
+    background-color: #fff;
+    text-align: center;
+    padding: 0.2rem;
+    i {
+      left: 0.3rem;
+      top: 0.32rem;
+      position: absolute;
+    }
+    span {
+      font-size: 0.32rem;
+    }
+  }
+
+  .pullUpdel {
+    margin: 0.15rem 0 6rem 0;
+    padding: 0.25rem;
+    background-color: #ffffff;
+    .intro {
+      span {
+        display: inline-block;
+        padding: 0.05rem 0;
+      }
+      .introcol {
+        color: rgb(171, 171, 171);
+      }
+      .intropad {
+        padding: 0.1rem 0;
+      }
+    }
+  }
+}
+.all {
+  height: calc(100% - 0.92rem) !important;
+  background-color: #f5f7fa;
+  overflow-y: scroll;
+}
+/deep/ .van-field__control{
+  height: 72px !important;
+}
+/deep/ .van-field__label {
+  display: none;
+}
+/deep/ .van-field {
+  display: block;
+}
+</style>

+ 173 - 0
src/performance-07-19/components/actionplan/actionplanList.vue

@@ -0,0 +1,173 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar :title="'填写' + Tit" left-text="" left-arrow @click-left="routerBak" />
+    <header class="performanceList">
+      <div>请选择记录"{{ Tit }}"的考核指标</div>
+    </header>
+    <scroller ref="work_bench_scroller" class="all">
+      <div style="padding-bottom:1.5rem;">
+        <van-empty description="暂无绩效考核数据" v-if="backlogList.length == 0" />
+        <div v-else v-for="(item, index) in backlogList" :key="index">
+          <template v-if="item.index.length > 0">
+            <div class="backlog_list_tit">{{ item.name }}</div>
+            <div v-for="(arr, keys) in item.index" :key="keys" class="backlog_list">
+              <van-cell :title="arr.name + '(' + arr.weight + '%)'" @click="openPlanPath(arr)" is-link class="apListt">
+                <template>
+                  <span class="num" v-if="returnNum(arr) > 0">{{ returnNum(arr) }}</span>
+                </template>
+              </van-cell>
+            </div>
+          </template>
+        </div>
+      </div>
+    </scroller>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      Tit: '',
+      knowFrom: '',
+      backlogList: [],
+      packId: 0, //记录id
+      assessID: 0, //记录人
+      recordMemberIds: []
+    };
+  },
+  methods: {
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+    returnNum(item) {
+      if (this.knowFrom == 'action') {
+        //执行计划
+        return item.schedule.length;
+      } else if (this.knowFrom == 'admnin') {
+        //管理记录
+        return item.mamage_record.length;
+      }
+    },
+    openPlanPath(apList) {
+      let data = {
+        know: this.knowFrom,
+        apList: JSON.stringify(apList),
+        packId: this.packId,
+        assessID: this.assessID
+      };
+      this.$setCache('actionplanDetails', data);
+      this.$router.push({ name: 'actionplanDetails' });
+    },
+    //获取指定人员上级列表
+    getSuperiors(employee_id){
+      return this.$axiosUser('get', 'api/pro/employee/superior', {employee_id:employee_id,platform:'3'}).then(res=>{
+        return res.data.data.list
+      })
+    },
+    async init() {
+      let query = this.$getCache('actionplanList');
+      this.knowFrom = query.know;
+      this.packId = query.packId; //记录id
+      this.assessID = query.assessID; //记录人
+      this.recordMemberIds = query.recordMemberIds ? query.recordMemberIds : []; //管理记录人ID
+      if (this.knowFrom == 'action') {
+        //执行计划
+        this.Tit = '执行计划';
+      } else if (this.knowFrom == 'admnin') {
+        //管理记录
+        this.Tit = '管理记录';
+      }
+      let apList = JSON.parse(query.apList);
+      apList.forEach((item, keys) => {
+        item.index.forEach((arr, index) => {
+          arr.planIndex = [keys, index]; //当打开执行计划时的下标
+          arr.isOperation = true;
+        });
+      });
+      // 当有管理记录人时过滤数据
+      let isFiltration = true; //是否需要过滤数据源
+      if (this.recordMemberIds.length > 0) {
+        let superior_list=await this.getSuperiors(this.assessID);
+        superior_list.some(item => {
+          // 判断被考核人的上级是否包含登录者
+          if (item.id == this.$userInfo().id) {
+            isFiltration = false;
+            return true;
+          }
+        });
+        if (this.$userInfo().is_per_manager) {
+          // 如果是绩效管理员也可以操作
+          isFiltration = true;
+        }
+        if (this.$getPermis(3)) {
+          // 如果是子管理员并且管理范围权限为“全公司”
+          isFiltration = false;
+        }
+        if (isFiltration) {
+          let actionPlanList = JSON.parse(JSON.stringify(apList));
+          actionPlanList.forEach((item, index) => {
+            item.index.forEach(item2 => {
+              item2.isOperation = false;
+              if (item2.record_ids.indexOf(this.$userInfo().id) >= 0) {
+                item2.isOperation = true;
+              }
+            });
+          });
+          this.backlogList = actionPlanList;
+        } else {
+          this.backlogList = apList;
+        }
+      } else {
+        this.backlogList = apList;
+      }
+    }
+  },
+  activated() {
+    this.init();
+  }
+};
+</script>
+
+<style scoped lang="less">
+.num {
+  color: #fff;
+  text-align: center;
+  border-radius: 25px;
+  padding: 0 5px;
+  width: 0.8rem;
+  background-color: #2686ff;
+}
+.all {
+  height: calc(100% - 1.74rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  padding: 0.2rem;
+  background-color: #fff;
+  padding-left: 0.3rem;
+  font-size: 0.26rem;
+  z-index: 1;
+}
+.backlog_list_tit {
+  background-color: #f5f7fa;
+  padding: 0.2rem 0 0.2rem 0.3rem;
+  font-size: 0.28rem;
+}
+.backlog_list {
+  border-bottom: red;
+  /deep/ .apListt {
+    border-bottom: 1px solid #f1f1f1;
+  }
+  /deep/ .apListt span {
+    font-size: 0.27rem;
+  }
+}
+
+/deep/ .van-cell__value {
+  width: 1rem;
+  flex: none;
+}
+</style>

+ 449 - 0
src/performance-07-19/components/actionplan/addthePlan.vue

@@ -0,0 +1,449 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar :title="detailsTIt" left-text="" left-arrow @click-left="routerBak">
+      <template #right>
+        <span v-if="arrlist && isShowAdd" @click="deleteList" style="color:#fff;">删除</span>
+      </template>
+    </van-nav-bar>
+    <div class="body_com">
+      <scroller>
+        <header v-if="knowFrom == 'action'" class="performanceList">
+          <div>
+            <icon style="width: .32rem;height: .32rem;" name="lamp"></icon>
+            <span style="font-size:.32rem;padding-left:.1rem;color:black;">执行计划用来做什么</span>
+          </div>
+          <span>1、可以填写如何达成指标的计划,并记录进展行动</span>
+          <br />
+          <span>2、填写的内容将给评分人作为参考</span>
+        </header>
+        <header v-else-if="knowFrom == 'admnin'" class="performanceList">
+          <div>
+            <icon style="width: .32rem;height: .32rem;" name="lamp"></icon>
+            <span style="font-size:.32rem;padding-left:.1rem;color:black;">跟踪管理记录用来做什么</span>
+          </div>
+          <span>1、填写工作执行过程的实际情况、表现好坏及奖惩情况</span>
+          <br />
+          <span>2、填写管理指导的过程记录</span>
+          <br />
+          <span>3、填写的内容可以给评分人作为参考</span>
+        </header>
+
+        <div class="plancenter"><van-cell :title="'所属指标:' + apDetails.name" @click="detailsshow = true" is-link /></div>
+        <div class="planText">
+          <van-cell-group>
+            <van-field :label="detailsTIt" v-model="titValue" rows="3" type="textarea" autosize maxlength="200" :placeholder="'请输入' + detailsTIt" show-word-limit />
+            <van-field label="备注" v-model="messageVal" rows="3" type="textarea" autosize maxlength="500" placeholder="选填,请输入备注" show-word-limit />
+            <van-cell><Uploader v-model="img_fileList"  :max-count="3" :beforeRead="beforeRead" :accept="accept"/></van-cell>
+            <van-cell>
+              <template v-if="appendObj.append">
+                <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                <div class="blue" style="padding-top: 5px;font-size: 0.28rem;"  @click="downWgt(appendObj.append,appendObj.append_name)">{{appendObj.append_name}}</div>
+              </template>
+            </van-cell>
+          </van-cell-group>
+        </div>
+        <footer v-if="isShowAdd"><button @click="save">保存</button></footer>
+      </scroller>
+    </div>
+    <van-action-sheet v-model="detailsshow" :closeable="false" duration=".35">
+      <div class="vassheet">
+        <div class="vasHead">
+          <van-icon name="arrow-down" size=".3rem" @click.stop="detailsshow = false" />
+          <span>所属指标</span>
+        </div>
+        <div class="pullUpdel">
+          <div style="padding:.05rem 0 .15rem 0;font-size:.32rem;">{{ apDetails.name }}</div>
+          <div class="intro" style="font-size:.26rem;">
+            <span class="introcol">考核标准:</span>
+            <br />
+            <span v-html="apDetails.per_remark"></span>
+            <br />
+            <span class="introcol intropad">权重(%):{{ apDetails.weight }}%</span>
+            <br />
+            <span class="introcol intropad">目标值:{{ apDetails.target }}{{ apDetails.unit }}</span>
+          </div>
+        </div>
+      </div>
+    </van-action-sheet>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { NoticeBar, ActionSheet } from 'vant';
+import Uploader from '@/components/OssUploader';
+Vue.use(NoticeBar).use(ActionSheet);
+export default {
+  components: {Uploader},
+  data() {
+    return {
+      apDetails: {
+        name: '技术部量化指标1_(50%)',
+        standard: '完成50万,100分<br/>技术部量化标准1',
+        weight: 50,
+        target: '100 万'
+      },
+      detailsshow: false,
+      titValue: '', // 执行计划名
+      messageVal: '', // 备注
+
+      knowFrom: '',
+      detailsTIt: '',
+      packId: 0, // 记录ID
+      keyszb: {},
+      arrlist: false,
+      bootBool: false, // 防止多次请求
+      isShowAdd: false, // 是否可操作
+      assessID: 0,
+      planIndex: [],
+      // 上传图标与附件
+      img_fileList: [], // 图片附件
+      images: [],
+      accept:'image/jpeg,image/png,image/jpg',
+      appendObj:{
+        append:'',
+        append_name:''
+      }
+    };
+  },
+  watch:{
+    img_fileList(val){
+      if(val.length>0){
+        let images=[];
+        val.forEach(item=>{
+          let name=item.split('/');
+          let obj={
+            name:name[name.length-1],
+            url:item,
+          }
+          images.push(obj)
+        })
+        this.images=images;
+      }else{
+        this.images=[];
+      }
+    }
+  },
+  methods: {
+    downWgt (url,name) {
+      let self = this
+      if(!window.plus){
+          window.open(url, '_blank');
+          return false
+      }
+      plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
+        function (d, status) {
+          if (status == 200) {
+            plus.runtime.openFile(d.filename,{},(err)=>{
+              // console.log(JSON.stringify(err))
+            });
+          } else {
+            self.$toast.clear()
+            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
+          }
+        }
+      ).start()
+    },
+    // 返回布尔值
+    beforeRead(file) {
+      if(Array.isArray(file)){
+        let isJPG=true;
+        // let isLt2M=true;
+        file.some(item=>{
+           isJPG = /^image\/(jpeg|png|jpg)$/.test(item.type);
+           // isLt2M = item.size / 1024 / 1024 < 2;
+           if (!isJPG) {
+             this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+             return true
+           }
+           // if (!isLt2M) {
+           //   this.$toast('单张图片大小不能超过 2MB!');
+           //   return true
+           // }
+        })
+        return isJPG;
+      }else{
+        const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+        // const isLt2M = file.size / 1024 / 1024 < 2;
+        if (!isJPG) {
+          this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+        }
+        // if (!isLt2M) {
+        //   this.$toast('单张图片大小不能超过 2MB!');
+        // }
+        return isJPG;
+      }
+    },
+    openUrl(url){
+      window.open(url)
+    },
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+    deleteList() {
+      this.$dialog
+        .confirm({
+          title: this.knowFrom == 'action' ? '删除计划' : '删除记录',
+          messageVal: '确认删除' + this.detailsTIt + ' :' + this.titValue + ''
+        })
+        .then(res => {
+          if (this.knowFrom == 'action') {
+            // 执行计划
+            this.deLists('/api/pro/per/package/action/del', 'action');
+          } else if (this.knowFrom == 'admnin') {
+            // 管理记录
+            this.deLists('/api/pro/per/package/track/del', 'admnin');
+          }
+        })
+        .catch(() => {});
+    },
+    deLists(urls, name) {
+      let data = {
+        package_employee_id: this.packId,
+        index_id: this.apDetails.id,
+        dimension_xb: this.planIndex
+      };
+      if (name == 'action') {
+        data.action_id = this.keyszb.id;
+      } else if (name == 'admnin') {
+        if (this.keyszb.employee_id != this.$userInfo().id) {
+          this.$toast('不能删除其他管理者的管理记录!');
+          return false;
+        }
+        data.track_id = this.keyszb.id;
+      }
+      this.$axiosUser('post', urls, data).then(res => {
+        if (res.data.code == 1) {
+          this.$toast.success('删除成功');
+          this.routerBak();
+        }
+      });
+    },
+    save() {
+      // 保存
+      if (this.knowFrom == 'action') {
+        // 执行计划
+        this.saveAction('/api/pro/per/package/action');
+      } else if (this.knowFrom == 'admnin') {
+        // 管理记录
+        this.saveAction('/api/pro/per/package/track');
+      }
+    },
+    saveAction(urls) {
+      if (this.bootBool) {
+        return;
+      }
+      // 执行计划
+      if (!this.titValue && this.titValue == '') {
+        this.$toast.fail('请输入标题');
+        return;
+      }
+      let data = {
+        package_employee_id: this.packId,
+        index_id: this.apDetails.id,
+        title: this.titValue,
+        remark: this.messageVal,
+        dimension_xb: this.planIndex,
+        images: JSON.stringify(this.images),
+        // append: '', //附件
+        // appendName: '' //附件名称
+      };
+      data = Object.assign(data,this.appendObj);
+      if (this.arrlist) {
+        if (this.knowFrom == 'admnin') {
+          if (this.keyszb.employee_id != this.$userInfo().id) {
+            this.$toast('不能编辑其他管理者的管理记录!');
+            return false;
+          }
+          data.track_id = this.keyszb.id;
+        } else {
+          data.action_id = this.keyszb.id;
+        }
+      }
+      this.bootBool = true;
+      this.$axiosUser('post', urls, data)
+        .then(res => {
+          if (res.data.code == 1) {
+            this.$toast.success('提交成功');
+            this.routerBak();
+          }
+        })
+        .finally(() => {
+          setTimeout(() => {
+            this.bootBool = false;
+          }, 3000);
+        });
+    },
+    //获取指定人员上级列表
+    getSuperiors(employee_id){
+      return this.$axiosUser('get', 'api/pro/employee/superior', {employee_id:employee_id,platform:'3'}).then(res=>{
+        return res.data.data.list
+      })
+    },
+    async init() {
+      let rout = this.$getCache('addthePlan');
+      this.planIndex = rout.planIndex;
+      this.assessID = rout.assessID; // 记录人id
+      this.keyszb = JSON.parse(rout.keys);
+
+      if (this.keyszb) {
+        this.arrlist = true;
+        this.titValue = this.keyszb.title;
+        this.messageVal = this.keyszb.remark;
+        this.appendObj={
+          append:this.keyszb.append,
+          append_name:this.keyszb.append_name,
+        }
+        let images=this.keyszb.images;
+        let img_fileList=[];
+        if(images.length>0){
+          images.forEach(item=>{
+            img_fileList.push(item.url);
+          })
+        }
+        this.img_fileList=img_fileList;
+      } else {
+        this.arrlist = false;
+      }
+      this.knowFrom = rout.know;
+      let apList = JSON.parse(rout.apList);
+      this.apDetails = apList;
+      this.packId = rout.packId;
+      if (this.knowFrom == 'action') {
+        if (this.assessID == this.$userInfo().id) {
+          this.isShowAdd = true;
+        }
+        // 执行计划
+        this.detailsTIt = '执行计划';
+      } else if (this.knowFrom == 'admnin') {
+        this.isShowAdd = apList.isOperation; //管理记录人判断
+        let superior_list=await this.getSuperiors(this.assessID);
+        superior_list.some(item => {
+          // 判断被考核人的上级是否包含登录者
+          if (item.id == this.$userInfo().id) {
+            this.isShowAdd = true;
+            return true;
+          }
+        });
+        if (this.$getPermis(3)) {
+          // 如果是子管理员并且管理范围权限为“全公司”
+          this.isShowAdd = true;
+        }
+        // 管理记录
+        this.detailsTIt = '管理记录';
+      }
+    }
+  },
+  activated() {
+    this.$nextTick(() => {
+      this.init();
+    });
+  }
+};
+</script>
+
+<style scoped lang="less">
+.body_com {
+  height: calc(100% - 0.92rem);
+  position: relative;
+}
+header {
+  border-radius: 0.15rem;
+  position: relative;
+  margin: 0.2rem;
+  background-color: #fff;
+  padding: 0.2rem;
+  div {
+    font-size: 0.32rem;
+    margin: 0.1rem 0 0.15rem 0;
+  }
+  span {
+    font-size: 0.26rem;
+    color: #a0a0a0;
+  }
+}
+.plancenter {
+  margin: 0.2rem 0;
+  background-color: #fff;
+  .van-cell__title {
+    span {
+      color: #2d2d2d;
+      width: 6.45rem;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      -webkit-line-clamp: 1;
+      -webkit-box-orient: vertical;
+    }
+  }
+}
+footer {
+  // position: fixed;
+  // left: 0px;
+  // bottom: 0px;
+  width: 100%;
+  // background-color: #ffffff;
+  // z-index: 999;
+  margin-top: 0.1rem;
+  text-align: center;
+  button {
+    border-radius: 0.1rem;
+    width: 6.7rem;
+    height: 0.9rem;
+    border: 0;
+    font-size: 0.33rem;
+    color: #fff;
+    background-color: #4498ef;
+    text-align: center;
+    margin: 0.2rem;
+    line-height: 0.9rem;
+  }
+}
+.van-popup--bottom.van-popup--round {
+  background-color: rgb(245, 245, 245);
+}
+.vassheet {
+  background-color: rgb(245, 245, 245);
+  .vasHead {
+    background-color: #fff;
+    text-align: center;
+    padding: 0.2rem;
+    i {
+      left: 0.3rem;
+      top: 0.32rem;
+      position: absolute;
+    }
+    span {
+      font-size: 0.32rem;
+    }
+  }
+
+  .pullUpdel {
+    margin: 0.15rem 0 6rem 0;
+    padding: 0.25rem;
+    background-color: #ffffff;
+    .intro {
+      span {
+        display: inline-block;
+        padding: 0.05rem 0;
+      }
+      .introcol {
+        color: rgb(171, 171, 171);
+      }
+      .intropad {
+        padding: 0.1rem 0;
+      }
+    }
+  }
+}
+/deep/ .van-field__label {
+  display: none;
+}
+/deep/ .van-field {
+  display: block;
+}
+/deep/ .van-field__control{
+  height: 72px !important;
+}
+</style>

+ 552 - 0
src/performance-07-19/components/actionplan/resultValueEntry.vue

@@ -0,0 +1,552 @@
+<template>
+  <div :class="[{ bg_fff: skeletonLoad }]" style="width: 100%; height: 100%; ">
+    <van-nav-bar title="结果值数据录入" left-text="" left-arrow @click-left="routerBak" />
+
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <div style="width: 100%; height: calc(100% - 0.92rem); display: flex; flex-direction: column;">
+        <header v-if="$route.query.resultStr=='录入结果值'">
+          <van-tabs v-model="active" swipeable>
+            <van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'" :key="index"></van-tab>
+          </van-tabs>
+        </header>
+
+        <div class="batch-operate" style="width: 100%; font-size: 0.28rem;  color: rgb(146, 146, 146);  display: flex; align-items: center; padding: 0.24rem; box-sizing: border-box;background-color: #fff;">
+          <van-checkbox v-model="isAllChecked" shape="square" icon-size="18px" @change="toggleAllCheck" style="margin-right: 0.24rem;"></van-checkbox>
+          <button class="footcolButno" @click="openBatchOperation(1)" style="width: 2rem; height: 0.5rem; margin-right: 0.24rem;" :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">结果值</button>
+          <button class="footcolButno" @click="openBatchOperation(2)" style="width: 2rem; height: 0.5rem; margin-right: 0.24rem;" :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">图片</button>
+        </div>
+
+      <scroller :isNeed="isNeed" ref="work_bench_scroller" class="all">
+        <div style="padding-bottom:2.65rem;" v-if="rvenotList.length > 0">
+          <div v-for="(item, index) in rvenotList" :key="index" style="margin:.2rem 0;padding:0.24rem;background-color:#fff;">
+            <div style="display:flex; border-bottom: 1px dashed #f3f3f3;padding-bottom: .25rem;">
+              <div style="width: 100%; display:flex; align-items: center;">
+                <van-checkbox v-model="item.isChecked" shape="square" style="margin-right: 0.24rem;" icon-size="18px" @change="updateAllCheckStatus"></van-checkbox>
+                <userImage class="about-me__avatar" :id="item.userId" :user_name="item.userName" fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
+                <span style="font-size:.3rem;padding: 0.09rem 0px 0px 0.18rem;">{{ item.userName }}</span>
+              </div>
+              <div style="width: 100%; display:flex; align-items: center;">
+                <span class="font-flex-word" style="width: 100%; display:inline-block;color:#a7a7a7;">
+                  <span v-for="(depts, keys) in item.dept_list" :key="keys" style="font-size:.25rem;padding: 0.14rem 0px 0px 0.15rem;display: inline-block;">
+                    {{ depts.dept_name }}
+                    <span v-if="item.dept_list.length - keys > 1">,</span>
+                  </span>
+                </span>
+              </div>
+
+            </div>
+            <div>
+              <div style="font-size:.32rem;margin: 0.2rem 0;">{{ item.name }}</div>
+              <div  class="flex-box" style="margin-bottom: 0.14rem;" v-for="(arr, att) in item.dil" :key="att" v-if="arr.prop">
+                <div style="color:#929292;font-size:.27rem;width: 1.6rem;">{{ arr.lab }}:</div>
+                <div class="flex-1" style="font-size:.28rem;">{{ arr.prop }}</div>
+              </div>
+              <!-- v-if="active == 0" -->
+              <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;">
+                <div class="flex-box-ce" v-if="item.type==1">
+                  <van-field v-model="item.result" placeholder="请输入结果值" />
+                  <div style="padding-right: 0.32rem;" class="fontColorC">{{item.unit}}</div>
+                </div>
+                <van-cell><Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept" /></van-cell>
+                <van-cell v-if="item.result_file.append.length > 0">
+                  <template>
+                    <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                    <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e, index2) in item.result_file.append" :key="index2"  @click="downWgt(e.url, e.name)">{{ e.name}}</div>
+                  </template>
+                </van-cell>
+              </div>
+
+            </div>
+          </div>
+        </div>
+        <van-empty description="暂无结果值录入" v-else />
+      </scroller>
+      <footer v-if="active == 0 && rvenotList.length > 0 && selectList && selectList.length > 0">
+        <van-row class="footfoot">
+          <van-col span="14" class="footcol" @click="save(1)">
+            <div style="width:1rem;margin: auto;" v-if="$route.query.resultStr=='录入结果值'">
+              <icon name="save" style="width: 0.5rem;height: 0.5rem;"></icon>
+              <div style="font-size: .24rem;color:#8a8a8a;">暂存</div>
+            </div>
+          </van-col>
+          <van-col span="10" class="footBut">
+            <button style="" class="footcolButno" @click="rveno">取消</button>
+            <button class="footcolButok" @click="save(0)">提交</button>
+          </van-col>
+        </van-row>
+      </footer>
+      <footer v-if="active == 1 && rvenotList.length > 0 && selectList && selectList.length > 0">
+        <van-row class="footfoot">
+          <van-col span="14" class="footcol">
+          </van-col>
+          <van-col span="10" class="footBut">
+            <button style="" class="footcolButno" @click="rveno">取消</button>
+            <button class="footcolButok" @click="save(3)">提交</button>
+          </van-col>
+        </van-row>
+      </footer>
+    </div>
+    </VanSkeleton>
+
+    <van-popup v-model:show="isBatchOperation" round>
+      <div style="width: 7rem; padding: 0.24rem; box-sizing: border-box;">
+        <div>
+        <div style="font-weight: 600; text-align: center;">
+          批量录入数据
+        </div>
+        <div style="color: #FF9600; padding: 0.24rem 0.32rem; box-sizing: border-box;">选择的数据将会录入同一结果值和图片</div>
+        <div class="flex-box-ce" v-if="showType == 1">
+          <van-field label="结果值" v-model="batch_result_cache" placeholder="请输入结果值" border/>
+        </div>
+
+        <div style="padding: 0.24rem 0.32rem; box-sizing: border-box;" v-if="showType == 2">
+          <div style="color: #646566; margin-bottom: 0.24rem;">请上传图片</div>
+          <Uploader v-model="batch_result_imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept"/>
+          </div>
+        </div>
+
+        <span slot="footer">
+          <div class="flex-box-end" style="margin-top: 12px;" >
+            <button class="footcolButno" @click="cancelBatchOperation()" style="height: 0.6rem;">取消</button>
+            <button class="footcolButok" @click="confirmBatchOperation()" style="height: 0.6rem;">确定</button>
+          </div>
+        </span>
+      </div>
+    </van-popup>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import Uploader from '@/components/OssUploader';
+import { Tab, Tabs, ImagePreview } from 'vant';
+Vue.use(Tab)
+  .use(Tabs)
+  .use(ImagePreview);
+export default {
+  data() {
+    return {
+      showType: 1,
+      isNeed:!this.$getCache('isAndroid'),
+      isAllChecked: false,
+      batch_result_cache: "",
+      batch_result_imgs: [],
+      isBatchOperation: false,
+      skeletonLoad: true, // 骨架屏
+      rvenotList: [],
+      minFormactive: [{ name: '未录入', age: 0 }, { name: '已录入', age: 0 }],
+      active: 0,
+      id: 0, // 考核记录ID
+      packageName: '', // 考核包名
+      noStatusList: [], // 未录入指标
+      statusList: [], // 已录入指标
+      bootBool: false, // 防止多次请求
+      isIos: this.$getCache('iPhone'),
+
+      // 上传图标与附件
+      img_fileList: [], // 图片附件
+      images: [],
+      accept: 'image/jpeg,image/png,image/jpg'
+    };
+  },
+  components: { VanSkeleton, Uploader },
+  watch: {
+    active(val) {
+      if (val == 0) {
+        this.rvenotList = this.noStatusList;
+      } else if (val == 1) {
+        this.rvenotList = this.statusList;
+      }
+      this.isAllChecked = false
+      this.rvenotList.forEach(item => item.isChecked = false)
+    }
+  },
+
+  computed: {
+    selectList() {
+      return this.rvenotList.filter(item => item.isChecked)
+    }
+  },
+
+  methods: {
+    toggleAllCheck() {
+      this.rvenotList.forEach(item => {
+        item.isChecked = this.isAllChecked;
+      });
+    },
+    updateAllCheckStatus() {
+      this.isAllChecked = this.rvenotList.every(item => item.isChecked);
+    },
+    cancelBatchOperation() {
+      this.isBatchOperation = false
+    },
+    confirmBatchOperation() {
+      if(this.batch_result_imgs && this.batch_result_imgs.length > 0) {
+        this.rvenotList.forEach(item => {
+          if(item.isChecked) {
+            item.result_file.imgs = this.batch_result_imgs
+          }
+        })
+      }
+      if(this.batch_result_cache !== '' && this.batch_result_cache !== null) {
+        this.rvenotList.forEach(item => {
+          if(item.isChecked) {
+            if(item.index_type == 1) item.result_cache = this.batch_result_cache
+          }
+        })
+      }
+      this.isBatchOperation = false
+    },
+    openBatchOperation(type) {
+      if(this.selectList && this.selectList.length > 0) {
+        this.showType = type
+        this.isBatchOperation = true
+      }
+    },
+    downWgt(url, name) {
+      let self = this;
+      if (!window.plus) {
+        window.open(url, '_blank');
+        return false;
+      }
+      plus.downloader
+        .createDownload(encodeURI(url), { filename: '_doc/update/' }, function(d, status) {
+          if (status == 200) {
+            plus.runtime.openFile(d.filename, {}, err => {
+              // console.log(JSON.stringify(err))
+            });
+          } else {
+            self.$toast.clear();
+            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 });
+          }
+        })
+        .start();
+    },
+    openImg(imgs, index) {
+      let imgArr = imgs.map(item => {
+        return item.url;
+      });
+      ImagePreview({
+        images: imgArr,
+        startPosition: index
+      });
+    },
+    // 返回布尔值
+    beforeRead(file) {
+      // console.log(file)
+      const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+      // const isLt2M = file.size / 1024 / 1024 < 2;
+      if (!isJPG) {
+        this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+      }
+      // if (!isLt2M) {
+      //   this.$toast('上传图片大小不能超过 2MB!');
+      // }
+      return isJPG;
+    },
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+    rveno() {
+      // 取消
+      this.$route_back();
+    },
+    // 提交
+    save(num) {
+      let data = {
+        id: this.id, // 个人考核包ID
+        cache: num==1? 1:0, // 是否暂存 1 是 0 否(提交)
+        result_info: '' ,// 结果值信息
+        sub: num==3? 0:1
+      };
+      let result_info = [];
+      let isPost=true;
+      let str='';
+      this.selectList.some(e => {
+        let images = [];
+        if (e.result_file.imgs) {
+          e.result_file.imgs.forEach(imgItem => {
+            let name = imgItem.split('/');
+            let obj = {
+              name: name[name.length - 1],
+              url: imgItem
+            };
+            images.push(obj);
+          });
+        }
+        e.result_file.images = images;
+        if(num==3){
+          if (e.type == 1) {
+              if(!e.result){
+                isPost=false;
+                str=e.name+': 请输入结果值'
+                return true
+              }
+              result_info.push({
+                result: e.result, //单项目结果值
+                dimension_key: e.message.dimension_key, //维度索引
+                index_key: e.message.index_key, //指标索引
+                index_id: e.id, //指标ID
+                result_file: e.result_file
+              });
+          } else {
+             if (e.result_file.append.length == 0 && e.result_file.images.length == 0) {
+                isPost=false;
+                str=e.name+': 至少添加一份附件'
+                return true
+             }
+              result_info.push({
+                // result: e.result, //单项目结果值
+                dimension_key: e.message.dimension_key, //维度索引
+                index_key: e.message.index_key, //指标索引
+                index_id: e.id, //指标ID
+                result_file: e.result_file
+              });
+          }
+        }else{
+          if (e.type == 1) {
+            if (e.result) {
+              result_info.push({
+                result: e.result, //单项目结果值
+                dimension_key: e.message.dimension_key, //维度索引
+                index_key: e.message.index_key, //指标索引
+                index_id: e.id, //指标ID
+                result_file: e.result_file
+              });
+            }
+          } else {
+            if (e.result_file.append.length > 0 || e.result_file.images.length > 0) {
+              result_info.push({
+                // result: e.result, //单项目结果值
+                dimension_key: e.message.dimension_key, //维度索引
+                index_key: e.message.index_key, //指标索引
+                index_id: e.id, //指标ID
+                result_file: e.result_file
+              });
+            }
+          }
+        }
+
+      });
+      if(num==3){
+        if(!isPost){
+          this.$toast(str);
+          return false;
+        }
+      }else{
+        if (result_info.length == 0) {
+          this.$toast.fail('至少输入一项结果值或非量化指标添加一份附件');
+          return false;
+        }
+      }
+
+      data.result_info = JSON.stringify(result_info);
+      if (this.bootBool) {
+        return;
+      }
+      if(num==0){
+        this.$dialog.confirm({
+          message:'请仔细检查结果值数据是否填写准确,以免数据错误造成不便!',
+          cancelButtonText:'返回检查',
+          confirmButtonText:'确认提交',
+        }).then(() => {
+             this.recordResult(data,num)
+        }).catch(() => {});
+      }else{
+        this.recordResult(data,num)
+      }
+    },
+    recordResult(data,num){
+      this.bootBool = true;
+      this.$axiosUser('post', '/api/pro/per/package/record_result', data).then(res => {
+          this.$toast.success(data.cache==1? '已暂存':'提交成功');
+          if(num==3){
+            setTimeout(() => {
+              this.routerBak();
+            }, 500);
+            return false
+          }
+         this.getPackageDtail();
+      }).finally(() => {
+        setTimeout(() => {
+          this.bootBool = false;
+        }, 3000);
+      });
+    },
+
+    getPackageDtail() {
+      this.$axiosUser('get', '/api/pro/per/package/employee/info', { id: this.id })
+        .then(res => {
+          let data = res.data.data;
+          let dimension = data.dimension;
+          let relevance_employee = data.relevance_employee;
+          dimension.forEach((item, index) => {
+            if (item.index.length > 0) {
+              item.index.forEach((item2, index2) => {
+                let target=item2.target? item2.target+' '+item2.unit:null;
+                item2.wdName = item.name;
+                item2.userName = relevance_employee.name;
+                item2.userId = relevance_employee.id;
+                item2.dept_list = relevance_employee.employee_detail.dept_list;
+                item2.isChecked = false;
+                item2.dil = [
+                  {lab: '考核标准',prop: item2.per_remark ? item2.per_remark : null},
+                  { lab: '权重%', prop: item2.weight ? item2.weight : null },
+                  { lab: '备注', prop: item2.remark ? item2.remark : null },
+                  { lab: '目标值', prop: target },
+                ];
+              });
+            }
+          });
+          let flow = data.flow;
+          let list = []; // 结果值录入集合
+          flow.forEach(item => {
+            if (item.code == 'result_value') {
+              item.target.forEach(item2 => {
+                if (item2.employee_id == this.$userInfo().id) {
+                  list = item2.list;
+                  status = item2.status;
+                }
+              });
+            }
+          });
+          let statusList = []; // 已录入指标
+          let noStatusList = []; // 未录入指标
+          list.forEach(item => {
+            let imgs = [];
+            if (item.result_file) {
+              item.result_file.images.forEach(img => {
+                imgs.push(img.url);
+              });
+              item.result_file.imgs = imgs;
+            }
+
+            if (item.status == 2) {
+              dimension[item.dimension_key].index[item.index_key].message = item;
+              let result_file=dimension[item.dimension_key].index[item.index_key].result_file;
+              result_file.imgs=result_file.images.map(img=>{
+                return img.url
+              })
+              statusList.push(dimension[item.dimension_key].index[item.index_key]);
+            }
+            if (item.status == 1) {
+              dimension[item.dimension_key].index[item.index_key].message = item;
+              if (item.result_cache) {
+                // 是否有暂存的数据有就显示出来
+                dimension[item.dimension_key].index[item.index_key].result = item.result_cache;
+              }
+              if (item.result_file) {
+                dimension[item.dimension_key].index[item.index_key].result_file = item.result_file;
+              }
+              noStatusList.push(dimension[item.dimension_key].index[item.index_key]);
+            }
+          });
+
+          // noStatusList.push(...statusList)
+          // this.rvenotList=noStatusList
+
+          this.statusList = statusList;
+          this.noStatusList = noStatusList;
+          if (this.active == 0) {
+            this.rvenotList = this.noStatusList;
+          } else if (this.active == 1) {
+            this.rvenotList = this.statusList;
+          }
+          this.minFormactive[0].age = noStatusList.length; // 未
+          this.minFormactive[1].age = statusList.length; // 已
+        })
+        .finally(() => {
+          this.skeletonLoad = false;
+        });
+    }
+  },
+  created() {
+    if (this.$route.query.resultStr == '调整结果值') {
+      this.active = 1;
+    }
+    if (this.$route.query.id) {
+      this.id = this.$route.query.id;
+      this.packageName = this.$route.query.packageName;
+      this.getPackageDtail();
+    }
+  },
+  mounted() {}
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  flex: 1;
+  position: relative ;
+  background-color: #f5f7fa;
+  padding-bottom: 0.3rem;
+  overflow-y: scroll;
+}
+header {
+  background-color: #fff;
+  font-size: 0.3rem;
+  z-index: 1;
+}
+.isIos {
+  height: calc(100% - 3.6rem) !important;
+}
+.batch-operate {
+  width: 100%;
+  font-size: 0.28rem;
+  color: rgb(146, 146, 146);
+  display: flex;
+  align-items: center;
+  padding: 0.24rem;
+  box-sizing: border-box;
+  background-color: #fff;
+}
+
+.footcolButno {
+  border: 1px solid #42a8ff;
+  width: 1.4rem;
+  height: 0.8rem;
+  font-size: 0.28rem;
+  color: #2f9eff;
+  background-color: #ffffff;
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.footcolButok {
+  border: 0;
+  width: 1.4rem;
+  height: 0.8rem;
+  font-size: 0.28rem;
+  color: #fff;
+  background-color: #42a8ff;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
+}
+footer {
+  // position: fixed;
+  // left: 0px;
+  // bottom: 0px;
+  // width: 100%;
+
+  background-color: #ffffff;
+  z-index: 999;
+  border-top: 1px solid #e2e2e2;
+  .footfoot {
+    padding: 0.1rem;
+    // padding-bottom: 0.4rem !important;
+    .footcol {
+      text-align: center;
+    }
+    .footBut {
+      display: flex;
+    }
+
+  }
+}
+
+.disabled {
+  color: #bbb;
+  border-color: #bbb;
+}
+</style>

+ 472 - 0
src/performance-07-19/components/actionplan/resultValueEntryAll.vue

@@ -0,0 +1,472 @@
+<template>
+  <div :class="[{ bg_fff: skeletonLoad }]">
+    <van-nav-bar title="结果值数据录入" left-text="" left-arrow @click-left="routerBak" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <div style="height: 1rem;background-color: #fff;font-size: 0.32rem;" class="flex-box-ce flex-center-center" @click="selectUser=true">
+        <span style="max-width: 4rem;" class="font-flex-word">{{userName}} </span>
+        <van-icon name="arrow-down"/>
+      </div>
+      <header>
+        <van-tabs v-model="active" swipeable><van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'" :key="index"></van-tab></van-tabs>
+      </header>
+      <scroller :isNeed="isNeed" ref="work_bench_scroller" class="all" :class="{ isIos: isIos }" :style="{height:active == 0? 'calc(100% - 4.2rem)':'calc(100% - 1rem)'}">
+        <div style="padding-bottom:2.65rem;" v-if="rvenotList.length > 0">
+          <div v-for="(item, index) in rvenotList" :key="index" style="margin:.2rem 0;padding:0.24rem;background-color:#fff;">
+            <div style="display:flex;border-bottom: 1px dashed #f3f3f3;padding-bottom: .25rem;">
+              <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
+              <span style="font-size:.3rem;padding: 0.09rem 0px 0px 0.18rem;">{{ item.employee_name }}</span>
+              <span class="font-flex-word" style="width: 4rem;display:inline-block;color:#a7a7a7;">
+                <span v-for="(depts, keys) in item.dept_list" :key="keys" style="font-size:.25rem;padding: 0.14rem 0px 0px 0.15rem;display: inline-block;">
+                  {{ depts.dept_name }}
+                  <span v-if="item.dept_list.length - keys > 1">,</span>
+                </span>
+              </span>
+            </div>
+            <div>
+              <div style="font-size:.32rem;margin: 0.2rem 0;">{{ item.index_name }}</div>
+              <div  class="flex-box" style="margin-bottom: 0.14rem;" v-for="(arr, att) in item.dil" :key="att" v-if="arr.prop">
+                <div style="color:#929292;font-size:.27rem;width: 1.4rem;">{{ arr.lab }}:</div>
+                <div class="flex-1" style="font-size:.28rem;">{{ arr.prop }}</div>
+              </div>
+              <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="active == 0">
+                <van-field v-model="item.result_cache" placeholder="请输入结果值" v-if="item.index_type==1" />
+                <van-cell><Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept"/></van-cell>
+                <van-cell v-if="item.result_file.append.length>0">
+                  <template >
+                    <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                    <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">{{e.name}}</div>
+                  </template>
+                </van-cell>
+              </div>
+              <span v-else>
+                <span style="color:#929292;font-size:.27rem;width: 1.4rem;display: inline-block;">结果值:</span>
+                <span style="font-size:.28rem;" class="orange" v-if="item.index_type==1">{{ item.result_cache }} {{ item.unit }}</span>
+                <template v-if="item.result_file.images">
+                  <div class="flex-box-ce" style="margin: 10px 0;" v-if="item.result_file.images.length>0">
+                    <van-image @click="openImg(item.result_file.images,index2)" v-for="(e,index2) in item.result_file.images" :key="index2" style="border-radius: 3px;margin-right: 10px;" width="100" height="100" :src="e.url"/>
+                  </div>
+                </template>
+                <template v-if="item.result_file.append.length>0">
+                  <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                  <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">{{e.name}}</div>
+                </template>
+              </span>
+            </div>
+          </div>
+        </div>
+        <van-empty description="暂无结果值录入" v-else />
+      </scroller>
+      <footer v-if="active == 0 && rvenotList.length > 0">
+        <van-row class="footfoot">
+          <van-col span="14" class="footcol" @click="save(1)">
+            <div style="width:1rem;margin: auto;">
+              <icon name="save" style="width: 0.5rem;height: 0.5rem;"></icon>
+              <div style="font-size: .24rem;color:#8a8a8a;">暂存</div>
+            </div>
+          </van-col>
+          <van-col span="10" class="footBut">
+            <button style="" class="footcolButno" @click="rveno">取消</button>
+            <button class="footcolButok" @click="save(0)">提交</button>
+          </van-col>
+        </van-row>
+      </footer>
+      <van-popup v-model:show="isResult" round >
+        <div style="width: 7rem;padding: 0.24rem;box-sizing: border-box;">
+          <div style="font-size: 0.28rem;margin-bottom: 0.24rem;">提交结果</div>
+          <van-progress :percentage="percentage" stroke-width="8" />
+          <div style="margin-top: 16px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+            <div class="flex-box-ce results" style="font-weight: 600;">
+              <div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
+              <div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
+              <div class="flex-2" style="border-right: 1px solid #f1f1f1;">指标名称</div>
+              <div class="flex-2">提交结果</div>
+            </div>
+            <div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+              <div style="border-right: 1px solid #f1f1f1;width: 40px;">{{ results.length - index }}</div>
+              <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.info.employee_name }}</div>
+              <div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.info.index_name }}</div>
+              <div class="flex-2 red" v-if="item.msg">{{item.msg}}</div>
+              <div class="flex-2 green" v-else>提交成功</div>
+            </div>
+          </div>
+          <span slot="footer">
+            <div class="flex-box-end" style="margin-top: 12px;" >
+              <van-button type="primary" @click="isResult = false" size="small">确 定</van-button>
+            </div>
+          </span>
+        </div>
+      </van-popup>
+    </VanSkeleton>
+    <!-- 人员选择 -->
+    <EmployeeSelector
+      title="选择人员"
+      :visible.sync="selectUser"
+      @confirm="confirmCreator"
+      :can_select_dept="false"
+      :selected.sync="selected_data"
+    ></EmployeeSelector>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import Uploader from '@/components/OssUploader';
+import { Tab, Tabs,ImagePreview,Popup,Progress,DropdownMenu, DropdownItem, Icon   } from 'vant';
+Vue.use(Tab).use(Tabs).use(ImagePreview).use(Popup).use(Progress).use(DropdownMenu).use(DropdownItem).use(Icon);
+export default {
+  data() {
+    return {
+      isNeed:!this.$getCache('isAndroid'),
+      skeletonLoad: true, // 骨架屏
+      rvenotList: [],
+      minFormactive: [{ name: '未录入', age: 0 }, { name: '已录入', age: 0 }],
+      active: 0,
+      pe_ids: 0, // 个人考核记录集合
+      packageName: '', // 考核包名
+      noStatusList: [], // 未录入指标
+      statusList: [], // 已录入指标
+      bootBool: false, // 防止多次请求
+      isIos: this.$getCache('iPhone'),
+
+      // 上传图标与附件
+      img_fileList: [], // 图片附件
+      images: [],
+      accept:'image/jpeg,image/png,image/jpg',
+
+      // 长连接结果
+      results: [], //提交的返回结果集合
+      isResult: false,
+      percentage: 0,
+      resultList: [], //要发送数据的集合
+      resultIndex: 0,
+
+      userName:'全部人员',
+      selectUser:false,
+      employee_list: [],
+      selected_data: { dept: [], employee: [] } //传入已选部门
+    };
+  },
+  components: {VanSkeleton,Uploader,EmployeeSelector },
+  watch: {
+    isResult(val) {
+      if (!val) {
+        this.results = []; //提交的返回结果集合
+        this.isResult = false;
+        this.percentage = 0;
+        this.resultList = []; //要发送数据的集合
+        this.resultIndex = 0;
+        this.getPackageDtail();
+      }
+    },
+    active(val) {
+      if (val == 0) {
+        this.rvenotList = this.noStatusList;
+      } else if (val == 1) {
+        this.rvenotList = this.statusList;
+      }
+    },
+  },
+  methods: {
+    confirmCreator(data) {
+      let userName = '';
+      this.userName="全部人员"
+      this.employee_list=[];
+      if (data.employee !== null && data.employee.length != 0) {
+        data.employee.forEach(item=>{
+          this.employee_list.push(item.id);
+          userName+=(item.name+',')
+        })
+        this.userName = userName;
+      }
+      this.selected_data = data;
+      this.selectUser = false;
+      this.getPackageDtail();
+    },
+    downWgt (url,name) {
+      let self = this
+      if(!window.plus){
+          window.open(url, '_blank');
+          return false
+      }
+      plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
+        function (d, status) {
+          if (status == 200) {
+            plus.runtime.openFile(d.filename,{},(err)=>{
+              // console.log(JSON.stringify(err))
+            });
+          } else {
+            self.$toast.clear()
+            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
+          }
+        }
+      ).start()
+    },
+    openImg(imgs,index){
+      let imgArr=imgs.map(item=>{
+        return item.url
+      })
+      ImagePreview({
+        images:imgArr,
+        startPosition:index,
+      });
+    },
+    // 返回布尔值
+    beforeRead(file) {
+      const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+      // const isLt2M = file.size / 1024 / 1024 < 2;
+      if (!isJPG) {
+        this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+      }
+      // if (!isLt2M) {
+      //   this.$toast('上传图片大小不能超过 2MB!');
+      // }
+      return isJPG;
+    },
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+    rveno() {
+      // 取消
+      this.$route_back();
+    },
+    // 提交
+    save(num) {
+      let isLr = false;
+      let parameterArr = [];
+      // let data = {
+      //   id: this.id, // 个人考核包ID
+      //   cache: num, // 是否暂存 1 是 0 否(提交)
+      //   result_info: '' // 结果值信息
+      // };
+
+      this.noStatusList.some(item => {
+        let images=[];//图片
+        let result_info = [];
+        if( item.result_file.imgs){
+          item.result_file.imgs.forEach(imgItem=>{
+            let name=imgItem.split('/');
+            let obj={
+              name:name[name.length-1],
+              url:imgItem,
+            }
+            images.push(obj)
+          })
+        }
+        item.result_file.images=images;
+        result_info.push({
+          dimension_key: item.dimension_id, //维度索引
+          index_key: item.index_key, //指标索引
+          index_id: item.index_id, //指标ID
+          result_file: item.result_file
+        });
+
+        if(item.index_type == 1){
+          result_info[0].result=item.result_cache
+        }
+        let data = {
+          id: item.pe_id, //个人考核包ID
+          cache: num, //是否暂存 1 是 0 否(提交)
+          info: item,
+          result_info: JSON.stringify(result_info),
+          sub: num==3? 0:1
+        };
+        if (item.index_type == 1 && item.result_cache!==null && item.result_cache!=='') {
+          parameterArr.push(data);
+        }
+        if (item.index_type != 1 && (item.result_file.append.length > 0 || item.result_file.images.length > 0)) {
+          parameterArr.push(data);
+        }
+      });
+      if (parameterArr.length==0) {
+        this.$toast.fail('至少输入一项结果值或非量化指标添加一份附件');
+        return false;
+      }
+      this.webSocket(parameterArr);
+      return;
+
+
+      if (this.bootBool) {
+        return;
+      }
+      this.bootBool = true;
+      this.$axiosUser('post', '/api/pro/per/package/record_result', data)
+        .then(res => {
+          this.$toast.success('设置成功');
+          this.getPackageDtail();
+        })
+        .finally(() => {
+          setTimeout(() => {
+            this.bootBool = false;
+          }, 3000);
+        });
+    },
+    webSocket(data) {
+      this.resultList = data;
+      this.resultIndex = 0;
+      this.percentage = 0;
+      this.results = [];
+      this.isResult = true;
+      this.opneWebSocket();
+    },
+    opneWebSocket() {
+      let wsData = this.resultList;
+      if (wsData[this.resultIndex]) {
+        this.$axiosUser('post', '/api/pro/per/package/record_result', wsData[this.resultIndex]).then(res => {
+          this.onmessageWS(wsData[this.resultIndex],true);
+        }).catch(e=>{
+          let data=wsData[this.resultIndex];
+          data.msg=e.data.msg;
+          this.onmessageWS(data,false);
+          // console.log(e)
+        });
+
+      }
+    },
+    onmessageWS(data,isJx) {
+      this.results.unshift(data);
+      this.resultIndex++;
+      if(!isJx){
+        return false
+      }
+      this.opneWebSocket();
+      // 进度条
+      let lng = this.resultList.length;
+      this.percentage += Math.floor(100 / lng);
+      if (lng == this.results.length) {
+        this.percentage = 100;
+      }
+    },
+    getPackageDtail() {
+      this.$axiosUser('get', '/api/pro/per/package/result_job_list', { pe_ids: this.pe_ids, page: 1, page_size: 2000,employee_ids:JSON.stringify(this.employee_list) }).then(res => {
+          let list = res.data.data.list;
+
+          let statusList = []; // 已录入指标
+          let noStatusList = []; // 未录入指标
+          list.forEach(item => {
+            let imgs=[];
+            if(item.result_file){
+              item.result_file.images.forEach(img => {
+                imgs.push(img.url);
+              })
+              item.result_file.imgs=imgs;
+            }
+            item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
+            item.dil = [
+              { lab: '考核标准', prop: item.index_standard ? item.index_standard : null},
+              { lab: '权重%', prop: item.index_weight ? item.index_weight : null },
+              { lab: '备注', prop: item.index_remark ? item.index_remark : null },
+              { lab: '目标值', prop: item.target ? item.target : null },
+            ];
+            if (item.index_result_status == 1) {
+              noStatusList.push(item);
+            }
+            if (item.index_result_status == 2) {
+              statusList.push(item);
+            }
+          });
+          this.statusList = statusList;
+          this.noStatusList = noStatusList;
+
+          if (this.active == 0) {
+            this.rvenotList = this.noStatusList;
+          } else if (this.active == 1) {
+            this.rvenotList = this.statusList;
+          }
+          this.minFormactive[0].age = noStatusList.length; // 未
+          this.minFormactive[1].age = statusList.length; // 已
+        })
+        .finally(() => {
+          this.skeletonLoad = false;
+        });
+    }
+  },
+  created() {
+    if (this.$route.query.pe_ids) {
+      this.pe_ids = this.$route.query.pe_ids;
+      this.packageName = this.$route.query.name;
+      this.getPackageDtail();
+    }
+  },
+  mounted() {}
+};
+</script>
+
+<style scoped lang="less">
+.userName{
+  position: absolute;
+  left: 0%;
+  height: 50px;
+  width: 100%;
+  opacity: 0;
+}
+.results {
+  border-bottom: 1px solid #f1f1f1;
+  text-align: center;
+  font-size: 0.24rem;
+}
+.results div {
+  padding: 10px;
+}
+.line-feed {
+    white-space: pre-wrap;
+}
+.all {
+  height: calc(100% - 3.2rem);
+  position: relative !important;
+  background-color: #f5f7fa;
+  padding-bottom: 0.3rem;
+  overflow-y: scroll;
+}
+header {
+  background-color: #fff;
+  font-size: 0.3rem;
+  z-index: 1;
+}
+.isIos {
+  height: calc(100% - 3.6rem);
+}
+
+footer {
+  // position: fixed;
+  // left: 0px;
+  // bottom: 0px;
+  // width: 100%;
+
+  background-color: #ffffff;
+  z-index: 999;
+  border-top: 1px solid #e2e2e2;
+  .footfoot {
+    padding: 0.1rem;
+    // padding-bottom: 0.4rem !important;
+    .footcol {
+      text-align: center;
+    }
+    .footBut {
+      display: flex;
+    }
+    .footcolButno {
+      border: 1px solid #42a8ff;
+      width: 1.4rem;
+      height: 0.8rem;
+      font-size: 0.28rem;
+      color: #2f9eff;
+      background-color: #ffffff;
+      border-top-left-radius: 3px;
+      border-bottom-left-radius: 3px;
+    }
+    .footcolButok {
+      border: 0;
+      width: 1.4rem;
+      height: 0.8rem;
+      font-size: 0.28rem;
+      color: #fff;
+      background-color: #42a8ff;
+      border-top-right-radius: 3px;
+      border-bottom-right-radius: 3px;
+    }
+  }
+}
+</style>

+ 1175 - 0
src/performance-07-19/components/actionplan/resultValueEntryMb.vue

@@ -0,0 +1,1175 @@
+<template>
+  <div style="height:calc(100% - 1.92rem);">
+    <div style="width:100%; height: 100%;">
+      <header>
+        <van-tabs v-model="active" swipeable>
+          <van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'"
+            :key="index"></van-tab>
+        </van-tabs>
+      </header>
+
+      <div class="batch-operate">
+        <van-checkbox v-model="isAllChecked" shape="square" icon-size="18px" @change="toggleAllCheck"
+          style="margin: 0 0.24rem;"></van-checkbox>
+        <button class="footcolButno" @click="openBatchOperation(1)"
+          style="width: 2rem; height: 0.5rem; font-size: 0.28rem; margin-right: 0.24rem;"
+          :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">结果值</button>
+        <button class="footcolButno" @click="openBatchOperation(2)"
+          style="width: 2rem; height: 0.5rem;  font-size: 0.28rem; margin-right: 0.24rem;"
+          :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">图片</button>
+        <!-- <div style="color: #FF9600;">支持批量录入结果值和图片</div> -->
+        <span @click.stop="openText2()"><van-icon name="question" class="fontColorC" /></span>
+      </div>
+
+      <div style="width:100%; height:calc(100% - 1.8rem);display: flex; flex-direction: column;">
+        <scroller :isNeed="isNeed" ref="work_bench_scroller" class="all">
+          <div style="padding-bottom:2.65rem;" v-if="rvenotList.length > 0">
+            <div v-for="(item, index) in rvenotList" :key="index"
+              style="margin:.2rem 0;padding:0.24rem;background-color:#fff;">
+              <div class="flex-box-ce" style="border-bottom: 1px dashed #f3f3f3; padding-bottom: .25rem;">
+                <van-checkbox v-model="item.isChecked" shape="square" style="margin-right: 0.24rem;" icon-size="18px"
+                  @change="updateAllCheckStatus"></van-checkbox>
+                <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name"
+                  fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
+                <div style="font-size:.3rem; padding: 0rem 0px 0px 0.18rem; box-sizing: border-box;">
+                  {{ item.employee_name }}
+                </div>
+                <div class="font-flex-word fontColorC flex-1" style="padding-right: 0.2rem;">
+                  <span v-for="(depts, keys) in item.dept_list" :key="keys"
+                    style="font-size:.25rem;padding: 0rem 0px 0px 0.15rem;display: inline-block;">
+                    {{ depts.dept_name }}
+                    <span v-if="item.dept_list.length - keys > 1">,</span>
+                  </span>
+                </div>
+                <template v-if="active == 1">
+                  <div style="font-size:.3rem" class="fontColorC" v-if="!item.isUpdate" @click="openText(item)">
+                    <van-icon name="info-o" />不可调整
+                  </div>
+                </template>
+              </div>
+              <div>
+                <div style="font-size:.32rem;margin: 0.2rem 0;">{{ item.index_name }}</div>
+                <div class="flex-box" style="margin-bottom: 0.14rem;" v-for="(arr, att) in item.dil" :key="att"
+                  v-if="arr.prop">
+                  <div style="color:#929292;font-size:.27rem; width: 1.6rem;">{{ arr.lab }}:</div>
+                  <div class="flex-1" style="font-size:.28rem;">{{ arr.prop }}</div>
+                </div>
+
+                <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="active == 0">
+                  <div class="flex-box-ce"
+                    style="justify-content: space-between; padding: 0 0.32rem 0 0; box-sizing: border-box;"
+                    v-if="item.index_type==1">
+                    <van-field v-model="item.result_cache" placeholder="请输入结果值" style="width: 5rem;" />
+                    <div class="fontColorC">{{item.unit}}</div>
+                  </div>
+                  <van-cell>
+                    <Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead"
+                      :accept="accept" />
+                  </van-cell>
+                  <van-cell v-if="item.result_file.append.length>0">
+                    <template>
+                      <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                      <div class="blue" style="padding-top: 5px;font-size: 0.28rem;"
+                        v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">
+                        {{e.name}}
+                      </div>
+                    </template>
+                  </van-cell>
+                </div>
+                <template v-else>
+                  <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="item.isUpdate">
+                    <div class="flex-box-ce"
+                      style="justify-content: space-between; padding: 0 0.32rem 0 0; box-sizing: border-box;"
+                      v-if="item.index_type==1">
+                      <van-field v-model="item.result_cache" placeholder="请输入结果值" style="width: 5rem;" />
+                      <div class="fontColorC">{{item.unit}}</div>
+                    </div>
+                    <van-cell>
+                      <Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead"
+                        :accept="accept" />
+                    </van-cell>
+                    <van-cell v-if="item.result_file.append.length>0">
+                      <template>
+                        <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                        <div class="blue" style="padding-top: 5px;font-size: 0.28rem;"
+                          v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">
+                          {{e.name}}
+                        </div>
+                      </template>
+                    </van-cell>
+                  </div>
+                  <div v-else>
+                    <span style="color:#929292;font-size:.27rem;width: 1.4rem;display: inline-block;">结果值:</span>
+                    <span style="font-size:.28rem;position: relative;left: -4px;" class="orange"
+                      v-if="item.index_type==1">{{ item.result_cache }} {{ item.unit }}</span>
+                    <template v-if="item.result_file.images">
+                      <div class="flex-box-ce" style="margin: 10px 0;" v-if="item.result_file.images.length>0">
+                        <van-image @click="openImg(item.result_file.images,index2)"
+                          v-for="(e,index2) in item.result_file.images" :key="index2"
+                          style="border-radius: 3px;margin-right: 10px;" width="100" height="100" :src="e.url" />
+                      </div>
+                    </template>
+                    <template v-if="item.result_file.append.length>0">
+                      <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                      <div class="blue" style="padding-top: 5px;font-size: 0.28rem;"
+                        v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">
+                        {{e.name}}
+                      </div>
+                    </template>
+                  </div>
+                </template>
+              </div>
+
+            </div>
+          </div>
+          <van-empty description="暂无结果值录入" v-else />
+        </scroller>
+        <footer v-if="active == 0 && rvenotList.length > 0 && selectList && selectList.length > 0" v-isKeyboard>
+          <van-row class="footfoot">
+            <van-col span="14" class="footcol" @click="save(1)">
+              <div style="width:1rem;margin: auto;">
+                <icon name="save" style="width: 0.5rem;height: 0.5rem;"></icon>
+                <div style="font-size: .24rem;color:#8a8a8a;">暂存</div>
+              </div>
+            </van-col>
+            <van-col span="10" class="footBut">
+              <button class="footcolButno" @click="rveno">取消</button>
+              <button class="footcolButok" @click="save(0)">提交</button>
+            </van-col>
+          </van-row>
+        </footer>
+        <footer v-if="active == 1 && rvenotList.length > 0 && returnIsShow && selectList && selectList.length > 0"
+          v-isKeyboard>
+          <van-row class="footfoot">
+            <van-col span="14" class="footcol"></van-col>
+            <van-col span="10" class="footBut">
+              <button class="footcolButno" @click="rveno">取消</button>
+              <button class="footcolButok" @click="save(3)">提交</button>
+            </van-col>
+          </van-row>
+        </footer>
+      </div>
+
+    </div>
+
+
+    <van-popup v-model="isFilterShow" position="bottom" :style="popStyle">
+      <div class="popup-title">
+        {{ title }}
+      </div>
+      <div class="filter-options-box">
+        <scroller style="height: 5rem; border-top: 0.01rem solid #f5f7fa;">
+          <div class="dropdown-item-title" style="margin-top: 10px;">选择人员</div>
+          <div class="dropdown-item-content-list">
+            <div class="dropdown-item-content" v-for="(item, index) in user_list" :key="index"
+              @click="chooseOptions(item, 'user_name')" :class="selectOptions.includes(item) ? 'active' : ''">
+              {{ item }}
+            </div>
+          </div>
+          <div class="dropdown-item-title">指标名称</div>
+          <div class="dropdown-item-content-list">
+            <div class="dropdown-item-content" v-for="(item, index) in index_name_list" :key="index"
+              @click="chooseOptions(item, 'index_name')" :class="selectOptions.includes(item) ? 'active' : ''">
+              {{ item }}
+            </div>
+          </div>
+          <div class="dropdown-item-title">考核标准</div>
+          <div class="dropdown-item-content-list">
+            <div class="dropdown-item-content" v-for="(item, index) in index_standard_list" :key="index"
+              style="flex: 0 0 100%; margin-right: 0;" @click="chooseOptions(item, 'index_standard')"
+              :class="selectOptions.includes(item) ? 'active' : ''" s>
+              {{ item }}
+            </div>
+          </div>
+
+          <div class="dropdown-item-title">目标值</div>
+          <div class="dropdown-item-content-list">
+            <template v-if="target_list && target_list.length > 0">
+              <div class="dropdown-item-content" v-for="(item, index) in target_list" :key="index"
+                @click="chooseOptions(item, 'target')" :class="select_target_list.includes(item) ? 'active' : ''">
+                {{ item }}
+              </div>
+            </template>
+          </div>
+
+          <div class="dropdown-item-title">权重%</div>
+          <div class="dropdown-item-content-list">
+            <template v-if="index_weight_list && index_weight_list.length > 0">
+              <div class="dropdown-item-content" v-for="(item, index) in index_weight_list" :key="index"
+                @click="chooseOptions(item, 'weight')" :class="select_index_weight_list.includes(item) ? 'active' : ''">
+                {{ item }}
+              </div>
+            </template>
+          </div>
+
+          <div style="height: 1.2rem;"></div>
+
+        </scroller>
+        <div class="btn-container">
+          <button class="footcolButno" style="width: 96%; height: 0.8rem;" @click="clearFilters()">重置</button>
+        </div>
+      </div>
+    </van-popup>
+
+    <van-popup v-model:show="isResult" round>
+      <div style="width: 7rem;padding: 0.24rem;box-sizing: border-box;">
+        <div style="font-size: 0.28rem;margin-bottom: 0.24rem;">提交结果</div>
+        <van-progress :percentage="percentage" stroke-width="8" />
+        <div style="margin-top: 16px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+          <div class="flex-box-ce results" style="font-weight: 600;">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
+            <div class="flex-2" style="border-right: 1px solid #f1f1f1;">指标名称</div>
+            <div class="flex-2">提交结果</div>
+          </div>
+          <div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">{{ results.length - index }}</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.info.employee_name }}</div>
+            <div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.info.index_name }}</div>
+            <div class="flex-2 red" v-if="item.msg">{{item.msg}}</div>
+            <div class="flex-2 green" v-else>提交成功</div>
+          </div>
+        </div>
+        <span slot="footer">
+          <div class="flex-box-end" style="margin-top: 12px;">
+            <van-button type="primary" @click="closeIsResult" size="small">确 定</van-button>
+          </div>
+        </span>
+      </div>
+    </van-popup>
+
+    <van-popup v-model:show="isBatchOperation" round>
+      <div style="width: 7rem; padding: 0.24rem; box-sizing: border-box;">
+        <div>
+          <div style="font-weight: 600; text-align: center;">
+            批量录入数据
+          </div>
+          <div style="color: #FF9600; padding: 0.24rem 0.32rem; box-sizing: border-box;">选择的数据将会录入同一结果值和图片</div>
+          <div class="flex-box-ce" v-if="showType == 1">
+            <van-field label="结果值" v-model="batch_result_cache" placeholder="请输入结果值" border />
+            <!-- <div style="padding-right: 0.32rem;" class="fontColorC">{{item.unit}}</div> -->
+          </div>
+
+          <div style="padding: 0.24rem 0.32rem; box-sizing: border-box;" v-if="showType == 2">
+            <div style="color: #646566; margin-bottom: 0.24rem;">请上传图片</div>
+            <Uploader v-model="batch_result_imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept" />
+          </div>
+        </div>
+
+        <span slot="footer">
+          <div class="flex-box-end" style="margin-top: 12px;">
+            <button class="footcolButno" @click="cancelBatchOperation()" style="height: 0.6rem;">取消</button>
+            <button class="footcolButok" @click="confirmBatchOperation()" style="height: 0.6rem;">确定</button>
+          </div>
+        </span>
+      </div>
+    </van-popup>
+
+  </div>
+</template>
+
+<script>
+  import Vue from 'vue';
+  import VanSkeleton from '@/performance/components/public/VanSkeleton';
+  import EmployeeSelector from '@/components/EmployeeSelector';
+  import Uploader from '@/components/OssUploader';
+  import DeptSelectorDropdown from '@/components/DeptSelectorDropdown'
+  import {
+    Tab,
+    Tabs,
+    ImagePreview,
+    Popup,
+    Progress,
+    DropdownMenu,
+    DropdownItem,
+    Icon
+  } from 'vant';
+  Vue.use(Tab).use(Tabs).use(ImagePreview).use(Popup).use(Progress).use(DropdownMenu).use(DropdownItem).use(Icon);
+  export default {
+    props: {
+      peIds: {
+        type: String,
+        default: ''
+      },
+      isUpdate: {
+        type: Boolean,
+        default: false
+      },
+    },
+    data() {
+      return {
+        popStyle: {
+          width: '100%',
+          height: '9rem',
+          padding: '10px',
+          boxSizing: 'border-box',
+          borderRadius: '10px',
+          position: 'relation'
+        },
+        showType: 1,
+        isFilterShow: false,
+        title: '未录入',
+        isAllChecked: false,
+        batch_result_cache: "",
+        batch_result_imgs: [],
+        isBatchOperation: false,
+        isNeed: !this.$getCache('isAndroid'),
+        skeletonLoad: true, // 骨架屏
+        rvenotList: [],
+        minFormactive: [{
+          name: '未录入',
+          age: 0
+        }, {
+          name: '已录入',
+          age: 0
+        }],
+        active: 0,
+        noStatusListAll: [],
+        noStatusListDx: [],
+        noStatusList: [], // 未录入指标
+        statusList: [], // 已录入指标
+        bootBool: false, // 防止多次请求
+        isIos: this.$getCache('iPhone'),
+        user_list: [],
+        index_name_list: [],
+        index_standard_list: [],
+        target_list: [],
+        index_weight_list: [],
+        select_user_name_list: [],
+        select_index_name_list: [], // 筛选指标名称列表
+        select_index_standard_list: [], // 筛选指标标准列表
+        select_target_list: [], // 筛选指标名称列表
+        select_index_weight_list: [], // 筛选指标名称列表
+        // 上传图标与附件
+        img_fileList: [], // 图片附件
+        images: [],
+        accept: 'image/jpeg,image/png,image/jpg',
+
+        // 长连接结果
+        results: [], //提交的返回结果集合
+        isResult: false,
+        percentage: 0,
+        resultList: [], //要发送数据的集合
+        resultIndex: 0,
+
+        userName: '全部人员',
+        selectUser: false,
+        employee_list: [],
+        selected_data: {
+          dept: [],
+          employee: []
+        }, //传入已选部门
+        paiXu: false,
+        selectOptions: []
+      };
+    },
+    components: {
+      VanSkeleton,
+      Uploader,
+      EmployeeSelector
+    },
+    computed: {
+      returnIsShow() {
+        let is = false
+        this.statusList.forEach(item => {
+          if (item.isUpdate) {
+            is = true;
+          }
+        })
+        return is
+      },
+      selectList() {
+        return this.rvenotList.filter(item => item.isChecked)
+      }
+    },
+    watch: {
+
+      paiXu(val) {
+        if (val) {
+          this.rvenotList = JSON.parse(JSON.stringify(this.noStatusListDx));
+        } else {
+          this.rvenotList = JSON.parse(JSON.stringify(this.noStatusList));
+        }
+      },
+      isResult(val) {
+        if (!val) {
+          this.results = []; //提交的返回结果集合
+          this.isResult = false;
+          this.percentage = 0;
+          this.resultList = []; //要发送数据的集合
+          this.resultIndex = 0;
+          this.getPackageDtail();
+        }
+      },
+      active(val) {
+        if (val == 0) this.title = '未录入'
+        else this.title = '已录入'
+        this.clearFilters();
+        this.initFilterData();
+      },
+      selectOptions(val) {
+        if (this.active == 0) this.rvenotList = this.filterFn(this.noStatusList);
+        else this.rvenotList = this.filterFn(this.statusList);
+      },
+      peIds() {
+        this.getPackageDtail();
+      }
+    },
+
+    methods: {
+      openFilterBox(type) {
+        if (type == 1) this.active = 0
+        else this.active = 1
+        this.isFilterShow = true;
+      },
+      clearFilters() {
+        this.selectOptions = [];
+        this.select_user_name_list = [];
+        this.select_index_name_list = [];
+        this.select_index_standard_list = [];
+        this.select_target_list = [];
+        this.select_index_weight_list = [];
+        if (this.active == 0) this.rvenotList = this.noStatusList;
+        else this.rvenotList = this.statusList;
+      },
+
+
+
+      filterFn(data) {
+
+        let result = [];
+        let flag0 = 0
+        let flag1 = 0
+        let flag2 = 0
+        let flag3 = 0
+        let flag4 = 0
+        // 筛选条件对象
+        let filterCriteria = {
+          // employee_name: [],
+          // index_name: [],
+          // index_standard: [],
+          // target: [],
+          // index_weight: []
+        };
+
+
+        // 按照用户名称过滤数据
+        if (this.select_user_name_list && this.select_user_name_list.length > 0) {
+          flag0 = true;
+          filterCriteria.employee_name = this.select_user_name_list
+        }
+
+        // 按照指标名称过滤数据
+        if (this.select_index_name_list && this.select_index_name_list.length > 0) {
+          flag1 = true;
+          filterCriteria.index_name = this.select_index_name_list
+        }
+
+        // 按照指标标准过滤数据
+        if (this.select_index_standard_list && this.select_index_standard_list.length > 0) {
+          flag2 = true;
+          filterCriteria.index_standard = this.select_index_standard_list
+        }
+
+        // 按照目标值过滤数据
+        if (this.select_target_list && this.select_target_list.length > 0) {
+          flag3 = true;
+          filterCriteria.target = this.select_target_list
+        }
+
+        // 按照权重过滤数据
+        if (this.select_index_weight_list && this.select_index_weight_list.length > 0) {
+          flag4 = true;
+          filterCriteria.index_weight = this.select_index_weight_list
+        }
+
+
+        if(!flag0 && !flag1 && !flag2 && !flag3 && !flag4) result = data
+
+
+        // 根据条件对象筛选数组
+        result = data.filter(user => {
+          return Object.keys(filterCriteria).every(key => {
+            if (Array.isArray(filterCriteria[key])) {
+              // 如果条件值是数组,则检查属性值是否包含在数组中
+              return filterCriteria[key] && filterCriteria[key].includes(user[key]);
+            }
+          });
+        });
+        return result
+
+      },
+
+
+      chooseOptions(item, type) {
+        // 所有的过滤条件
+        if (!this.selectOptions.includes(item)) this.selectOptions.push(item);
+        else {
+          let select_option_index = 0
+          this.selectOptions.forEach((select, index) => {
+            if (select == item) {
+              select_option_index = index
+            }
+          })
+          this.selectOptions.splice(select_option_index, 1)
+        }
+
+        // 用户名称
+        if (type == 'user_name') {
+          if (!this.select_user_name_list.includes(item)) this.select_user_name_list.push(item);
+          else {
+            let select_index = 0
+            this.select_user_name_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_user_name_list.splice(select_index, 1)
+          }
+        }
+
+        // 指标名称
+        if (type == 'index_name') {
+          if (!this.select_index_name_list.includes(item)) this.select_index_name_list.push(item);
+          else {
+            let select_index = 0
+            this.select_index_name_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_index_name_list.splice(select_index, 1)
+          }
+        }
+
+        // 考核标准
+        if (type == 'index_standard') {
+          if (!this.select_index_standard_list.includes(item)) this.select_index_standard_list.push(item);
+          else {
+            let select_index = 0
+            this.select_index_standard_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_index_standard_list.splice(select_index, 1)
+          }
+        }
+
+        // 目标值
+        if (type == 'target') {
+          if (!this.select_target_list.includes(item)) this.select_target_list.push(item);
+          else {
+            let select_index = 0
+            this.select_target_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_target_list.splice(select_index, 1)
+          }
+        }
+
+        // 权重
+        if (type == 'weight') {
+          if (!this.select_index_weight_list.includes(item)) this.select_index_weight_list.push(item);
+          else {
+            let select_index = 0
+            this.select_index_weight_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_index_weight_list.splice(select_index, 1)
+          }
+        }
+
+      },
+      toggleAllCheck() {
+        this.rvenotList.forEach(item => {
+          item.isChecked = this.isAllChecked;
+        });
+      },
+      updateAllCheckStatus() {
+        this.isAllChecked = this.rvenotList.every(item => item.isChecked);
+      },
+      cancelBatchOperation() {
+        this.isBatchOperation = false
+      },
+      confirmBatchOperation() {
+        if (this.batch_result_imgs && this.batch_result_imgs.length > 0) {
+          this.rvenotList.forEach(item => {
+            if (item.isChecked) {
+              item.result_file.imgs = this.batch_result_imgs
+            }
+          })
+        }
+        if (this.batch_result_cache !== '' && this.batch_result_cache !== null) {
+          this.rvenotList.forEach(item => {
+            if (item.isChecked) {
+              if (item.index_type == 1) item.result_cache = this.batch_result_cache
+            }
+          })
+        }
+        this.isBatchOperation = false
+      },
+      openBatchOperation(type) {
+        if (this.selectList && this.selectList.length > 0) {
+          this.showType = type
+          this.isBatchOperation = true
+        }
+      },
+
+      closeIsResult() {
+        this.isResult = false;
+        this.batch_result_cache = "";
+        this.batch_result_imgs = [];
+        this.selectOptions = [];
+        this.select_user_name_list = [];
+        this.select_index_name_list = [];
+        this.select_index_standard_list = [];
+        this.select_target_list = [];
+        this.select_index_weight_list = [];
+      },
+
+      openText2(index) {
+        this.$dialog.alert({
+          message: '支持多条件筛选,批量录入结果值及图片',
+        }).then(() => {});
+      },
+      openText(item) {
+        let message = `${item.employee_name}的考核指标已评分,不可调整结果值;如需调整,请联系绩效管理员`;
+        this.$dialog.alert({
+          message: message,
+        }).then(() => {});
+      },
+      confirmCreator(data) {
+        let userName = '';
+        this.userName = "全部人员"
+        this.employee_list = [];
+        if (data.employee !== null && data.employee.length != 0) {
+          data.employee.forEach(item => {
+            this.employee_list.push(item.id);
+            userName += (item.name + ',')
+          })
+          this.userName = userName;
+        }
+        this.selected_data = data;
+        this.selectUser = false;
+        this.getPackageDtail();
+      },
+      downWgt(url, name) {
+        let self = this
+        if (!window.plus) {
+          window.open(url, '_blank');
+          return false
+        }
+        plus.downloader.createDownload(encodeURI(url), {
+            filename: '_doc/update/'
+          },
+          function(d, status) {
+            if (status == 200) {
+              plus.runtime.openFile(d.filename, {}, (err) => {
+                // console.log(JSON.stringify(err))
+              });
+            } else {
+              self.$toast.clear()
+              Notify({
+                type: 'danger',
+                message: '下载失败,请稍后重试',
+                duration: 1000
+              })
+            }
+          }
+        ).start()
+      },
+      openImg(imgs, index) {
+        let imgArr = imgs.map(item => {
+          return item.url
+        })
+        ImagePreview({
+          images: imgArr,
+          startPosition: index,
+        });
+      },
+      // 返回布尔值
+      beforeRead(file) {
+        const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+        // const isLt2M = file.size / 1024 / 1024 < 2;
+        if (!isJPG) {
+          this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+        }
+        // if (!isLt2M) {
+        //   this.$toast('上传图片大小不能超过 2MB!');
+        // }
+        return isJPG;
+      },
+      // 返回上一页
+      routerBak() {
+        this.$route_back();
+      },
+      rveno() {
+        // 取消
+        this.$route_back();
+      },
+      // 提交
+      save(num) {
+        let isLr = false;
+        let parameterArr = [];
+        let isPost = true;
+        let str = '';
+        this.selectList.some(item => {
+          let images = []; //图片
+          let result_info = [];
+          if (item.result_file.imgs) {
+            item.result_file.imgs.forEach(imgItem => {
+              let name = imgItem.split('/');
+              let obj = {
+                name: name[name.length - 1],
+                url: imgItem,
+              }
+              images.push(obj)
+            })
+          }
+          item.result_file.images = images;
+
+          result_info.push({
+            dimension_key: item.dimension_id, //维度索引
+            index_key: item.index_key, //指标索引
+            index_id: item.index_id, //指标ID
+            result_file: item.result_file
+          });
+          if (item.index_type == 1) {
+            result_info[0].result = item.result_cache
+          }
+          let data = {
+            id: item.pe_id, //个人考核包ID
+            cache: num == 1 ? 1 : 0, // 是否暂存 1 是 0 否(提交)
+            info: item,
+            result_info: JSON.stringify(result_info),
+            sub: num == 3 ? 0 : 1
+          };
+
+          if (num == 3) {
+            if (item.isUpdate) {
+              if (item.index_type == 1) {
+                if (!item.result_cache) {
+                  isPost = false;
+                  str = item.index_name + ': 请输入结果值'
+                  return true
+                }
+                parameterArr.push(data);
+              } else {
+                if (item.result_file.append.length == 0 && item.result_file.images.length == 0) {
+                  isPost = false;
+                  str = item.index_name + ': 至少添加一份附件'
+                  return true
+                }
+                parameterArr.push(data);
+              }
+            }
+          } else {
+            if (item.index_type == 1 && item.result_cache !== null && item.result_cache !== '') {
+              parameterArr.push(data);
+            }
+            if (item.index_type != 1 && (item.result_file.append.length > 0 || item.result_file.images.length >
+                0)) {
+              parameterArr.push(data);
+            }
+          }
+        });
+        if (num == 3) {
+          if (!isPost) {
+            this.$toast(str);
+            return false;
+          }
+        } else {
+          if (parameterArr.length == 0) {
+            this.$toast.fail('至少输入一项结果值或非量化指标添加一份附件');
+            return false;
+          }
+        }
+        this.webSocket(parameterArr);
+      },
+      webSocket(data) {
+        this.resultList = data;
+        this.resultIndex = 0;
+        this.percentage = 0;
+        this.results = [];
+        this.isResult = true;
+        this.opneWebSocket();
+      },
+      opneWebSocket() {
+        let wsData = this.resultList;
+        if (wsData[this.resultIndex]) {
+          this.$axiosUser('post', '/api/pro/per/package/record_result', wsData[this.resultIndex]).then(res => {
+            this.onmessageWS(wsData[this.resultIndex], true);
+          }).catch(e => {
+            let data = wsData[this.resultIndex];
+            data.msg = e.data.msg;
+            this.onmessageWS(data, false);
+          });
+
+        }
+      },
+      onmessageWS(data, isJx) {
+        this.results.unshift(data);
+        this.resultIndex++;
+        if (!isJx) {
+          return false
+        }
+        this.opneWebSocket();
+        // 进度条
+        let lng = this.resultList.length;
+        this.percentage += Math.floor(100 / lng);
+        if (lng == this.results.length) {
+          this.percentage = 100;
+        }
+      },
+      getPackageDtail() {
+        this.$axiosUser('get', '/api/pro/per/package/result_job_list', {
+            pe_ids: this.peIds,
+            page: 1,
+            page_size: 2000,
+            employee_ids: JSON.stringify(this.employee_list)
+          }).then(res => {
+            let list = res.data.data.list;
+            let pe_flows = res.data.data.pe_flows;
+            let statusList = []; // 已录入指标
+            let noStatusList = []; // 未录入指标
+
+            list.forEach(item => {
+              let imgs = [];
+              if (item.result_file) {
+                item.result_file.images.forEach(img => {
+                  imgs.push(img.url);
+                })
+                item.result_file.imgs = imgs;
+              }
+              item.isChecked = false;
+              item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
+              let target = item.target ? item.target + ' ' + item.unit : null;
+              item.dil = [{
+                  lab: '考核标准',
+                  prop: item.index_standard ? item.index_standard : null
+                },
+                {
+                  lab: '权重%',
+                  prop: item.index_weight ? item.index_weight : null
+                },
+                {
+                  lab: '备注',
+                  prop: item.index_remark ? item.index_remark : null
+                },
+                {
+                  lab: '目标值',
+                  prop: target
+                },
+              ];
+
+              if (item.index_result_status == 1) {
+                noStatusList.push(item);
+              }
+              if (item.index_result_status == 2) {
+                item.isUpdate = true;
+                pe_flows.forEach(e => {
+                  if (e.pe_id == item.pe_id) {
+                    item.isUpdate = this.returnIs(e.flow);
+                  }
+                })
+                statusList.push(item);
+              }
+            });
+
+
+            this.statusList = statusList;
+            this.noStatusList = noStatusList;
+
+            if (this.active == 0) {
+              this.rvenotList = JSON.parse(JSON.stringify(noStatusList));
+            } else if (this.active == 1) {
+              this.rvenotList = this.statusList;
+            }
+
+
+            let obj = {},
+              arr = [];
+            noStatusList.forEach(item => {
+              if (obj[item.index_name]) {
+                obj[item.index_name].push(item)
+              } else {
+                obj[item.index_name] = [item]
+              }
+            })
+            for (let key in obj) {
+              arr.push(obj[key]);
+            }
+            arr.sort(function(a, b) {
+              return b.length - a.length
+            });
+            let noStatusListDx = [];
+            arr.forEach(item => {
+              noStatusListDx.push(...item);
+            })
+
+            this.noStatusListDx = noStatusListDx
+            this.title1 = '未录入' + '(' + noStatusList.length + ')'
+            this.title2 = '已录入' + '(' + statusList.length + ')'
+            this.minFormactive[0].age = noStatusList.length; // 未
+            this.minFormactive[1].age = statusList.length; // 已
+            if (this.isUpdate) {
+              this.active = 1
+            }
+            this.initFilterData();
+          })
+          .finally(() => {
+            this.skeletonLoad = false;
+          });
+      },
+      uniqueArray(arr) {
+        return [...new Set(arr.map(item => JSON.stringify(item)))].map(item => JSON.parse(item));
+      },
+
+      initFilterData() {
+        if(this.rvenotList && this.rvenotList.length > 0) {
+          this.user_list = [];
+          this.index_name_list = [];
+          this.index_standard_list = [];
+          this.target_list = [];
+          this.index_weight_list = [];
+          this.rvenotList.forEach(item => {
+            this.user_list.push(item.employee_name);
+            this.index_name_list.push(item.index_name);
+            this.index_standard_list.push(item.index_standard);
+            this.target_list.push(item.target);
+            this.index_weight_list.push(item.index_weight);
+          })
+          this.user_list = this.uniqueArray(this.user_list);
+          this.index_name_list = this.uniqueArray(this.index_name_list);
+          this.index_standard_list = this.uniqueArray(this.index_standard_list);
+          this.target_list = this.uniqueArray(this.target_list);
+          this.index_weight_list = this.uniqueArray(this.index_weight_list);
+        }
+      },
+      //判断评分节点是否有人评了分
+      returnIs(list) {
+        let is = true;
+        list.forEach(item => {
+          if (item.code == 'score_supervisor' || item.code == 'special_scorer') {
+            item.target.forEach(e => {
+              if (e.status == 2) {
+                is = false;
+              }
+            })
+          }
+        })
+        return is
+      },
+    },
+    created() {
+      if (this.peIds) {
+        this.getPackageDtail();
+      }
+
+    },
+  };
+</script>
+
+<style scoped lang="less">
+  .userName {
+    position: absolute;
+    left: 0%;
+    height: 50px;
+    width: 100%;
+    opacity: 0;
+  }
+
+  .results {
+    border-bottom: 1px solid #f1f1f1;
+    text-align: center;
+    font-size: 0.24rem;
+  }
+
+  .results div {
+    padding: 10px;
+  }
+
+  .line-feed {
+    white-space: pre-wrap;
+  }
+
+  .all {
+    flex: 1;
+    position: relative !important;
+    background-color: #f5f7fa;
+    padding-bottom: 0.3rem;
+    overflow-y: scroll;
+  }
+
+  header {
+    width: 100%;
+    height: 0.8rem;
+    font-size: 0.3rem;
+    z-index: 1;
+  }
+
+  .isIos {
+    height: calc(100% - 3.6rem);
+  }
+
+  footer {
+    width: 100%;
+    background-color: #fff;
+    border-top: 1px solid #e2e2e2;
+    padding: 0.1rem;
+
+    .footfoot {
+      .footcol {
+        text-align: center;
+      }
+
+      .footBut {
+        display: flex;
+      }
+
+    }
+  }
+
+  .footcolButno {
+    border: 1px solid #42a8ff;
+    width: 1.4rem;
+    height: 0.8rem;
+    font-size: 0.28rem;
+    color: #2f9eff;
+    background-color: #ffffff;
+    border-top-left-radius: 3px;
+    border-bottom-left-radius: 3px;
+  }
+
+  .footcolButok {
+    border: 0;
+    width: 1.4rem;
+    height: 0.8rem;
+    font-size: 0.28rem;
+    color: #fff;
+    background-color: #42a8ff;
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+  }
+
+  .tab-box {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-bottom: 0.01rem solid #f5f7fa;
+    font-size: 0.28rem;
+
+    .tab-item {
+      flex: 1;
+      height: 0.8rem;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+
+
+
+  .popup-title {
+    width: 100%;
+    height: 0.6rem;
+    line-height: 0.6rem;
+    font-weight: 600;
+    font-size: 0.28rem;
+    margin-bottom: 10px;
+    text-align: center;
+  }
+
+  .filter-options-box {
+    width: 100%;
+    height: 8rem;
+    background-color: white;
+    position: absolute;
+    top: 1rem;
+    left: 0;
+  }
+
+  .batch-operate {
+    width: 100%;
+    background-color: white;
+    height: 1rem;
+    font-size: 0.28rem;
+    color: rgb(146, 146, 146);
+    display: flex;
+    align-items: center;
+    box-sizing: border-box;
+  }
+
+
+  .dropdown-item-title {
+    margin-bottom: 10px;
+    padding: 0 0 0 10px;
+    color: rgb(146, 146, 146);
+    font-size: 0.27rem;
+  }
+
+  .dropdown-item-content-list {
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    padding: 0 10px;
+    margin-bottom: 10px;
+    box-sizing: border-box;
+
+    .dropdown-item-content {
+      flex: 0 0 calc((100% - 10px)/3);
+      height: 0.48rem;
+      line-height: 0.48rem;
+      background: #F5F7FA;
+      border-radius: 0.28rem;
+      color: rgb(146, 146, 146);
+      font-size: 0.27rem;
+      text-align: center;
+      margin: 0 5px 5px 0;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      overflow: hidden;
+      transition: 0.3s;
+      padding: 0 0.24rem;
+      box-sizing: border-box;
+
+      &.active {
+        background: #42a8ff;
+        color: white;
+      }
+
+      &:nth-child(3n) {
+        /* 去除第3n个的margin-right */
+        margin-right: 0;
+      }
+    }
+  }
+
+  .van-dropdown-item {
+    position: relative;
+  }
+
+  .btn-container {
+    width: 100%;
+    background-color: #fff;
+    display: flex;
+    justify-content: space-around;
+    border-top: 0.01rem solid #f5f7fa;
+    padding: 10px 0;
+    box-sizing: border-box;
+    z-index: 10;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+  }
+
+  .disabled {
+    color: #bbb;
+    border-color: #bbb;
+  }
+</style>

+ 2616 - 0
src/performance-07-19/components/performanceDetails - 副本.vue

@@ -0,0 +1,2616 @@
+<template>
+  <div :class="[{ bg_fff: skeletonLoad }]">
+    <van-nav-bar :title="detailsTIt" left-arrow @click-left="routerBak">
+      <div v-if="!isDetails" slot="right" @click="handleClick()" style="color: #fff;">筛选<van-icon name="list-switch" /></div>
+    </van-nav-bar>
+    <div v-if="isDisabled && !graded" class="upDownList flex-box flex-d-center">
+      <div class="uDownBut font-flex-word" style="" v-for="(item, index) in headuDown" :key="index" @click="uDownCli(item)">
+        <span v-if="!item.id" style="color: #a2a2a2;">已无待办</span>
+        <span v-else>
+          <span v-if="item.keys == 1">{{ item.keys2 }}</span>
+          {{ item.keys1 }}:{{ item.name }}
+          <span v-if="item.keys == 2">{{ item.keys2 }}</span>
+        </span>
+      </div>
+    </div>
+    <template v-if="isDetails">
+        <VanSkeleton :skeLoad="skeletonLoad">
+          <div class="overall">
+            <scroller :isNeed="isNeed">
+              <div :style="isDisabled ? 'padding-bottom: 3rem;' : 'padding-bottom: 2rem;'">
+                <header>
+                  <div class="flex-box-ce" style="position: relative;">
+                    <userImage
+                      class="about-me__avatar"
+                      :id="Information.id"
+                      :img_url="Information.img_url"
+                      :user_name="Information.name"
+                      fontSize=".28"
+                      width=".75rem"
+                      height=".75rem"
+                      style="margin-top:.1rem;"
+                    ></userImage>
+                    <div style="padding:.1rem 0 0 .25rem; box-sizing: border-box;">
+                      <span style="font-size:.28rem;color:black;">{{ Information.name }}</span>
+                      <span v-if="okrs && okrs.length > 0" class="okr-tips" @click="goMyTarget">查看okr</span>
+                      <br />
+                      <span class="font-flex-word" style="width: 4.4rem;display:inline-block;" v-if="Information.employee_detail && Information.employee_detail.dept_list.length>0">
+                        <span class="pdHeadDept" v-for="(arr, att) in Information.employee_detail.dept_list" :key="att">
+                          {{ arr.dept_name }}
+                          <span v-if="Information.employee_detail.dept_list.length - att > 1">,</span>
+                        </span>
+                      </span>
+                    </div>
+                    <img v-if="has_finish" class="guidang" src="static/images/guidang.png" />
+                  </div>
+                  <div v-if="titList.length > 0" style="border-top:1px solid #e0e0e0; padding: .25rem 0 0rem 0; margin: .25rem 0 0 0;" class="">
+                    <van-row v-for="(list, arr) in titList" :key="arr" style="font-size:.29rem;padding:.1rem 0;" v-if="list.prop">
+                      <van-col span="5" style="color:#757575;">{{ list.lab }}:</van-col>
+                      <van-col span="19">
+                        <div v-if="typeof list.prop == 'object'">
+                          <div v-for="(data, sit) in list.prop" :key="sit">{{ data }}</div>
+                        </div>
+                        <span v-else v-html="list.prop" class="orange"></span>
+                      </van-col>
+                    </van-row>
+                  </div>
+                </header>
+                <div>
+                  <div class="modTit flex-box flex-d-center">
+                    <span>绩效流程</span>
+                    <van-checkbox icon-size=".28rem" v-model="checked" shape="square">查看更多</van-checkbox>
+                  </div>
+                  <div class="flexPopover" ref="refarrow">
+                    <div class="flex_one flex-box flex-d-center" v-if="perfstepFlow[flexIndex - 1]" @click="flexDialog = true">
+                      <div class="font-flex-word">
+                        <span>{{ flexIndex }}. {{ perfstepFlow[flexIndex - 1].remark }}</span>
+                        <span v-if="perfstepFlow[flexIndex - 1].target.length > 0">
+                          <span v-for="(item, index) in perfstepFlow[flexIndex - 1].target" :key="index">
+                            {{ item.employee_name }}
+                            <span v-if="perfstepFlow[flexIndex - 1].target.length - index > 1">,</span>
+                          </span>
+                        </span>
+                      </div>
+                      <div><van-icon name="arrow-down" /></div>
+                    </div>
+                  </div>
+                </div>
+
+                <!-- 执行中 -->
+                <div v-for="(item, index) in inExecution" :key="index">
+                  <div class="modTit">{{ item.theDimension }}</div>
+                  <div class="modCont">
+                    <div v-if="!item.totalScore" style="padding-bottom: .1rem;" class="flex-box flex-d-center">
+                      <span style="font-size: .33rem;font-weight: bold;color: #303133;">
+                        <span>{{ item.name }}</span>
+                      </span>
+                    </div>
+                    <div>
+                      <span v-for="(list, arr) in item.tabList" :key="arr" class="tab-List" v-if="list.prop">{{ list.prop }}</span>
+                      <div v-if="initData(item.per_remark)" class="stanif">
+                        <div class="stanTit">考核标准</div>
+                        <div class="standara"><span class="standarapad line-feed" v-html="item.per_remark"></span></div>
+                      </div>
+                    </div>
+                    <!-- 详情信息 -->
+                    <div>
+                      <div v-for="(list, arr) in item.details" :key="arr" class="flex-box" style="font-size:.29rem;padding:.1rem 0;" v-if="list.prop && list.prop != '0'">
+                        <div style="color:#757575;">{{ list.lab }}:</div>
+                        <div style="padding-left: 0.2rem;" class="flex-1">
+                          <pre v-if="list.lab == '备注'" class="pre">{{ list.prop }}</pre>
+                          <div v-else-if="list.lab == '结果值附件'">
+                              <div class="flex-box-ce" style="margin: 10px 0;" v-if="list.prop.images.length>0">
+                                <van-image @click="openImg(list.prop.images,imgIndex)" v-for="(e,imgIndex) in list.prop.images" :key="imgIndex" style="border-radius: 3px;margin-right: 10px;" width="70" height="70" :src="e.url"/>
+                              </div>
+                              <div class="flex-box-v" v-if="list.prop.append.length>0">
+                                <div class="color_blue" style="margin-bottom:5px;" @click="downWgt(e.url,e.name)" v-for="(e,imgIndex) in list.prop.append" :key="imgIndex">{{e.name}}</div>
+                              </div>
+                          </div>
+                          <div v-else-if="list.lab == '结果值'" class="orange">{{ list.prop }}</div>
+                          <div v-else>{{ list.prop }}</div>
+                        </div>
+                      </div>
+                    </div>
+                    <!-- 评分结果 -->
+                    <div>
+                      <van-row v-for="(list, arr) in item.scoreList" :key="arr" v-if="list.prop && isShowOneself(list)">
+                        <van-col span="24" style="color:#757575; font-size:.29rem;padding:.1rem 0;">
+                          <template v-if="list.pointShow">
+                            <span>{{ list.lab }}</span>
+                            <span class="orange">评分:</span>
+                            <span>{{ list.prop }}</span>
+                            <span v-if="list.level" style="margin-left: .1rem;color: #26a2ff;">{{ list.level }}</span>
+                          </template>
+                        </van-col>
+                        <van-col span="24">
+                          <div class="flex-box" style="font-size:.29rem;padding:.1rem 0;" v-if="list.remark && list.textShow">
+                            <span style="padding-right: 0.2rem;color:#757575;">说明:</span>
+                            <pre class="pre2 flex-1">{{ list.remark }}</pre>
+                          </div>
+                        </van-col>
+                      </van-row>
+                    </div>
+
+                    <div class="flex-box-ce">
+                      <span v-if="item.schedule && item.schedule.length > 0" style="font-size: .28rem;padding-right:.2rem;color:#1d96ff;" @click="openPlanPath(item, 'action')">
+                        执行计划({{ item.schedule.length }})
+                      </span>
+                      <span v-if="item.mamage_record && item.mamage_record.length > 0" style="font-size:.26rem; color:rgb(29, 150, 255);" @click="openPlanPath(item, 'admnin')">
+                        管理记录({{ item.mamage_record.length }})
+                      </span>
+                    </div>
+                    <div v-if="item.update_time" style="border-top: 1px solid #f1f1f1;margin-top: 0.2rem;">
+                      <div v-if="returnStr(item.update_time).indexOf('今天')>=0" class="orange" style="font-size: 0.28rem;padding-top: 0.2rem;" >{{returnStr(item.update_time)}}</div>
+                      <div v-else-if="returnStr(item.update_time).indexOf('昨天')>=0" class="color_green" style="font-size: 0.28rem;padding-top: 0.2rem;" >{{returnStr(item.update_time)}}</div>
+                      <div v-else-if="returnStr(item.update_time).indexOf('前天')>=0" style="font-size: 0.28rem;padding-top: 0.2rem;" >{{returnStr(item.update_time)}}</div>
+                      <div v-else style="font-size: 0.28rem;padding-top: 0.2rem;" >{{returnStr(item.update_time)}}</div>
+                    </div>
+
+                    <!-- 评分 -->
+                    <div style="margin:.2rem 0;" v-if="graded">
+                      <div  v-if="item.auto_score||item.auto_score===0" class="flex-box-ce" style="font-size: 0.28rem;">
+                        <div class="flex-1" @click="showE(item)"><span>系统评分</span><van-icon name="question-o" style="position: relative;top: 2px;" />:<span class="color_blue">{{item.auto_score}}</span></div>
+                        <div class="blue" style="text-decoration:underline" @click="copyPoin(item)">使用系统评分</div>
+                      </div>
+                      <div v-if="(ruleScore == 1 && !item.totalScore) || (ruleScore == 2 && item.totalScore)">
+                        <van-cell-group>
+                          <van-field
+                            label="评分"
+                            v-model="item.resultval"
+                            type="number"
+                            placeholder="请输入评分"
+                            @focus="isShowPoint = false"
+                            style="border: 1px solid rgb(226 226 226);border-radius: 5px;"
+                            @blur="watresultval(item.resultval, item.totalScore ? item.totalScore : false)"
+                            @input="[sgradeInp(item), (item.resultval = item.resultval.match(/\d+(\.\d{0,2})?/) ? item.resultval.match(/\d+(\.\d{0,2})?/)[0] : '')]"
+                          />
+                        </van-cell-group>
+                      </div>
+                      <div v-if="(ruleScore == 1 && !item.totalScore) || (ruleScore == 2 && item.totalScore)">
+                        <van-cell-group>
+                          <van-field
+                            v-model="item.remarks"
+                            label="评分说明"
+                            rows="3"
+                            type="textarea"
+                            @focus="isShowPoint = false"
+                            @blur="isShowPoint = true"
+                            maxlength="50"
+                            autosize
+                            placeholder="请输入"
+                            show-word-limit
+                            style="border: 1px solid rgb(226 226 226);border-radius: 5px;"
+                          />
+                        </van-cell-group>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+
+                <!-- 记录 -->
+                <div v-if="recordList.length > 0">
+                  <div class="modTit">记录</div>
+                  <div class="modCont" style="">
+                    <div
+                      v-for="(item, index) in recordList"
+                      :key="index"
+                      :style="index != recordList.length - 1 ? 'min-height: 1rem;' : ''"
+                      style="position: relative;padding-bottom: .2rem;"
+                    >
+                      <van-row gutter="10">
+                        <van-col span="15">
+                          <div style="display:flex;">
+                            <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.name" fontSize=".24" width="0.5rem" height="0.5rem" font_min></userImage>
+                            <span style="font-size:.255rem;padding: .06rem 0 0 .07rem;" class="font-flex-word">{{ item.name }}</span>
+                          </div>
+                          <div v-if="index != recordList.length - 1" class="bian"></div>
+                        </van-col>
+                        <van-col span="9" style="font-size:.24rem;color:#ababab;padding:.06rem 0 0 0;">{{ item.time }}</van-col>
+                      </van-row>
+                      <van-row>
+                        <van-col offset="2" span="" style="font-size:.255rem;padding-top:.06rem;white-space:normal;">
+                          <div style="color:#3bab62;"># {{ item.remark }} #</div>
+                          <div style="color:#ababab;width: 100%;word-break:break-all;" v-if="item.content">{{ item.content }}</div>
+                        </van-col>
+                      </van-row>
+                    </div>
+                    <span style="font-size: .26rem;color: #5699ff;" @click="unfold" v-if="recordList.length <= 3 && recordAllList.length > 3">全部记录</span>
+                    <span style="font-size: .26rem;color: #5699ff;" @click="packUp" v-if="recordList.length > 3">收起</span>
+                  </div>
+                </div>
+              </div>
+              <div style="padding-bottom: 1.5rem;"></div>
+            </scroller>
+          </div>
+        </VanSkeleton>
+        <template v-if="!has_finish">
+          <!-- 执行计划 -->
+          <div class="sidebar flex-box-ce" v-if="actionButShow && !graded" @click="openTrackPath('action')">
+            <van-icon name="plus" size=".32rem" />
+            <icon name="delivery_of_program" class="isdeliveryRecord_icon" />
+            执行计划
+          </div>
+          <!-- 管理记录 -->
+          <div class="managementRecord flex-box-ce" v-if="recordsManagement && !graded" @click="openTrackPath('admnin')">
+            <van-icon name="plus" size=".32rem" />
+            <icon name="management_record" class="isdeliveryRecord_icon" />
+            管理记录
+          </div>
+
+          <div class="footerBut" :class="{ isIos: isIos }">
+            <div v-if="!graded">
+              <div class="footweight">指标总权重:{{ weight }}</div>
+              <div class="footfoot flex-box flex-dv-center" v-if="transferBut || feedbackBut || gradeButShow || examineButShow || resultButShow || targetConfirmed">
+                <div class="footcol" v-if="revocationShow" @click="openCx">
+                  <icon name="withdraw" style="width: 0.5rem;height: 0.5rem;"></icon>
+                  <div style="font-size: .24rem;">撤销</div>
+                </div>
+                <!-- 结果值编辑 -->
+                <div class="footcol" v-if="resultButShow2" @click="enteringResult">
+                  <icon name="withdraw" style="width: 0.5rem;height: 0.5rem;"></icon>
+                  <div style="font-size: .24rem;">{{resultStr}}</div>
+                </div>
+                <div class="footcol" v-if="transferBut" @click="openSelectUser">
+                  <icon name="careOf" style="width: 0.5rem;height: 0.5rem;"></icon>
+                  <div style="font-size: .24rem;">转交</div>
+                </div>
+                <div class="footcol" v-if="feedbackBut" @click="communicate">
+                  <icon name="messagejx" style="width: 0.5rem;height: 0.5rem;"></icon>
+                  <div style="font-size: .24rem;">沟通</div>
+                </div>
+
+                <div class="footBut" v-if="gradeButShow || examineButShow || resultButShow || targetConfirmed">
+                  <!-- 评分 -->
+                  <button v-if="gradeButShow" class="gradefootcolButok" @click="gradeClick">评分</button>
+                  <!-- 审批 -->
+                  <button v-if="examineButShow && isAction" style="" class="footcolButno" @click="gradeTurn">驳回</button>
+                  <button v-if="examineButShow" :class="isAction ? 'footcolButok' : 'gradefootcolButok'" @click="gradeOk">同意</button>
+                  <!-- 目标确认 -->
+                  <template v-if="targetConfirmed">
+                    <button style="" class="footcolButno" @click="gradeTurn">驳回</button>
+                    <button class="gradefootcolButok" @click="gradeOk">同意</button>
+                  </template>
+                  <!-- 结果值录入 -->
+                  <button v-if="resultButShow" class="gradefootcolButok" @click="enteringResult">{{resultStr}}</button>
+                </div>
+              </div>
+            </div>
+            <div v-else>
+              <template v-if="isShowPoint">
+                <div class="footweight">我评的总分:{{ gradeval }}</div>
+                <van-row class="footfoot">
+                  <van-col span="14" class="footcol" @click="scorerveok(0)">
+                    <icon name="save" style="width: 0.5rem;height: 0.5rem;"></icon>
+                    <div style="font-size: .24rem;color:#8a8a8a;">暂存</div>
+                  </van-col>
+                  <van-col span="10" class="footBut">
+                    <button style="" class="footcolButno" @click="scorerveno">取消</button>
+                    <button class="footcolButok" @click="scorerveok(1)">提交</button>
+                  </van-col>
+                </van-row>
+              </template>
+            </div>
+          </div>
+        </template>
+    </template>
+    <resultValueEntryMb v-else ref="result-mb" :peIds="pe_ids" :isUpdate="isUpdate"></resultValueEntryMb>
+
+    <van-dialog v-model="isShowE" :show-cancel-button="false">
+      <div style="padding: 10px;font-size: 0.28rem;">
+         <div class="flex-box-ce" style="margin-bottom: 10px;">按以下公式和数据自动计算评分
+         </div>
+        <div v-html="eData.expressionStr" style="background-color: #f1f1f1;padding: 10px;text-align: left;border-radius: 5px;cursor: pointer;"></div>
+        <div class="flex-box-ce" style="margin-top: 10px;">
+          <div class="orange" style="margin-right: 20px;">结果值:{{eData.result}}</div>
+          <div class="orange">目标值:{{eData.target}}</div>
+        </div>
+       </div>
+    </van-dialog>
+
+    <van-popup
+      :duration="0.2"
+      :get-container="getContainer"
+      :overlay="false"
+      v-model="communication"
+      position="bottom"
+      :style="'height:' + com_height"
+      class="employee_selector_popup"
+    >
+      <van-nav-bar :title="detailsTIt" left-text="" left-arrow @click-left="communication = false" />
+      <div style="height:.2rem;background-color:#f5f7fa;"></div>
+      <div v-if="popupknowFrom == 1">
+        <van-cell title="驳回到" is-link :value="rejectval" @click="openBh()" />
+        <van-cell v-if="rejectProp" title="驳回到指定成员" is-link :value="rejectval1" @click="rejectdlg1 = true" />
+        <div style="height:.2rem;background-color:#f5f7fa;"></div>
+      </div>
+      <div>
+        <van-field
+          v-model="commFeedback"
+          rows="6"
+          autosize
+          type="textarea"
+          :placeholder="
+            popupknowFrom == 0
+              ? '请输入沟通反馈(必填)'
+              : popupknowFrom == 1
+              ? '请输入驳回内容(必填)'
+              : popupknowFrom == 2
+              ? '请输入审批说明(选填)'
+              : popupknowFrom == 3
+              ? '请输入目标确认说明(选填)'
+              : popupknowFrom == 4
+              ? '请输入撤销理由(选填)'
+              : ''
+          "
+        />
+      </div>
+      <div class="commButt">
+        <div class="aite" v-if="popupknowFrom == 0">
+          <span @click="selectUser = true" style="color: #4498ef;">@</span>
+          <span style="font-size: .25rem;text-align:left;">
+            <span class="font-flex-word" style="max-width: 5.8rem;display:inline-block;">
+              <span v-for="(item, index) in emtags" :key="index">
+                {{ item.name }}
+                <span v-if="emtags.length - index > 1">,</span>
+              </span>
+            </span>
+            <span v-if="emtags.length > 3">等{{ emtags.length }}人</span>
+          </span>
+        </div>
+        <button class="commButtno" @click="commcliButon">取消</button>
+        <button class="commButtok" @click="commcliButok">确定</button>
+      </div>
+    </van-popup>
+
+    <van-dialog v-model="rejectdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectpradio">
+        <div v-for="(item, index) in rejectList" :key="index">
+          <van-radio :name="index" @click="clickreject(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.26rem" icon-size="16px">
+            <span>{{ index + 1 }} .</span>
+            <span>{{ item.name }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+    <van-dialog v-model="rejectdlg1" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectpradio1">
+        <div v-for="(item, index) in rejectList1" :key="index">
+          <van-radio :name="index" @click="clickreject1(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.26rem" icon-size="16px">
+            <span style="margin-left: .25rem">{{ item.employee_name }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+    <van-dialog v-model="selectZj" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <div style="text-align: center;font-size: 0.24rem;padding: 0.2rem 0;">请选择被转交人员</div>
+      <van-radio-group v-model="zjId">
+        <div v-for="(item, index) in careOfPeopleId" :key="index">
+          <van-radio :name="item.employee_id" :label="item.employee_id" style="margin:.3rem 0 .3rem .4rem;font-size:.26rem" icon-size="16px">
+            <span style="margin-left: .25rem">{{ item.employee_name }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+    <van-dialog v-model="flexDialog" title="" width="350" :show-confirm-button="false" closeOnClickOverlay>
+      <div class="flexDiaWb">
+        <div v-for="(item, index) in perfstepFlow" :key="index" class="flexDiaLL flex-box" :style="perfstepFlow.length - 1 == index ? 'padding: 0;' : ''">
+          <span class="fdz">
+            <div class="fdYuan fdYuan1" v-if="item.status == 2"><van-icon name="success" /></div>
+            <div class="fdYuan fdYuan2" v-else-if="item.status == 1"><van-icon name="play" size=".38rem" /></div>
+            <div class="fdYuan fdYuan3" v-else></div>
+            <div class="fdShu" :class="{ fdShu1: item.status == 2 }" v-if="!(perfstepFlow.length - 1 == index)"></div>
+          </span>
+          <span class="fdy" :class="{ fdyBlue: item.status == 1 }" style="position: relative;top:2px">
+            <span style="height: 100%;padding-right:.15rem;">{{ index + 1 }}.</span>
+            <div>
+              {{ item.remark }}
+              <span v-if="item.target.length > 0">
+                <span v-for="(item2, index2) in item.target" :key="index2">
+                  {{ item2.employee_name }}
+                  <span v-if="item.target.length - index2 > 1">,</span>
+                </span>
+              </span>
+            </div>
+          </span>
+        </div>
+      </div>
+    </van-dialog>
+    <!-- 沟通反馈 -->
+    <EmployeeSelector
+      title="选择@人员"
+      :visible.sync="selectUser"
+      @confirm="confirmCreator"
+      :can_select_dept="false"
+      :dept_multi="false"
+      :append_body="true"
+      :isShowDepts="false"
+    />
+    <!-- 转交 -->
+    <EmployeeSelector
+      :title="'选择转交人员'"
+      :multi="false"
+      ref="selector"
+      :can_select_dept="false"
+      :dept_multi="false"
+      @confirm="confirm"
+      :visible.sync="show_dept_selector"
+      :append_body="true"
+      :isShowDepts="false"
+    ></EmployeeSelector>
+
+    <van-popup v-model="isPoint" :close-on-click-overlay="false" style="border-radius: 0.15rem; background: #fff0;">
+      <div class="buyPopupBody" style="width: 90vw;">
+        <div class="buyPopupContent" style="position: relative;background: white;padding: 0 5vw 5vw 5vw;border-radius: 0.15rem;">
+          <div
+            class="buyPopupTitle"
+            style="background: #1a89fa;
+            text-align: center;
+            border-radius: 0.1rem;
+            font-weight: normal;
+            font-size: 0.36rem;
+            height: 0.8rem;
+            line-height: 0.8rem;
+            color: #fff;"
+          >
+            请确认您的评分
+          </div>
+          <div style="max-height: 500px;overflow-y: auto;font-size: 0.32rem;margin: 0.28rem 0;border: 1px solid #e4e4e4;border-bottom: none;">
+            <div class="flex-box-ce" style="background:#ECF5FF;border-bottom: 1px solid #e4e4e4;">
+              <div class="flex-4" style="border-right: 1px solid #e4e4e4;padding: 10px 5px;">
+                指标(<span style="color:#ff9600;">每项指标评分</span>)
+              </div>
+              <div class="flex-1" style="padding: 10px 5px;">评分</div>
+            </div>
+            <div v-for="(item, index) in pointList" :key="index" class="flex-box-ce" style="border-bottom: 1px solid #e4e4e4;">
+              <div class="flex-4" style="border-right: 1px solid #e4e4e4;padding: 10px 5px;">{{ item.name }}</div>
+              <div class="flex-1" style="padding: 10px 5px;">{{ item.score }}</div>
+            </div>
+          </div>
+          <van-row gutter="20">
+            <van-col span="12"><van-button block @click="isPoint = false">返回修改</van-button></van-col>
+            <van-col span="12"><van-button block type="info" @click="score">确认提交</van-button></van-col>
+          </van-row>
+        </div>
+      </div>
+    </van-popup>
+    <!-- 展示 执行 管理 记录 -->
+    <van-action-sheet v-model="isShowText" :closeable="false" duration=".35">
+      <div class="vassheet">
+        <div class="vasHead">
+          <van-icon name="cross" size=".3rem" @click.stop="isShowText = false" />
+          <span>{{ logText }}</span>
+        </div>
+        <div style="padding:0.15rem 0.15rem 0 0.15rem;font-size:.32rem;background-color: rgb(245, 245, 245);">{{ apDetails.name }}</div>
+        <div v-for="(item, index) in logList" :key="index" class="apdList flex-box" :class="{ apdListMarTop: index == 0 }">
+          <div style="margin: .24rem 0 0 .2rem;position: relative;">
+            <div class="apdDian"></div>
+            <div class="apdHeadBoeder" :class="{ apdborderNO: index == logList.length - 1 || logList.length <= 1 }"></div>
+          </div>
+          <div class="apdData" :class="{ apdborderNO: logList.length == index + 1 }">
+            <div>
+              <b class="line-feed" style="font-size:.3rem;color:block;">{{ item.title }}</b>
+              <br />
+              <span style="font-size:.24rem;color:#b7b7b7;">
+                {{ item.date }}
+                <span v-if="logText == '管理记录' && $getEmployeeMapItem(item.employee_id)">&nbsp; 记录人:{{ $getEmployeeMapItem(item.employee_id).name }}</span>
+              </span>
+              <br />
+              <span class="line-feed" style="font-size:.25rem;color:#505050;" v-html="item.remark"></span>
+            </div>
+            <template v-if="item.images">
+              <div class="flex-box-ce" style="margin: 10px 0;" v-if="item.images.length > 0">
+                <van-image @click="openImg(item.images, index2)" v-for="(e, index2) in item.images" :key="index2" style="border-radius: 3px;margin-right: 10px;"  width="100"  height="100" :src="e.url" />
+              </div>
+            </template>
+            <template v-if="item.append_name">
+              <div class="color_blue" style="margin: 10px 0;font-size: 0.28rem;" @click="downWgt(item.append,item.append_name)">{{item.append_name}}</div>
+            </template>
+          </div>
+        </div>
+      </div>
+    </van-action-sheet>
+
+  </div>
+</template>
+<script>
+import Vue from 'vue';
+import moment from 'moment';
+import { Checkbox, CheckboxGroup, ActionSheet, ImagePreview } from 'vant';
+Vue.use(Checkbox)
+  .use(CheckboxGroup)
+  .use(ActionSheet)
+  .use(ImagePreview);
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import resultValueEntryMb from '@/performance/components/actionplan/resultValueEntryMb';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import {getExpressionStr} from '@/performance/utils/auth'
+
+export default {
+  data() {
+    return {
+      isShowE:false,
+      eData:{
+        expressionStr:'',
+        result:'',
+        target:''
+      },
+
+      isDetails:true,
+      pe_ids:'',
+
+      day: moment().format('YYYY-MM-DD'),
+      isNeed: !this.$getCache('isAndroid'),
+      detailsTIt: '', // 顶部title
+      skeletonLoad: true, // 骨架屏
+      employeeID: this.$route.query.id, // 绩效记录ID
+      assID: this.$route.query.assId, // 考核包ID
+      staffID: this.$route.query.staffId, // 员工ID
+
+      perfstepFlow: [], // 步骤
+      smdsinsFlow: 0, // 当前绩效流程所在位置
+      flowNow: {}, // 当前节点
+
+      thecurrentFlow: '', // 当前节点
+      ruleScore: 1, // 1-指标均要评分 2-评分总结
+      mandatoryScore: false, // 指标说明是否必填
+
+      weight: '',
+
+      userInfo: this.$userInfo(), // 当前角色
+
+      apList: [], // 执行计划数据
+      planIndex: [], // 执行计划的下标,当点击表格查看时用到
+
+      // 按钮显示隐藏
+      targetConfirmed: false, // 目标确认
+      gradeButShow: false, // 评分
+      examineButShow: false, // 审批
+      isAction: false, // 审批驳回
+      resultButShow: false, // 结果值录入
+      resultButShow2:false,// 结果值编辑
+      actionButShow: false, // 执行计划
+      recordsManagement: false, // 管理记录
+      feedbackBut: false, // 沟通反馈按钮
+
+      transferBut: false, // 转交按钮
+      careOfPeopleId: [], // 转交的 -- 转出ID
+      selectZj: false,
+      zjId: 0, // 转交用户ID
+
+      revocationShow: false, //是否可以撤销
+      revocationNodeId: 1, //撤销节点ID
+
+      recordList: [], // 记录列表
+      recordAllList: [], // 记录列表
+
+      selectUser: false, // 沟通反馈@
+      emtags: [], // 沟通反馈@选中人员
+
+      selectpradio: '',
+      selectpradio1: '',
+      rejectList: [],
+      rejectList1: [],
+      rejectdlg: false, // 驳回选项弹窗
+      rejectval: '', // 驳回选中内容
+
+      rejectData: {}, // 驳回数据
+
+      rejectProp: false, // 驳回--选人
+      rejectdlg1: false, // 驳回选人选项弹窗
+      rejectval1: '', // 驳回选人选中内容
+
+      popupknowFrom: 0, // 0:沟通反馈,1:驳回,2审批,3目标确认,4.撤销
+      gradeval: 0, // 评分总分
+      graded: false, // 评分模块开关
+      commFeedback: '', // 沟通弹窗反馈
+      communication: false, // 沟通弹窗
+      show_dept_selector: false, // 转交选人
+
+      isIos: this.$getCache('iPhone'),
+      Information: {
+        // 顶部员工信息
+        name: '',
+        employee_detail:{dept_list:[]},
+      },
+
+      // 执行中
+      inExecution: [],
+      scoreInfo: [], // 各个节点的人评的总分
+      titList: [],
+      bootBool: false, // 防止多次请求
+      isCs: false, // 是否抄送人进入(抄送人能看到全部评分内容)
+      com_height: '100%',
+
+      isDisabled: false, //是否显示上下一条
+      headuDown: [],
+      pendingList: [],
+      page: 1,
+      isJz: true,
+      activeName: '', //待办带进来的节点类型
+
+      checked: false, //只看自己评分
+      recordMemberIds: [],
+
+      flexDialog: false,
+      flexIndex: 0,
+      has_finish: 0, //是否归档 0否 1是
+
+      // 评分确认列表
+      pointList: [],
+      pointData: {},
+      isPoint: false,
+
+      isShowPoint: true,
+      publicity: 0,
+
+      isShowText: false,
+      isUpdate:false,
+      logText: '执行计划',
+      logList: [],
+      apDetails: {},
+      resultStr:'录入结果值',
+      okrs: [], // 已关联的OKR
+    };
+  },
+  computed: {
+    isShowOneself() {
+      return function(value) {
+        if(this.titList.length > 0){
+          return true;
+        }else if (!this.checked) {
+          if (value.employee_id == this.userInfo.id) {
+            return true;
+          } else {
+            return false;
+          }
+        } else {
+          return true;
+        }
+      };
+    }
+  },
+  components: { EmployeeSelector, VanSkeleton,resultValueEntryMb },
+  watch: {
+    zjId(val) {
+      if (val) {
+        this.selectZj = false;
+        this.show_dept_selector = true;
+      }
+    }
+  },
+  methods: {
+    handleClick() {
+      this.$refs["result-mb"].isFilterShow = true;
+    },
+    goMyTarget() {
+      this.$router.push({name: 'myTarget', query: {ids: JSON.stringify(this.okrs)}});
+    },
+    copyPoin(item){
+      if(item.auto_score<0||item.auto_score===0){
+        item.resultval='0';
+      }else{
+        item.resultval=item.auto_score
+      }
+    },
+    showE(item){
+      this.eData={
+        expressionStr:item.expressionStr,
+        result:item.result,
+        target:item.target
+      };
+      this.isShowE=true;
+    },
+    downWgt (url,name) {
+      let self = this
+      if(!window.plus){
+          window.open(url, '_blank');
+          return false
+      }
+      let dtask=plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
+        function (d, status) {
+          if (status == 200) {
+            plus.runtime.openFile(d.filename,{},(err)=>{
+              // console.log(JSON.stringify(err))
+            });
+          } else {
+            self.$toast.clear()
+            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
+          }
+        }
+      )
+      dtask.start();
+    },
+    returnStr(time){
+      let date=`${time}000`
+      let res = moment(Number(date)).format('YYYY/MM/DD HH:mm');
+      return this.fnTime(res);
+    },
+    fnTime( time ){
+        let staer=time.slice(0,11);
+        let ptime = new Date(time).getTime()
+        const twentyFourHours = 24 * 60 * 60 * 1000;
+        const fortyEightHours = 24 * 60 * 60 * 1000 * 2;
+        const today = moment().format('YYYY/MM/DD');
+
+        const todayTime = new Date(today).getTime();
+        const yesterdayTime = new Date(todayTime - twentyFourHours).getTime();
+        const lastYesterdayTime = new Date(todayTime - fortyEightHours).getTime();
+
+        if( ptime >= todayTime ){
+            return '今天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < todayTime && yesterdayTime <= ptime ){
+            return '昨天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < yesterdayTime && lastYesterdayTime <= ptime ){
+            return '前天 '+time.split(' ')[1]+' 更新了执行计划';
+        }else if(this.dateSum(this.day,staer)>30){
+            return '近30天无计划更新';
+        } else{
+            return time+' 更新了执行计划';
+        }
+    },
+    dateSum(sDate1, sDate2){   //sDate1和sDate2是2008-12-13格式
+        var aDate, oDate1, oDate2, iDays
+        aDate = sDate1.split("-")
+        oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])   //转换为12-13-2008格式
+        aDate = sDate2.split("-")
+        oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
+        iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 /24)   //把相差的毫秒数转换为天数
+        return iDays
+    },
+    openImg(imgs, index) {
+      let imgArr = imgs.map(item => {
+        return item.url;
+      });
+      ImagePreview({
+        images: imgArr,
+        startPosition: index
+      });
+    },
+    // 获取待办数据
+    getAgency() {
+      if (!this.isJz) {
+        return false;
+      }
+      this.page = this.page + 1;
+      this.$axiosUser('get', '/api/pro/per/package/msg/agency', { node_type: this.activeName, status: 0, page: this.page, page_size: 10 },'v2').then(res => {
+        let list = res.data.data.list;
+        let pendingList = [];
+        list.forEach(item => {
+          if(item.node_type==4){
+            let userInfo = this.$getEmployeeMapItem(item.first_employee_id);
+            item.userInfo = userInfo;
+            let name=item.content.split(',')[0]
+            pendingList.push({ name: userInfo.name, employeeID: '结果', package_name: name,package_id:item.package_id,pe_ids:item.pe_ids, });
+            return false
+          }
+          if (item.remark.employee_id) {
+            //被考核人
+            let userInfo = this.$getEmployeeMapItem(item.remark.employee_id);
+            item.userInfo = userInfo;
+            pendingList.push({ name: userInfo.name, img_url: userInfo.img_url, employeeID: item.remark.packageEmployee_id, package_name: item.remark.package_name });
+          }
+        });
+        if (list.length < 10) {
+          this.isJz = false;
+        }
+        this.pendingList.push(...pendingList);
+      });
+    },
+    openBh() {
+      if (this.rejectList.length == 0) {
+        this.$toast.fail('没有可驳回节点');
+        return false;
+      }
+      this.rejectdlg = true;
+    },
+    openSelectUser() {
+      if (this.careOfPeopleId.length == 1) {
+        this.show_dept_selector = true;
+      } else {
+        this.selectZj = true;
+        this.zjId = 0;
+      }
+    },
+    getContainer() {
+      return document.body;
+    },
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+    employeeDet() {
+      let params = {};
+      if (this.$route.query.id) {
+        params.id = this.employeeID;
+      } else if (this.$route.query.assId && this.$route.query.staffId) {
+        params.package_id = this.$route.query.assId;
+        params.employee_id = this.$route.query.staffId;
+      }
+      this.skeletonLoad = true;
+      this.$axiosUser('get', '/api/pro/per/package/employee/info', params).then(res => {
+        if (res.data.code == 1) {
+          let data = res.data.data;
+          this.okrs = data.okrs || [];
+          this.has_finish = data.has_finish;
+          if (this.pendingList.length > 0) {
+            this.setUpD();
+          }
+          this.recordMemberIds = data.record_member_ids || [];
+          this.empDetList = data;
+          this.employeeID = data.id; // 考核记录id
+
+          this.Information =this.$getEmployeeMapItem(data.employee_id); // 考核人员信息
+          console.log(this.Information)
+          this.perfstepFlow = data.flow; // 流程
+          this.apList = JSON.stringify(data.dimension);
+          this.scoreInfo = data.score_info; // 各个节点的人评的总分
+          this.feedbackBut = data.config.assessment.feedback == '1'; // 沟通反馈是否启用
+          this.resultButShow = false; // 录入结果值
+          this.resultButShow2 = false; // 录入结果值
+          this.gradeButShow = false; // 评分按钮
+          this.examineButShow = false; // 审批按钮
+          this.transferBut = false; // 转交按钮
+          this.targetConfirmed = false; // 目标确认
+          this.publicity = data.publicity;
+          this.actionButShow = false; // 执行计划按钮
+          this.recordsManagement = false; // 管理记录按钮
+          this.revocationShow = false;
+          this.buttonIf2(); //判断管理记录/执行计划按钮是否显示
+          this.smdsinsFlow = 0;
+          this.flexIndex = 0;
+
+          let executor = {}; // 与当前登录账号相同的执行人
+          let review = {}; // 与当前登录账号相同的审批人
+          let isReview=false;//判断账号是否审批人中一位
+          let targetUserList=[];//结果值录入人 ,用来显示结果值录入人
+          data.flow.forEach((item, index) => {
+            if (item.code == 'execution') {
+              // 查找 已开始或已结束的执行节点中有无当前账号
+              if (item.status != 0) {
+                item.target.forEach(tar => {
+                  if (tar.employee_id == this.userInfo.id) {
+                    executor = tar; // 存入与当前登录账号相同的执行人
+                    executor.newCode = 'employee'; // 保存执行人节点code
+                  }
+                });
+              }
+            }
+            if (item.code == 'review') {
+              // 查找 已开始或已结束的审批节点中有无当前账号
+              if (item.status != 0) {
+                item.target.forEach(tar => {
+                  if (tar.employee_id == this.userInfo.id) {
+                    isReview=true;
+                    review = tar; // 存入与当前登录账号相同的审批人
+                    review.newCode = 'reviewer'; // 保存审批人节点code
+                  }
+                });
+              }
+            }
+            if (item.code=='result_value'){//获取结果值录入人集合
+               targetUserList=item.target
+            }
+            this.buttonIf(item);
+
+            if (item.status == 1) {
+              if (item.code != 'cc') {
+                this.isRevocation(item, data.flow[index - 1]);
+              }
+              data.flow.push({ id: data.flow.length + 1, remark: '结束', status: 0, target: [] });
+              this.flowNow = item;
+              this.smdsinsFlow = item.id;
+              this.flexIndex = index + 1;
+              //结果值录入按钮
+              if(item.code=='result_value'||item.code=='score_supervisor'||item.code=='special_scorer'){
+                this.isresultBtn(item)
+              }
+            }
+          });
+          if (this.flexIndex == 0) {
+            data.flow.push({ id: data.flow.length + 1, remark: '结束', status: 2, target: [] });
+            this.flexIndex = data.flow.length;
+          }
+          if (this.smdsinsFlow == 0) {
+            // 如果当前节点id为0,代表此考核详情已完毕,把最后一个节点作为当前节点
+            this.smdsinsFlow =data.flow[data.flow.length - 1].remark=='结束'?  data.flow[data.flow.length - 2].id:data.flow[data.flow.length - 1].id;
+            let cs =data.flow[data.flow.length - 1].remark=='结束'? data.flow[data.flow.length - 2]:data.flow[data.flow.length - 1];
+            cs.target.some(item => {
+              if (item.employee_id == this.userInfo.id) {
+                this.isCs = true;
+                return true;
+              }
+            });
+          }
+          // 整合表格格式
+          let dimension = data.dimension;
+          let dimeTab = [];
+          let weight = 0; // 权重统计
+          // poiSco    评分权限
+          // poicom    说明权限
+          let poiSco = data.config.assessment.point_scope; // 评分可见权限
+          let poicom = data.config.assessment.point_comment; // 说明可见权限
+          dimension.forEach((item, keys) => {
+            item.index.forEach((arr, index) => {
+              weight += Number(arr.weight);
+              arr.theDimension = item.name + '(' + Number(index + 1) + ')';
+              arr.dimension_weight = item.dimension_weight; // 维度权重
+              arr.score_infos = [];
+              arr.planIndex = [keys, index]; // 当打开执行计划时的下标
+              arr.tabList = [
+                {
+                  lab: '指标类型',
+                  prop: this.indexType(this.initData(arr.type))
+                },
+                {
+                  lab: '指标权重(%)',
+                  prop: this.initData(arr.weight) ? '指标权重:' + this.initData(arr.weight) + '%' : null
+                }
+              ];
+              let isFile=true;
+              if(arr.result_file.append.length==0&&arr.result_file.images.length==0){
+                isFile=false;
+              }
+              // 写入每个指标的结果值录入人
+              let resultUserName=''
+              targetUserList.forEach(target=>{
+                target.list.forEach(target2=>{
+                  if(target2.index_id==arr.id){
+                      resultUserName = target.employee_name; //结果值
+                  }
+                })
+              })
+              let tar ='';
+              if(arr.result!==null&&arr.result!==''&&arr.result!=0){
+                tar=arr.result + arr.unit+`(${resultUserName})`
+              }
+              // if(arr.type==1){
+              arr.details = [
+                { lab: '目标值', prop: arr.target+''+arr.unit},
+                { lab: '结果值', prop: tar },
+                { lab: '结果值附件', prop:isFile?arr.result_file:''},
+                { lab: '加扣分上限', prop: this.initData(arr.point_limit) },
+                { lab: '备注', prop: this.initData(arr.remark) }
+              ];
+              // }else{
+              //   arr.details = [
+              //     { lab: '目标值', prop: arr.target+''+arr.unit},
+              //     { lab: '结果值附件', prop:isFile?arr.result_file:''},
+              //     { lab: '加扣分上限', prop: this.initData(arr.point_limit) },
+              //     { lab: '备注', prop: this.initData(arr.remark) }
+              //   ];
+              // }
+
+              // 权限区分
+              arr.scoreList = [];
+              arr.score_info.forEach((list, auto) => {
+                if (list.id <= this.smdsinsFlow) {
+                  // smdsinsFlow为当前节点id。。数据-id <= 当前节点id .   :筛选出当前节点及之前的评分节点的数据
+                  list.employees.forEach(emplo => {
+                    if (emplo.employee_id == this.userInfo.id && list.id == this.smdsinsFlow) {
+                      arr.resultval = emplo.point;
+                      arr.remarks = emplo.remark;
+                      arr.employee_id = emplo.employee_id;
+                      arr.flowId = list.id;
+                    }
+                    // 获取code
+                    data.flow.forEach(codes => {
+                      if (codes.id == list.id) {
+                        if (codes.code == 'review') {
+                          // 审批
+                          emplo.newCode = 'reviewer';
+                        } else if (codes.code == 'execution') {
+                          // 执行中
+                          emplo.newCode = 'employee';
+                        } else if (codes.code == 'score_supervisor') {
+                          // 指定上级
+                          emplo.newCode = 'manager';
+                        } else if (codes.code == 'special_scorer') {
+                          // 特定上级
+                          emplo.newCode = 'special';
+                        }
+                        codes.target.some(tar => {
+                          //找到每个评分人获取评分状态
+                          if (tar.employee_id == emplo.employee_id) {
+                            emplo.status = tar.status;
+                            return true;
+                          }
+                        });
+                      }
+                    });
+                    // item为评分数据,数据内只有两个节点:指定(score_supervisor,权限名:manager)  特定上级(special_scorer,权限名:special)
+                    // executor  执行人中的当前登陆账号
+                    // review    审批人中的当前登陆账号
+                    if (executor.employee_id) {
+                      // 若有数据,那么当前登录账号必定在执行人中并且执行节点正在执行或已结束(哪怕正在执行也无所谓,前方已经过滤评分数据,会得到[])
+                      if (poiSco[executor.newCode] == '2') {
+                        // 已有数据并且为2 ‘查看所有的’ ,那就可以将所有的评分权限都改为 ‘2’
+                        for (let i in poiSco) {
+                          poiSco[i] = '2';
+                        }
+                      }
+                      if (poicom[executor.newCode] == '2') {
+                        // 说明同上
+                        for (let i in poicom) {
+                          poicom[i] = '2';
+                        }
+                      }
+                    }
+                    if (review.employee_id) {
+                      // 审批节点--同上  (审批节点默认为2,可以直接全部变成2)
+                      if (poiSco[review.newCode] == '2') {
+                        for (let i in poiSco) {
+                          poiSco[i] = '2';
+                        }
+                      }
+                      if (poicom[review.newCode] == '2') {
+                        // 说明同上
+                        for (let i in poicom) {
+                          poicom[i] = '2';
+                        }
+                      }
+                    }
+                    if (item.employee_id == executor.employee_id) {
+                      // 判断当前评分数据是否 与 执行节点的当前帐号一致
+                      if (poiSco[executor.newCode] == '2') {
+                        // 如果一致并且执行节点为‘2’即查看所有,那么就修改当前 评分数据 的权限也为‘2’
+                        poiSco[item.newCode] = '2';
+                      }
+                      if (poicom[executor.newCode] == '2') {
+                        // 执行中的 -- 说明权限-同上
+                        poicom[item.newCode] = '2';
+                      }
+                    }
+                    if (item.employee_id == review.employee_id) {
+                      // 判断当前评分数据是否 与 审批节点的当前帐号一致
+                      if (poiSco[review.newCode] == '2') {
+                        poiSco[item.newCode] = '2';
+                      }
+                      if (poicom[review.newCode] == '2') {
+                        // 审批的 -- 说明权限-同上
+                        poicom[item.newCode] = '2';
+                      }
+                    }
+                    let scoredata = {
+                      // 评分&&说明
+                      lab: emplo.title,
+                      prop: emplo.point,
+                      newCode: emplo.newCode,
+                      employee_id: emplo.employee_id,
+                      level: emplo.level,
+                      remark: emplo.remark,
+                      knowFrom: 0,
+                      status: emplo.status
+                    };
+
+                    arr.scoreList.push(scoredata);
+                    // 单项总分显示
+                    if (this.retrunFs(list.id, emplo).length > 0&&!emplo.point) {  //单项指标评分不显示总分,只评总分显示,要去掉,请把!emplo.point判断去掉
+                      arr.scoreList.push(...this.retrunFs(list.id, emplo));
+                    }
+                  });
+                }
+              });
+              dimeTab.push(arr);
+            });
+          });
+          this.weight = weight + '%';
+          let poiSOk = false; // 评分--为true时所有评分可看
+          let poiCOk = false; // 说明--为true时所有说明可看
+          dimeTab.forEach(arr => {
+            arr.scoreList.forEach(item => {
+              // 判断评分
+              if (poiSco[item.newCode] == '1' && item.employee_id == this.userInfo.id) {
+                item.pointShow = true; //是否显示评分
+              } else if (poiSco[item.newCode] == '2') {
+                // 当前 评分 数据权限等于2时并且(当前数据id为登陆账号  或  执行中权限等于2(代表当前登陆账号为执行中的一员) 或  审批权限等于2(代表当前登陆账号为审批中的一员)) 时,所有评分都可见
+                if (item.employee_id == this.userInfo.id || poiSco[executor.newCode] == '2' || poiSco[review.newCode] == '2') {
+                  poiSOk = true;
+                }
+              }
+              // 判断说明
+              if (poicom[item.newCode] == '1' && item.employee_id == this.userInfo.id) {
+                item.textShow = true; //是否显示说明
+              } else if (poicom[item.newCode] == '2') {
+                if (item.employee_id == this.userInfo.id || poicom[executor.newCode] == '2' || poicom[review.newCode] == '2') {
+                  poiCOk = true;
+                }
+              }
+            });
+          });
+          dimeTab.forEach(arr => {
+            let points = []; //最终显示评分
+            arr.scoreList.forEach(item => {
+
+              if (poiSOk || this.$getRole(1) || this.isCs) {
+                item.pointShow = true;
+              }
+              if (poiCOk || this.$getRole(1) || this.isCs) {
+                item.textShow = true;
+              }
+              if (item.status != 2 && item.id != this.smdsinsFlow) {
+                // delete duplicat[index]
+              } else {
+                points.push(item);
+              }
+            });
+            arr.scoreList = points;
+          });
+          this.inExecution = dimeTab;
+          this.pdLc(); //流程结束后的判断
+          let titDatas = [];
+          if (!this.flowNow.code || this.flowNow.code == 'review') { //是审批节点或者流程结束,(流程结束flowNow为空)
+            if(data.publicity == 1||this.$getRole(1)||isReview){//结果是否公示,是否主次管理员,是否是审批人
+              if (this.initData(data.final_point)) {
+                titDatas.push({ lab: '考核结果', prop: data.final_point });
+              }
+              if (this.initData(data.final_level)) {
+                titDatas.push({ lab: '绩效等级', prop: data.final_level });
+              }
+            }
+          }
+          this.titList = titDatas; // 顶部数据
+          this.recordList = [];
+          // 记录
+          let record = res.data.data.record;
+          record.forEach((item, index) => {
+            item.name = this.$getEmployeeMapItem(item.employee_id).name;
+            if (index < 3) {
+              this.recordList.push(item);
+            }
+          });
+          this.recordAllList = record;
+          this.skeletonLoad = false;
+        }
+      });
+    },
+    openCx() {
+      this.popupknowFrom = 4;
+      this.commFeedback = '';
+      this.communication = true;
+    },
+    // 判断是否显示撤销按钮
+    isRevocation(dqItem, upItem) {
+      // 当前只需要评分节点需要撤回
+      //当前节点包含自己并且其他任意一人未完成的显示按钮
+      if (dqItem.code == 'score_supervisor' || dqItem.code == 'special_scorer') {
+        dqItem.target.some((item, index) => {
+          if (item.employee_id == this.userInfo.id && item.status == 2) {
+            dqItem.target.some((item2, index2) => {
+              if (item2.status == 1) {
+                this.revocationNodeId = dqItem.id;
+                this.revocationShow = true;
+                return true;
+              }
+            });
+          }
+        });
+      }
+      let is = true; //判断当前节点人员是否有完成的
+      //上一节点中包含登录者并且是完成的状态显示按钮
+      if (upItem) {
+        dqItem.target.some((item, index) => {
+          if (item.status == 2) {
+            is = false;
+          }
+        });
+        if (upItem.code == 'score_supervisor' || upItem.code == 'special_scorer') {
+          upItem.target.some((item, index) => {
+            if (item.employee_id == this.userInfo.id && item.status == 2 && is) {
+              this.revocationNodeId = upItem.id;
+              this.revocationShow = true;
+              return true;
+            }
+          });
+        }
+      }
+    },
+    pdLc() {
+      let flow = JSON.parse(JSON.stringify(this.perfstepFlow)).reverse(); //反转流程,找第一个评分节点
+      //流程结束,但是最后一个“评分”节点里有自己显示撤销
+      if (this.publicity == 1) {
+        flow.some(item => {
+          if (item.code == 'review' || item.code == 'cc') {
+            return true;
+          }
+          if (item.code == 'score_supervisor' || item.code == 'special_scorer') {
+            item.target.some(e => {
+              if (e.employee_id == this.userInfo.id && e.status == 2) {
+                this.revocationNodeId = item.id;
+                this.revocationShow = true;
+                return true;
+              }
+            });
+            return true;
+          }
+        });
+      }
+    },
+    //获取指定人员上级列表
+    getSuperiors(employee_id){
+      return this.$axiosUser('get', 'api/pro/employee/superior', {employee_id:employee_id,platform:'3'}).then(res=>{
+        return res.data.data.list
+      })
+    },
+    async buttonIf2() {
+      if (this.Information.id == this.$userInfo().id) {
+        this.actionButShow = true;
+      }
+      // 指定管理记录人是否包含自己
+      this.recordMemberIds.some(item => {
+        if (item == this.$userInfo().id) {
+          this.recordsManagement = true;
+          return true;
+        }
+      });
+      let superior_list=await this.getSuperiors(this.Information.id);
+      superior_list.some(item => {
+        // 判断被考核人的上级是否包含登录者
+        if (item.id == this.$userInfo().id) {
+          this.recordsManagement = true;
+          return true;
+        }
+      });
+      if (this.$getPermis(3)) {
+        // 如果是子管理员并且管理范围权限为“全公司”
+        this.recordsManagement = true;
+      }
+    },
+    //判断是否显示结果值
+    isresultBtn(item){
+      //结果值录入按钮
+      let flow=this.perfstepFlow;
+      if (item.code == 'result_value') {
+        item.target.forEach(tar => {
+          if (tar.employee_id == this.userInfo.id) {
+            this.resultButShow = true;
+            this.resultStr=tar.status==2? '调整结果值':'录入结果值'
+          }
+        });
+        return true;
+      }else{
+        let is=false
+        flow.some(obj=>{
+          if (obj.code == 'result_value') {
+            obj.target.forEach(tar => {
+              if (tar.employee_id == this.userInfo.id) {
+                is = true;
+              }
+            });
+          }
+          if(obj.code=='score_supervisor'||obj.code=='special_scorer'){
+            let isUpdate=true;
+            if(obj.target.length>0){
+              obj.target.forEach(e=>{
+                if(e.status==2){
+                  isUpdate=false
+                }
+              })
+              if(isUpdate&&is){
+                this.resultButShow2 = true;
+                this.resultStr='调整结果值';
+              }
+            }
+            return true
+          }
+        })
+      }
+    },
+    buttonIf(item) {
+      // 按钮控制
+      if (item.status == 1) {
+        // 目标确认
+        if (item.code == 'confirm') {
+          item.target.forEach(tar => {
+            if (tar.employee_id == this.userInfo.id && tar.status == 1) {
+              this.targetConfirmed = true;
+            }
+          });
+        }
+        // 评分按钮
+        if (item.code == 'score_self' || item.code == 'score_mutual' || item.code == 'score_supervisor' || item.code == 'special_scorer') {
+          item.target.forEach(tar => {
+            if (tar.employee_id == this.userInfo.id && tar.status == 1) {
+              this.gradeButShow = true;
+            }
+          });
+        }
+        // 结果值录入按钮
+        if (item.code == 'result_value') {
+          item.target.forEach(tar => {
+            if (tar.employee_id == this.userInfo.id) {
+              this.resultButShow = true;
+              this.resultStr=tar.status==2? '调整结果值':'录入结果值'
+            }
+          });
+        }
+        // 审批按钮
+        if (item.code == 'review') {
+          let reviewif = false;
+          item.target.forEach(tar => {
+            if (tar.employee_id == this.userInfo.id && tar.status == 1) {
+              reviewif = true;
+            }
+          });
+          this.examineButShow = !!reviewif;
+          this.isAction = item.action.indexOf('refuse') >= 0;
+        }
+        this.careOfPeopleId = [];
+        // 当是结果值录入,上级评分,指定人评分,审批时显示转交按钮
+        if (
+          item.code == 'target' ||
+          item.code == 'score_supervisor' ||
+          item.code == 'special_scorer' ||
+          item.code == 'result_value' ||
+          item.code == 'review' ||
+          item.code == 'confirm'
+        ) {
+          item.target.forEach(add => {
+            if ((add.employee_id == this.userInfo.id || this.$getRole(1)) && add.status == 1) {
+              if (item.code == 'review' || item.code == 'confirm') {
+                if (item.action.indexOf('transfer') >= 0 || this.$getRole(1)) {
+                  this.careOfPeopleId.push(add);
+                  this.transferBut = true;
+                }
+              } else if (item.code == 'score_supervisor') {
+                if (item.transfer || this.$getRole(1)) {
+                  this.careOfPeopleId.push(add);
+                  this.transferBut = true;
+                }
+              } else {
+                this.careOfPeopleId.push(add);
+                this.transferBut = true;
+              }
+            }
+          });
+        }
+      }
+    },
+    // 返回节点评分是只评总分的
+    retrunFs(eid, e) {
+      let arr = [];
+      this.scoreInfo.forEach(item => {
+        if (item.id == eid) {
+          item.employees.forEach(u => {
+            if (u.point && u.employee_id == e.employee_id) {
+              let scoredata = {
+                // 评分
+                lab: e.title,
+                prop: u.point + '(总分)',
+                newCode: e.newCode,
+                knowFrom: 0,
+                employee_id: e.employee_id,
+                level: '',
+                remark: u.comment,
+                status: 2
+              };
+              arr.push(scoredata);
+            }
+          });
+        }
+      });
+      return arr;
+    },
+    // 数据初始化,没有值或者空数组的显示-
+    initData(str) {
+      if (str == null) {
+        return str || null;
+      }
+      if (typeof str === 'object') {
+        return str.length > 0 ? str : null;
+      } else {
+        return str || null;
+      }
+    },
+    indexType(item) {
+      return item == 1 ? '量化指标' : item == 2 ? '非量化指标' : item == 3 ? '额外加分项' : item == 4 ? '额外扣分项' : '';
+    },
+    // 评分-文本框失去焦点时触发
+    watresultval(val, totalScore) {
+      if (totalScore) {
+        this.gradeval = this.fomatFloat(val, 2);
+      } else {
+        let tPoints = [];
+        this.inExecution.forEach(item => {
+          if (item.resultval) {
+            tPoints.push({
+              score: item.resultval, // 分值
+              d_weight: item.dimension_weight, // 维度权重
+              weight: item.weight, // 指标权重
+              type: item.type // 所属指标种类 1-量化指标 2-行为价值观指标 3-额外加分项 4-额外扣分项
+            });
+          }
+        });
+        this.gradeval = this.fomatFloat(this.totalPointsCount(tPoints), 2);
+      }
+      this.isShowPoint = true;
+    },
+    // 计算总分
+    totalPointsCount(data) {
+      let ct = this.empDetList.calc_type; // 1-加和计算 2-加权计算
+      let cd = this.empDetList.calc_dimension; // 是否维度权重参与计算 1-是 0-否
+      let num = 0;
+      data.forEach(item => {
+        if (item.score) {
+          if (item.type == 3) {
+            // 3-额外加分项
+            num += Number(item.score);
+          } else if (item.type == 4) {
+            // 4-额外扣分项    不计算
+            num -= Number(item.score);
+          } else {
+            if (ct == 1 && cd == 0) {
+              // 加和
+              num += Number(item.score);
+            } else if (ct == 1 && cd == 1) {
+              // 加和--维度权重参与计算
+              num += Number(item.score) * Number(item.d_weight / 100);
+            } else if (ct == 2 && cd == 0) {
+              // 加权
+              num += Number(item.score) * Number(item.weight / 100);
+            } else if (ct == 2 && cd == 1) {
+              // 加权--维度权重参与计算
+              num += Number(item.score) * Number(item.d_weight / 100) * Number(item.weight / 100);
+            }
+          }
+        }
+      });
+      return num;
+    },
+    fomatFloat(src, pos) {
+      return Math.round(src * Math.pow(10, pos)) / Math.pow(10, pos);
+    },
+    // e当前行 ,item用于判断当前输入是否超过评分上限
+    sgradeInp(item) {
+      if (item) {
+        if (item.type == 3 || item.type == 4) {
+          if (item.point_limit) {
+            if (item.resultval > Number(item.point_limit)) {
+              this.$toast.fail('评分超过上限');
+              item.resultval = '';
+              return false;
+            }
+          }
+        }
+      }
+    },
+    gradeClick() {
+      // 评分
+      this.graded = true;
+      let dnsion = [];
+      this.inExecution.forEach(item => {
+        if (item.employee_id == this.userInfo.id && item.flowId == this.smdsinsFlow) {
+          dnsion.push(item);
+        }
+      });
+      let totalScore = {
+        theDimension: '总分',
+        wdLeg: 0,
+        totalScore: true
+      };
+      this.perfstepFlow.forEach(item => {
+        if (item.code == 'score_supervisor' && item.status == 1) {
+          this.ruleScore = item.rule == 2 ? 2 : 1; // 1-指标均要评分 2-评分总结
+          this.thecurrentFlow = 'score_supervisor';
+          totalScore.codeId = item.id;
+        } else if (item.code == 'special_scorer' && item.status == 1) {
+          this.ruleScore = 1;
+        }
+        if ((item.code == 'score_supervisor' && item.status == 1) || (item.code == 'special_scorer' && item.status == 1)) {
+          // 上级评分,特定评分     评分人必填项
+          item.action.forEach(arr => {
+            this.mandatoryScore = arr == 'comment'; // 指标说明是否必填
+          });
+        }
+      });
+      // 总分
+      this.scoreInfo.forEach(item => {
+        item.employees.forEach(arr => {
+          if (arr.employee_id == this.userInfo.id) {
+            this.gradeval = arr.point ? arr.point : 0;
+            if (item.id == totalScore.codeId && this.ruleScore == 2) {
+              totalScore.resultval = arr.point;
+              totalScore.remarks = arr.comment ? arr.comment : '';
+            }
+          }
+        });
+      });
+      let dimenList = [];
+      let users = []; // 当前节点的自己的信息
+      this.perfstepFlow.forEach(item => {
+        // 根据流程当前节点,找节点的人员中的登陆者
+        if (item.status == 1) {
+          item.target.some(arr => {
+            if (arr.employee_id == this.userInfo.id) {
+              arr.flowStatusId = item.id; // 当前节点的ID
+              users = arr;
+              return true;
+            }
+          });
+        }
+      });
+      users.list.forEach(att => {
+        // 获取当前节点审批人员中的登陆者
+        dnsion.forEach(add => {
+          if (att.index_id == add.id && att.dimension_key == add.planIndex[0] && att.index_key == add.planIndex[1]) {
+            add.dimension_key = att.dimension_key; // 维度索引
+            add.index_key = att.index_key; // 指标索引
+            if(add.type==1){
+              add.expressionStr=getExpressionStr(add.expression)
+            }else{
+              add.expressionStr=''
+            }
+            add.score_infos.forEach(user => {
+              // 显示的文案,找到当前登录人
+              if (user.id == users.flowStatusId) {
+                if (user.employee_id == this.userInfo.id) {
+                  this.scoreTab.title = user.title;
+                  this.scoreTab.explain = user.title.split(':')[0] + '说明';
+                }
+              }
+            });
+            dimenList.push(add);
+          }
+        });
+      });
+      this.scoreInfo.forEach(item => {
+        item.employees.forEach(arr => {
+          if (arr.employee_id == this.userInfo.id) {
+            this.gradeval = arr.point ? arr.point : 0;
+            if (item.id == totalScore.codeId && this.ruleScore == 2) {
+              totalScore.resultval = arr.point;
+              totalScore.remarks = arr.comment ? arr.comment : '';
+            }
+          }
+        });
+      });
+      this.perfstepFlow.forEach(item => {
+        if (item.code == 'score_supervisor' && item.status == 1 && this.ruleScore == 2) {
+          dimenList.push(totalScore);
+        }
+      });
+      this.$nextTick(() => {
+        this.inExecution = dimenList;
+      });
+    },
+    scoreClone() {
+      this.graded = false;
+      this.skeletonLoad = true;
+      this.employeeDet();
+    },
+    // 评分取消
+    scorerveno() {
+      this.$dialog
+        .confirm({
+          title: '暂存',
+          message: '是否暂存当前页面内容?'
+        })
+        .then(() => {
+          this.scorerveok(0);
+        })
+        .catch(() => {
+          this.scoreClone();
+        });
+    },
+    scorerveok(num) {
+      let data = {
+        id: this.employeeID, // 个人考核包ID
+        is_submit: num, // 是否提交 0否(暂存) 1 是
+        node_id: this.smdsinsFlow // 当前节点
+      };
+      let point_info = []; // 各项评分数据
+      let sumData = {
+        // 总分数据
+        total_score: '',
+        total_score_comment: ''
+      };
+      this.inExecution.forEach(item => {
+        let resultInfo = {};
+        if (this.ruleScore == 1 && !item.totalScore) {
+          // 各项评分
+          resultInfo = {
+            // 评分信息--只评总分不需要
+            score: item.resultval ? item.resultval : '', // 单项目结果值
+            score_remark: item.remarks,
+            dimension_key: item.dimension_key, // 维度索引
+            index_key: item.index_key, // 指标索引
+            index_id: item.id, // 指标ID
+            name: item.name,
+            // 用于计算分数
+            d_weight: item.dimension_weight, // 维度权重
+            weight: item.weight, // 指标权重
+            type: item.type // 所属指标种类 1-量化指标 2-行为价值观指标 3-额外加分项 4-额外扣分项
+          };
+          point_info.push(resultInfo);
+        } else {
+          // 等于2:只评总分
+          if (item.totalScore) {
+            sumData = {
+              total_score: item.resultval ? item.resultval : '',
+              total_score_comment: item.remarks
+            };
+          }
+        }
+      });
+      let isMust = true,
+        isExplain = true; // isMust验证评分,isExplain验证说明
+      if (num == 1) {
+        // 提交验证必填
+        if (this.ruleScore == 1) {
+          // 各项评分
+          point_info.forEach(item => {
+            if (this.mandatoryScore) {
+              // 评分说明必填
+              if (!item.score_remark) {
+                isExplain = false;
+              }
+            }
+            if (item.score===null||item.score===undefined||item.score==='') {
+              isMust = false;
+            }
+          });
+          if (!isMust) {
+            this.$toast('请输入所有评分');
+            return false;
+          }
+          if (!isExplain) {
+            this.$toast('请输入所有评分说明');
+            return false;
+          }
+        } else {
+          // 总分
+          if (!sumData.total_score) {
+            this.$toast('请输入评分总分');
+            return false;
+          }
+          if (this.mandatoryScore) {
+            if (!sumData.total_score_comment) {
+              this.$toast('请输入总分说明');
+              return false;
+            }
+          }
+        }
+      }
+      if (this.ruleScore == 1) {
+        data.total_score = this.fomatFloat(this.totalPointsCount(point_info), 2); // 计算的个人评出的总分(保留小数后两位)
+      } else {
+        data.total_score = this.fomatFloat(sumData.total_score, 2); // 计算的个人评出的总分(保留小数后两位)
+        data.total_score_comment = sumData.total_score_comment;
+      }
+      data.point_info = JSON.stringify(point_info); // 评分信息 --  填所有评分时必须的字段(传入某指标的分数、说明、维度索引、制表索引、指标ID)
+      if (this.bootBool) {
+        return;
+      }
+      let pointList = JSON.parse(JSON.stringify(point_info));
+      pointList.push({
+        name: '总分',
+        score: data.total_score,
+        score_remark: data.total_score_comment
+      });
+      this.pointList = pointList;
+      this.pointData = data;
+      if (this.ruleScore == 1) {
+        //只评总分不需要弹窗
+        this.isPoint = true;
+      } else {
+        this.score();
+      }
+    },
+    score() {
+      this.$axiosUser('post', '/api/pro/per/package/submit_score', this.pointData).then(res => {
+        this.$toast.success('提交成功');
+        this.bootBool = false;
+        this.isPoint = false;
+        this.graded = false;
+        this.employeeDet();
+      });
+    },
+    gradeTurn() {
+      this.rejectval = '';
+      this.rejectval1 = '';
+      this.selectpradio = '';
+      this.selectpradio1 = '';
+      this.rejectProp = false;
+      this.rejectData = {};
+      let list = [];
+      this.perfstepFlow.forEach((item, index) => {
+        if (item.status == 2 && item.code != 'execution' && item.code != 'cc' && item.target.length != 0) {
+          let arr = {};
+          arr.id = item.id;
+          arr.name = item.remark;
+          item.target.forEach((att, aoo) => {
+            arr.name += att.employee_name;
+            arr.name += item.target.length - aoo > 1 ? ',' : '';
+          });
+          arr.staff = item.target;
+          list.push(arr);
+        }
+      });
+      this.rejectList = list;
+      this.popupknowFrom = 1;
+      this.commFeedback = '';
+      this.communication = true;
+    },
+    // 审批同意
+    gradeOk() {
+      if (this.flowNow.code == 'confirm') {
+        // 驳回
+        this.popupknowFrom = 3;
+      } else if (this.flowNow.code == 'review') {
+        // 审批
+        this.popupknowFrom = 2;
+      }
+      this.commFeedback = '';
+      this.communication = true;
+    },
+    // 选人
+    confirm(data) {
+      let item = data.employee[0];
+      let employeeId = this.careOfPeopleId.length == 1 ? this.careOfPeopleId[0].employee_id : this.zjId;
+      this.$dialog.confirm({ title: '转交', message: '确认转交:' + item.name + '?' }).then(() => {
+        let data = {
+          id: this.employeeID, // 个人考核记录ID
+          node_id: this.flowNow.id, // 节点ID
+          to_employee_id: item.id, // 接收用户ID
+          from_employee_id: employeeId // 转出用户ID
+        };
+        this.$axiosUser('post', '/api/pro/per/package/transfer', data).then(res => {
+          if (res.data.code == 1) {
+            this.$toast.success('转交成功');
+            this.employeeDet();
+          }
+        });
+      });
+    },
+    // 打开执行计划
+    openPlan(index) {
+      this.planIndex = index;
+      this.openTrackPath('action');
+    },
+    // 打开管理记录
+    openTrack(index) {
+      this.planIndex = index;
+      this.openTrackPath('admnin');
+    },
+
+    // 管理记录||执行计划
+    openTrackPath(add) {
+      let data = {
+        know: add,
+        apList: this.apList,
+        packId: this.employeeID,
+        assessID: this.Information.id,
+        planIndex: this.planIndex,
+        recordMemberIds: this.recordMemberIds
+      };
+      this.$setCache('actionplanList', data);
+      this.$router.push({ name: 'actionplanList' });
+    },
+    // 指标详情
+    openPlanPath(apList, add) {
+      this.logList = add == 'action' ? apList.schedule : apList.mamage_record;
+      this.logText = add == 'action' ? '执行计划' : '管理记录';
+      this.apDetails = apList;
+      this.isShowText = true;
+    },
+    unfold() {
+      // 展开记录
+      this.recordList = this.recordAllList;
+    },
+    packUp() {
+      // 收起记录
+      let listtre = [];
+      this.recordAllList.forEach((item, index) => {
+        if (index < 3) {
+          listtre.push(item);
+        }
+      });
+      this.recordList = listtre;
+    },
+    communicate() {
+      this.popupknowFrom = 0;
+      this.commFeedback = '';
+      this.communication = true;
+    },
+    turndown() {
+      // 驳回
+      this.popupknowFrom = 1;
+      this.commFeedback = '';
+      this.communication = true;
+    },
+    enteringResult() {
+      // 录入结果值
+      this.$router.push({
+        name: 'resultValueEntry',
+        query: { id: this.employeeID, packageName: this.detailsTIt,resultStr:this.resultStr }
+      });
+    },
+    commcliButon() {
+      // 沟通弹窗取消按钮
+      this.communication = false;
+    },
+    commcliButok() {
+      // 沟通弹窗确定按钮
+      if (this.popupknowFrom == 0) {
+        // 沟通
+        if (!this.commFeedback) {
+          this.$toast('请输入沟通内容');
+          return false;
+        }
+        let target_id = this.emtags.map(item => {
+          return item.id;
+        });
+        this.$axiosUser('post', '/api/pro/per/package/negotiation', {
+          id: this.employeeID,
+          content: this.commFeedback,
+          target_id: JSON.stringify(target_id)
+        }).then(res => {
+          this.$toast.success('已沟通');
+          this.employeeDet();
+          this.communication = false;
+        });
+      } else if (this.popupknowFrom == 1) {
+        // 驳回
+        this.agree0Prop(0); // 审批驳回、目标确认驳回
+      } else if (this.popupknowFrom == 2 || this.popupknowFrom == 3) {
+        this.agree0Prop(1); // 审批同意、目标确认同意
+      } else if (this.popupknowFrom == 4) {
+        this.revocation();
+      }
+    },
+    // 撤销
+    revocation() {
+      let params = {
+        id: this.employeeID,
+        node_id: this.revocationNodeId,
+        comment: this.commFeedback
+      };
+      this.$axiosUser('post', '/api/pro/per/package/revoke', params)
+        .then(res => {
+          if (res.data.code == 1) {
+            this.$toast.success('撤销成功');
+            this.employeeDet();
+          }
+        })
+        .finally(() => {
+          this.communication = false;
+        });
+    },
+    agree0Prop(num) {
+      let data = {
+        id: this.employeeID, // 个人考核包ID
+        agree: num, // 同意1    驳回0
+        c_node_id: this.flowNow.id // 当前节点ID
+      };
+      if (num == 0) {
+        if (!this.commFeedback) {
+          this.$toast('请输入驳回内容');
+          return false;
+        }
+        if (!this.rejectData.node_id) {
+          this.$toast('请选择驳回节点!');
+          return false;
+        }
+        if (!this.rejectData.employee_id) {
+          this.$toast('至少选择一名重置人员!');
+          return false;
+        }
+        data.employee_id = JSON.stringify(this.rejectData.employee_id);
+        data.node_id = this.rejectData.node_id;
+      }
+      if (this.commFeedback) {
+        data.comment = this.commFeedback; // 审核意见
+      }
+      this.$axiosUser('post', '/api/pro/per/package/review', data).then(res => {
+        this.$toast.success('提交成功');
+        this.employeeDet();
+        this.communication = false;
+      });
+    },
+    confirmCreator(data) {
+      this.emtags = data.employee;
+    },
+    clickreject(item) {
+      this.rejectList1 = [];
+      this.rejectData = {};
+      this.rejectval = item.name;
+      if (item.staff.length > 1) {
+        this.rejectList1.push({ employee_id: 0, employee_name: '全部人员' });
+        item.staff.forEach(item => {
+          if (item.status == 2) {
+            this.rejectList1.push(item);
+          }
+        });
+        this.rejectProp = true;
+      } else {
+        this.rejectData.employee_id = [item.staff[0].employee_id];
+        this.rejectProp = false;
+      }
+      this.rejectData.node_id = item.id;
+      this.rejectdlg = false;
+    },
+    clickreject1(item) {
+      this.rejectval1 = item.employee_name;
+      if (item.employee_id == 0) {
+        let arr = [];
+        this.rejectList1.forEach(aoo => {
+          if (aoo.employee_id && aoo.employee_id != 0) {
+            arr.push(aoo.employee_id);
+          }
+        });
+        this.rejectData.employee_id = arr;
+      } else {
+        this.rejectData.employee_id = [item.employee_id];
+      }
+      this.rejectdlg1 = false;
+    },
+    setUpD() {
+      this.headuDown[0] = {};
+      this.headuDown[1] = {};
+      let pendingList = this.pendingList;
+      pendingList.some((item, index) => {
+        if (this.employeeID == item.employeeID) {
+          this.detailsTIt = item.package_name;
+          this.$route.query.id = item.employeeID;
+          if (pendingList[index - 1]) {
+            this.headuDown[0] = {
+              keys: 1,
+              keys1: '上一个',
+              keys2: '<',
+              name: pendingList[index - 1].name,
+              id: pendingList[index - 1].employeeID,
+              package_id:pendingList[index - 1].package_id,
+            };
+          }
+          if (pendingList[index + 1]) {
+            this.headuDown[1] = {
+              keys: 2,
+              keys1: '下一个',
+              keys2: '>',
+              name: pendingList[index + 1].name,
+              id: pendingList[index + 1].employeeID,
+              package_id:pendingList[index + 1].package_id,
+            };
+          }
+          if (index == pendingList.length - 2 && pendingList.length >= 10) {//如果当点击到待办人员的倒数第二个,加载剩余的
+            this.getAgency();
+          }
+          return true;
+        }
+      });
+    },
+    uDownCli(data) {
+      if (data.id=='结果') {
+          this.isDetails=false;
+          this.headuDown[0] = {};
+          this.headuDown[1] = {};
+          let pendingList = this.pendingList;
+          pendingList.some((item, index) => {
+            if (item.package_id&&item.package_id ==data.package_id) {
+              this.pe_ids=JSON.stringify(item.pe_ids);
+              this.detailsTIt = item.package_name;
+              if (pendingList[index - 1]) {
+                this.headuDown[0] = {
+                  keys: 1,
+                  keys1: '上一个',
+                  keys2: '<',
+                  name: pendingList[index - 1].name,
+                  id: pendingList[index - 1].employeeID,
+                  package_id:pendingList[index - 1].package_id,
+                };
+              }
+              if (pendingList[index + 1]) {
+                this.headuDown[1] = {
+                  keys: 2,
+                  keys1: '下一个',
+                  keys2: '>',
+                  name: pendingList[index + 1].name,
+                  id: pendingList[index + 1].employeeID,
+                  package_id:pendingList[index + 1].package_id,
+                };
+              }
+              if (index == pendingList.length - 2 && pendingList.length >= 10) {//如果当点击到待办人员的倒数第二个,加载剩余的
+                this.getAgency();
+              }
+              return true;
+            }
+          });
+      }else{
+        if(data.id){
+          this.$route.query.id = data.id;
+          this.isDetails=true;
+          this.employeeID = data.id;
+          this.skeletonLoad = true;
+          this.employeeDet();
+        }
+      }
+    }
+  },
+  created() {
+    // 沟通,跳转
+    if (document.documentElement.style.height) {
+      this.com_height = document.documentElement.style.height;
+    }
+  },
+  activated() {
+    // 是否显示上下人
+    if (this.$route.query.pendingList && this.$route.query.pendingList.length != 0) {
+      this.pendingList = JSON.parse(this.$route.query.pendingList);
+      this.isDisabled = true;
+      this.activeName = this.$route.query.activeName;
+      this.page = this.$route.query.page || 1;
+    } else {
+      this.isDisabled = false;
+      this.activeName = '';
+    }
+    this.skeletonLoad = true;
+    this.$nextTick(() => {
+      this.detailsTIt = this.$route.query.Tit;
+    });
+    if(this.$route.query.pe_ids){//结果值点击进来
+       this.isDetails=false;
+       this.headuDown[0] = {};
+       this.headuDown[1] = {};
+       let pendingList = JSON.parse(this.$route.query.pendingList);
+       pendingList.some((item, index) => {
+         if (item.package_id&&item.package_id ==this.$route.query.package_id) {
+           this.pe_ids=this.$route.query.pe_ids;
+           this.isUpdate=this.$route.query.isUpdate? true:false;
+           if (pendingList[index - 1]) {
+             this.headuDown[0] = {
+               keys: 1,
+               keys1: '上一个',
+               keys2: '<',
+               name: pendingList[index - 1].name,
+               id: pendingList[index - 1].employeeID,
+               package_id:pendingList[index - 1].package_id,
+             };
+           }
+           if (pendingList[index + 1]) {
+             this.headuDown[1] = {
+               keys: 2,
+               keys1: '下一个',
+               keys2: '>',
+               name: pendingList[index + 1].name,
+               id: pendingList[index + 1].employeeID,
+               package_id:pendingList[index + 1].package_id,
+             };
+           }
+           if (index == pendingList.length - 2 && pendingList.length >= 10) {//如果当点击到待办人员的倒数第二个,加载剩余的
+             this.getAgency();
+           }
+           return true;
+         }
+       });
+    }else{
+        this.employeeDet();
+    }
+    if (this.$route.query.paths && this.$route.query.data) {
+      let data = JSON.parse(this.$route.query.data);
+      this.$axiosUser('post', '/api/pro/per/package/msg/cc', data).then(res => {});
+    }
+  }
+};
+</script>
+
+<style scoped lang="less">
+  .okr-tips {
+    position: absolute;
+    top: 0;
+    right: 0;
+    height: 0.38rem;
+    font-size: 0.27rem;
+    padding: 0.1rem 0.25rem;
+    border-top-left-radius: 0.05rem;
+    border-bottom-left-radius: 0.05rem;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    color: #26a2ff;
+    background-color: #ecf5ff;
+  }
+
+.apdList {
+  background-color: #fff;
+}
+.apdData {
+  width: 88%;
+  padding: 0.1rem 0;
+  margin: 0 0.3rem 0 0.2rem;
+  border-bottom: 1px solid rgb(240, 240, 240);
+}
+.apdDian {
+  position: relative;
+  width: 0.25rem;
+  height: 0.25rem;
+  border-radius: 50%;
+  background-color: #d4d4d4;
+}
+.apdHeadBoeder {
+  position: absolute;
+  left: 0.11rem;
+  height: 100%;
+  width: 0.02rem;
+  border-left: 0.02rem solid #d4d4d4;
+}
+.apdborderNO {
+  border: 0 !important;
+}
+.apdListMarTop {
+  margin: 0.15rem 0 0rem 0;
+  background-color: #fff;
+}
+
+.vassheet {
+  margin-bottom: 1rem;
+  min-height: 6rem;
+  .vasHead {
+    background-color: #fff;
+    text-align: center;
+    padding: 0.2rem;
+    i {
+      right: 0.3rem;
+      top: 0.32rem;
+      position: absolute;
+    }
+    i ::active{
+      content:"";
+      position:absolute;
+      top:-10px;
+      right:-10px;
+      bottom:-10px;
+      left:-10px;
+    }
+    span {
+      font-size: 0.32rem;
+    }
+  }
+  .pullUpdel {
+    margin: 0.15rem 0 6rem 0;
+    padding: 0.25rem;
+    background-color: #ffffff;
+    .intro {
+      span {
+        display: inline-block;
+        padding: 0.05rem 0;
+      }
+      .introcol {
+        color: rgb(171, 171, 171);
+      }
+      .intropad {
+        padding: 0.1rem 0;
+      }
+    }
+  }
+}
+
+.guidang {
+  width: 60px;
+  animation: example 1s;
+  height: 35px;
+  margin-left: 10px;
+}
+@keyframes example {
+  from {
+    transform: scale(1.4);
+  }
+  to {
+    transform: scale(1);
+  }
+}
+/deep/ .upDownList {
+  z-index: 1;
+  padding: 0.2rem 0;
+  box-shadow: 0 0.05rem 0.15rem 0.01rem #efefef;
+  position: relative;
+  background-color: #fff;
+  .uDownBut {
+    border: 0.02rem solid #e4e4e4;
+    font-size: 0.26rem;
+    width: 2.3rem;
+    padding: 0.1rem 0.1rem;
+    margin: 0 0.3rem;
+    color: #378df9e8;
+    text-align: center;
+    border-radius: 0.05rem;
+  }
+}
+.pre {
+  margin: 0 !important;
+  font-family: 微软雅黑;
+  white-space: pre-wrap; /*css-3*/
+  white-space: -moz-pre-wrap; /*Mozilla,since1999*/
+  white-space: -pre-wrap; /*Opera4-6*/
+  white-space: -o-pre-wrap; /*Opera7*/
+  word-wrap: break-word; /*InternetExplorer5.5+*/
+  background-color: #f6f6f6;
+  padding: 0.1rem 0.2rem;
+}
+.pre2 {
+  margin: 0 !important;
+  font-family: 微软雅黑;
+  white-space: pre-wrap; /*css-3*/
+  white-space: -moz-pre-wrap; /*Mozilla,since1999*/
+  white-space: -pre-wrap; /*Opera4-6*/
+  white-space: -o-pre-wrap; /*Opera7*/
+  word-wrap: break-word; /*InternetExplorer5.5+*/
+}
+.bian::after {
+  content: '';
+  position: absolute;
+  width: 1px;
+  top: 0.5rem;
+  left: 0.21rem;
+  bottom: 0;
+  border-right: 1px dashed #ccc;
+  height: 100%;
+}
+.isIos {
+  padding-bottom: 0.4rem !important;
+}
+/deep/ .overall {
+  // width: 100%;
+  // width: 7.49rem;
+  height: calc(100% - 1.92rem) !important;
+  position: relative;
+  overflow-y: scroll;
+  // overflow-y: auto;
+  // overflow-x: hidden;
+  // display: inline-block;
+}
+header {
+  font-size: 0.31rem;
+  background-color: #fff;
+  padding: 0.3rem 0 0.3rem 0.3rem;
+  font-size: 0.3rem;
+  z-index: 1;
+  box-sizing: border-box;
+  .pdHeadDept {
+    color: rgb(117, 117, 117);
+    padding-top: 0.03rem;
+    font-size: 0.25rem;
+  }
+}
+.backlog_list_tit {
+  background-color: #f5f7fa;
+  padding: 0.2rem 0 0.2rem 0.2rem;
+  font-size: 0.28rem;
+}
+.backlog_list {
+  padding: 0.32rem 0.45rem;
+  span {
+    padding-left: 0.25rem;
+    font-size: 0.29rem;
+  }
+}
+.arrow::-webkit-scrollbar,
+.overall::-webkit-scrollbar {
+  //隐藏滚动条
+  width: 0px;
+  height: 0px;
+}
+.arrow {
+  position: relative;
+  width: 7.17rem;
+  overflow-x: auto;
+  white-space: nowrap;
+  padding-right: 1rem;
+  div {
+    position: relative;
+    display: inline-block;
+    margin-right: 0.12rem;
+    box-shadow: 0 0.06rem 0.1rem -0.07rem #828282;
+    .diamondo {
+      background-color: #e8e8e8;
+      max-height: 0.42rem;
+      font-size: 0.26rem;
+      border-top-left-radius: 0.04rem;
+      border-bottom-left-radius: 0.04rem;
+      padding: 0.13rem 0.2rem 0.1rem 0.5rem;
+      display: inline-block;
+      i {
+        color: rgb(43, 117, 255);
+        // position: absolute;
+        margin-left: 0.12rem;
+      }
+      .arrowdetails {
+        max-width: 4.5rem;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        display: inline-block;
+      }
+      .arrowdetails1 {
+        padding-left: 0.25rem;
+      }
+      .flowPadd {
+        padding-right: 0.2rem;
+      }
+    }
+    .diamondo1 {
+      padding: 0.13rem 0.2rem 0.1rem 0.3rem;
+    }
+
+    .diamondTzj,
+    .diamondTyj {
+      border-width: 0.33rem;
+      border-style: solid;
+      border-color: transparent transparent transparent #ffffff;
+      display: inline-block;
+      position: absolute;
+    }
+    .diamondTyj {
+      border-color: transparent transparent transparent #e8e8e8;
+      z-index: 1;
+    }
+  }
+  .active {
+    .diamondo {
+      background-color: #ccdffb;
+      color: #1d96ff;
+    }
+    .diamondTzj {
+    }
+    .diamondTyj {
+      border-color: transparent transparent transparent#ccdffb;
+    }
+  }
+}
+
+.managementRecord,
+.sidebar {
+  height: 0.38rem;
+  position: fixed;
+  right: 0px;
+  font-size: 0.27rem;
+  padding: 0.1rem 0.25rem;
+  border-top-left-radius: 0.05rem;
+  border-bottom-left-radius: 0.05rem;
+  display: flex;
+  color: #26a2ff;
+  background-color: #ecf5ff;
+  i {
+    // margin: 0.05rem 0.15rem 0 0;
+    margin-right: 0.15rem;
+    color: #26a2ff;
+  }
+}
+.managementRecord {
+  top: 66%;
+}
+.sidebar {
+  top: 71%;
+}
+.isdeliveryRecord_icon {
+  width: 0.28rem;
+  padding-right: 0.15rem;
+}
+/deep/ .footerBut {
+  position: fixed;
+  left: 0px;
+  bottom: 0px;
+  width: 100%;
+  background-color: #ffffff;
+  z-index: 999;
+  .footweight {
+    padding: 0.15rem 0 0.15rem 0.3rem;
+    background-color: #deeeff;
+    font-size: 0.27rem;
+    color: #1d96ff;
+  }
+  .footfoot {
+    padding: 0.1rem;
+    .footcol {
+      text-align: center;
+    }
+    .footcolBut {
+      border: 0;
+      width: 2rem;
+      height: 0.8rem;
+      font-size: 0.28rem;
+      color: #fff;
+      background-color: #42a8ff;
+      border-radius: 3px;
+    }
+
+    .footBut {
+      display: flex;
+    }
+    .gradefootcolButok {
+      width: 2.8rem;
+      height: 0.8rem;
+      font-size: 0.28rem;
+      border: 0;
+      color: #fff;
+      background-color: #42a8ff;
+      border-radius: 3px;
+    }
+    .footcolButno,
+    .footcolButok {
+      width: 1.4rem;
+      height: 0.8rem;
+      font-size: 0.28rem;
+    }
+    .footcolButno {
+      border: 1px solid #42a8ff;
+      color: #2f9eff;
+      background-color: #ffffff;
+      border-top-left-radius: 3px;
+      border-bottom-left-radius: 3px;
+    }
+    .footcolButok {
+      border: 0;
+      color: #fff;
+      background-color: #42a8ff;
+      border-top-right-radius: 3px;
+      border-bottom-right-radius: 3px;
+    }
+  }
+}
+
+.commButt {
+  position: fixed;
+  left: 0px;
+  bottom: 0px;
+  width: 100%;
+  background-color: #ffffff;
+  z-index: 999;
+  text-align: center;
+  border-top: 1px solid #dedede;
+  .commButtno {
+    border-radius: 0.1rem;
+    width: 3.2rem;
+    height: 0.9rem;
+    border: 0;
+    font-size: 0.3rem;
+    color: #464646;
+    background-color: #f3f3f3;
+    text-align: center;
+    margin: 0.2rem 0.07rem;
+    line-height: 0.9rem;
+    border: 1px solid #d6d6d6;
+  }
+  .commButtok {
+    border-radius: 0.1rem;
+    width: 3.2rem;
+    height: 0.9rem;
+    border: 0;
+    font-size: 0.3rem;
+    color: #fff;
+    background-color: #4498ef;
+    text-align: center;
+    margin: 0.2rem 0.07rem;
+    line-height: 0.9rem;
+    border: 1px solid #36a2ff;
+  }
+}
+
+.modTit {
+  background-color: #efefef;
+  padding: 0.27rem 0.3rem 0.15rem;
+  font-size: 0.28rem;
+  color: #8a8a8a;
+}
+.modCont {
+  padding: 0.3rem;
+  background-color: #fff;
+}
+.stanif {
+  .stanTit {
+    font-size: 0.26rem;
+    color: #222;
+    margin: 0.2rem 0 0.08rem 0;
+  }
+  .standara {
+    border: 1px solid #efefef;
+    border-radius: 5px;
+    .standarapad {
+      display: inline-block;
+      padding: 0.2rem;
+      font-size: 0.27rem;
+    }
+  }
+}
+.tab-List {
+  display: inline-block;
+  padding: 0.05rem 0.15rem;
+  background-color: #fdf6ec;
+  color: #ff9600;
+  font-size: 0.25rem;
+  margin-right: 0.1rem;
+  border-radius: 0.01rem;
+}
+.flexPopover {
+  padding: 0.25rem;
+  background-color: #fff;
+  .flex_one {
+    width: 100%;
+    height: 0.8rem;
+    font-size: 0.3rem;
+    border-radius: 1px;
+    background-color: #26a2ff;
+    color: #fff;
+    align-items: center;
+    div:nth-child(1) {
+      max-width: 80%;
+      padding: 0 0 0 0.2rem;
+    }
+    div:nth-child(2) {
+      padding: 0 0.2rem 0 0;
+    }
+  }
+}
+.aite {
+  padding: 0.2rem;
+  font-size: 0.36rem;
+  cursor: pointer;
+  position: absolute;
+  top: -0.8rem;
+  //   width: 40px;
+}
+
+.employee_selector_popup {
+  height: 100%;
+  width: 100%;
+}
+
+.flexDiaWb {
+  max-height: 7rem;
+  overflow-y: auto;
+  overflow-x: hidden;
+  margin: 0.4rem 0;
+  padding: 0 0.2rem 0 0.3rem;
+  .flexDiaLL {
+    padding: 0 0 0.5rem 0;
+    position: relative;
+    .fdz {
+      display: flex;
+      .fdYuan {
+        width: 0.45rem;
+        height: 0.45rem;
+        border-radius: 50%;
+        z-index: 1;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+      .fdYuan1 {
+        background-color: rgb(80, 168, 255);
+        color: #fff;
+      }
+      .fdYuan2 {
+        background-color: rgb(80, 168, 255);
+        color: #fff;
+      }
+      .fdYuan3 {
+        background-color: #ccc;
+      }
+      .fdShu {
+        width: 0.02rem;
+        height: 100%;
+        background-color: #ccc;
+        /* text-align: center; */
+        position: absolute;
+        top: 0;
+        left: 0.22rem;
+      }
+      /deep/ .fdShu1 {
+        background-color: rgb(80, 168, 255);
+      }
+    }
+    .fdy {
+      display: flex;
+      // flex-wrap: wrap;
+      padding-left: 0.2rem;
+      font-size: 0.3rem;
+    }
+    .fdyBlue {
+      color: #0099ff;
+    }
+  }
+}
+</style>

+ 782 - 0
src/performance-07-19/components/performanceDetails.vue

@@ -0,0 +1,782 @@
+<template>
+  <div class="all" :class="[{ bg_fff: skeletonLoad }]">
+    <van-nav-bar :title="'待办处理 - ' + dialogTitle" left-arrow @click-left="routerBak">
+      <!-- <div slot="right" @click="isShowPopup = true" style="color: #fff;">...</div> -->
+    </van-nav-bar>
+    <div class="scroller">
+      <scroller ref="scroller_com">
+        <div v-if="detailInfo">
+          <div class="title flex-box-ce" style="justify-content: space-between;">
+            <div>考核基础信息</div>
+            <div class="blue" @click="goDetails()">处理详情</div>
+          </div>
+
+          <div class="user-info-box">
+            <div class="flex-box-ce"style="margin-bottom: 0.2rem;">
+              <userImage class="about-me__avatar" :id="detailInfo.userInfo.id" :img_url="detailInfo.userInfo.img_url"  :user_name="detailInfo.userInfo.name"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+              <div class="user-info">
+                <div style="margin-bottom: 0.05rem; color: #000;">{{ detailInfo.userInfo.name }}</div>
+                <template v-if="detailInfo.deptList && detailInfo.deptList.length > 0">
+                  <span v-for="item in detailInfo.deptList" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
+                </template>
+              </div>
+            </div>
+            <div class="info-item flex-box-ce">考核周期: &nbsp;&nbsp;<div class="cycle-type">{{ detailInfo.cycleType | formatCycleType }}</div></div>
+            <div class="info-item">考核时间: &nbsp;&nbsp;{{ detailInfo.startTime | formatDate }} 至 {{ detailInfo.endTime | formatDate }}</div>
+          </div>
+
+         <div class="title" >
+           指标基础信息
+         </div>
+
+         <div class="user-info-box">
+           <div class="info-item">指标: {{ detailInfo.title }}</div>
+           <div class="info-item">目标值: {{ detailInfo.target }}</div>
+           <div class="info-item">权重: {{ detailInfo.weight }}</div>
+           <div class="info-item">单位: {{ detailInfo.unit }}</div>
+           <div class="info-item">指标规则: {{ detailInfo.content }}</div>
+           <div class="info-item">结果值: {{ detailInfo.result || '-' }}</div>
+           <div class="info-item">最终评分: {{ detailInfo.score || '-' }}</div>
+         </div>
+
+        </div>
+
+        <!-- 操作日志 -->
+        <OperateLogVue v-if="reviewId" :reviewId="reviewId" :reviewIndicatorId="reviewIndicatorId"/>
+
+        <div style="width: 100%; height: 1rem;">
+
+        </div>
+
+      </scroller>
+    </div>
+
+
+    <footer class="footer" v-if="type === 'entering'">
+      <div class="flex-box-ce">
+        <div class="btn flex-1" @click="isShowHandle = true">操 作</div>
+      </div>
+    </footer>
+
+
+
+
+    <!-- 操作弹框 -->
+    <van-popup v-model:show="isShowHandle" round position="bottom" :style="{ height: '70%' }">
+      <div class="content" style="">
+        <header class="flex-box-ce" style="text-align: center; font-size: 0.32rem; padding: 0.2rem;">
+          <div class="fontColorC" @click="isShowHandle = false">取消</div>
+          <div class="flex-1" style="font-weight: 600;font-size: 0.32rem;">{{ dialogTitle }}</div>
+          <div v-if="isFocus" class="fontColorC" >确定</div>
+          <div v-else class="blue" @click="confirmCommentDialog(2)">确定</div>
+        </header>
+        <div class="main" style="padding: 0.2rem;">
+          <div>
+            <!-- <div class="flex-center-center fontColorC" style="margin: 0.2rem 0;" v-if="!isEdit">
+              指标信息已设置不允许编辑
+            </div> -->
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm'"
+              label="指标"
+              v-model="formData.title"
+              border
+              placeholder="指标"
+              @blur="onFieldBlur($event, formData.title, 'title')"
+              :disabled="!isEdit"
+              @focus="onFocus"
+            />
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm'"
+              label="目标值"
+              v-model="formData.target"
+              border
+              type="number"
+              placeholder="目标值"
+              @blur="onFieldBlur($event, formData.target, 'target')"
+              :disabled="!isEdit"
+              @focus="onFocus"
+            />
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm'"
+              label="权重(%)"
+              v-model="formData.weight"
+              border
+              type="number"
+              placeholder="权重(请输入数字)"
+              @blur="onFieldBlur($event, formData.result, 'weight')"
+              :disabled="!isEdit"
+              @focus="onFocus"
+            />
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'targetConfirm'"
+              label="单位"
+              v-model="formData.unit"
+              border
+              placeholder="单位"
+              @blur="onFieldBlur($event, formData.unit, 'unit')"
+              :disabled="!isEdit"
+              @focus="onFocus"
+            />
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'resultInput'"
+              label="结果值"
+              v-model="formData.result"
+              border
+              placeholder="结果值"
+              @blur="onFieldBlur($event, formData.result, 'result')"
+              @focus="onFocus"
+            />
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreSelf'"
+              label="自评"
+              v-model="formData.score"
+              border
+              type="number"
+              placeholder="评分(请输入数字)"
+              @blur="onFieldBlur($event, formData.score, 'scoreSelf')"
+              @focus="onFocus"
+            />
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'scoreEachOther'"
+              label="互评"
+              v-model="formData.score"
+              border
+              type="number"
+              placeholder="评分(请输入数字)"
+              @blur="onFieldBlur($event, formData.score, 'scoreEachOther')"
+              @focus="onFocus"
+            />
+            <div
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'score' && formData.scoreExpression"
+              @click="inputScore()"
+              class="blue"
+              style="margin: 0.2rem 0;" >
+              {{ '系统评分: ' + formData.scoreExpression }}
+            </div>
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'score'"
+              label="评分"
+              v-model="formData.score"
+              border
+              type="number"
+              placeholder="评分(请输入数字)"
+              @blur="onFieldBlur($event, formData.score, 'score')"
+              @focus="onFocus"
+            />
+            <van-field
+              v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType === 'review'"
+              label="最终评分"
+              v-model="formData.score"
+              border type="number"
+              disabled
+            />
+            <van-field
+              label="意见"
+              v-model="comment"
+              rows="4"
+              border
+              autosize
+              maxlength="200"
+              show-word-limit
+              type="textarea"
+              placeholder="请输入意见"
+              @blur="confirmCommentDialog(1)"
+              @focus="onFocus"
+            />
+            <div v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType !== 'targetConfirm'" class="fontColorC" style="margin: 0.2rem 0;">上传附件</div>
+            <Uploader v-if="handleDetailInfo && handleDetailInfo.task && handleDetailInfo.task.nodeType !== 'targetConfirm'" v-model="img_fileList" :max-count="3" :beforeRead="beforeRead" :accept="accept"/>
+          </div>
+        </div>
+      </div>
+    </van-popup>
+
+    <!-- 筛选 -->
+    <!-- <van-popup v-model="isShowPopup" position="right" style="height: 100%;left: 20%;">
+      <div style="position: relative;height: 100%;">
+        <div style="border-bottom: 1px solid #f1f1f1;font-size: 16px;font-weight: 700;height: 0.92rem;line-height: 0.92rem;padding: 0 0.2rem;">高级筛选</div>
+        <div>
+        </div>
+        <div style="position: fixed; bottom: 0.2rem;left: 0.2rem;right: 0.2rem;">
+          <div class="btn" @click="isShowPopup = false">确认</div>
+        </div>
+      </div>
+    </van-popup> -->
+  </div>
+</template>
+<script>
+import Vue from 'vue';
+import moment from 'moment';
+import Uploader from '@/components/OssUploader';
+import { Checkbox, CheckboxGroup, ActionSheet, ImagePreview } from 'vant';
+Vue.use(Checkbox).use(CheckboxGroup).use(ActionSheet).use(ImagePreview);
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import resultValueEntryMb from '@/performance/components/actionplan/resultValueEntryMb';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import {getExpressionStr} from '@/performance/utils/auth'
+import OperateLogVue from '@/performance/components/public/OperateLog.vue'
+
+export default {
+  data() {
+    return {
+      type: "entering",
+      skeletonLoad: false, // 过度骨架屏
+      isDetails:true,
+      reviewIndicatorId: '',
+      reviewId: '',
+      taskId: '',
+      reject: false,
+      isFocus: false,
+      day: moment().format('YYYY-MM-DD'),
+      isNeed: !this.$getCache('isAndroid'),
+      detailInfo: null,
+      handleDetailInfo: null, // 弹窗中用来操作的数据
+      isShowHandle: false,
+      isShowPopup: false,
+      result: '',
+      dialogTitle: '',
+      comment: '',
+      img_fileList: [],
+      emtags: [],
+      accept:'image/jpeg,image/png,image/jpg,image/bmp',
+      formData: {
+        title: '',
+        weight: '',
+        unit: '',
+        target: '',
+        content: '',
+        result: '',
+        scoreExpression: '', // 系统评分
+        score: ''
+      }
+    };
+  },
+
+  components: {
+    EmployeeSelector,
+    VanSkeleton,
+    OperateLogVue,
+    Uploader,
+  },
+
+  watch: {
+  },
+
+  computed: {
+
+    // 确认目标节点是否可以编辑
+    isEdit() {
+      let children = [], employeeIds = [];
+      let user_id = this.$userInfo().id.toString() // 当前用户ID
+      const { nodes = [] } = this.detailInfo && this.detailInfo.flow || {};
+      if (nodes && nodes.length > 0)
+        children = nodes.find(node => node.type === 'targetConfirms').children
+        children.forEach(child => {
+            // 是否允许编辑
+            if (child.allows.includes('edit')) {
+                if (['leader', 'deptLeader', 'post', 'user'].includes(child.assigneeType)) {
+                    if (child.tasks && child.tasks.length > 0) {
+                        child.tasks.forEach(task => {
+                            employeeIds.push(task.assignee)
+                        })
+                    }
+                }
+                else {
+                    employeeIds = [user_id]
+                }
+            }
+        })
+        return employeeIds && employeeIds.length > 0 && employeeIds.includes(user_id) ? true : false
+      },
+  },
+
+  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 '--'
+    },
+
+    filterNodeStatus(v) {
+      if (v === 'start') return '开始'
+      if (v === 'target_confirm') return '确认目标'
+      if (v === 'result_input') return '录入结果值'
+      if (v === 'score_self') return '自评'
+      if (v === 'score_each_other') return '互评'
+      if (v === 'score') return '评分'
+      if (v === 'review') return '审批'
+      if (v === 'cc') return '抄送'
+      if (v === 'end') return '结束'
+    },
+
+    formatDate(val) {
+      if (val) return moment(val).format('YYYY-MM-DD')
+      else return "--"
+    },
+  },
+
+  created() {
+    this.reviewIndicatorId = this.$route.query.reviewIndicatorId
+    this.taskId = this.$route.query.taskId
+    this.reviewId = this.$route.query.reviewId
+    this.type = this.$route.query.type
+    console.log("路由参数")
+    console.log(this.$route.query)
+    this.getTaskDetails();
+  },
+
+  beforeDestroy() {
+    this.detailInfo = null
+    this.handleDetailInfo = null
+  },
+  activated() {},
+
+  methods: {
+    // 系统评分 - 立即评分
+    inputScore() {
+      this.formData.score = this.formData.scoreExpression
+    },
+
+    goDetails() {
+      let { reviewId, reviewIndicatorId, flow: { nodes } } = this.detailInfo
+      let showData = {
+        nodes,
+        reviewId,
+        reviewIndicatorId
+      }
+      this.$router.push({ path: "/handleDetails", query: {showData: JSON.stringify(showData)} })
+    },
+
+    // 获取待办任务详情
+    getTaskDetails() {
+      let url;
+      if(this.type === 'entering') url = `/performance/review/job/${this.$userInfo().site_id}/${this.reviewIndicatorId}/${this.taskId}`;
+      else url = `/performance/review/job/history/${this.$userInfo().site_id}/${this.reviewIndicatorId}/${this.taskId}`;
+      this.$axiosUser('get', url).then(res => {
+        if(res.data.code == 1) {
+          this.detailInfo = res.data.data;
+          this.formData.title = this.detailInfo.title;
+          this.formData.target = this.detailInfo.target;
+          this.formData.unit = this.detailInfo.unit;
+          this.formData.result = this.detailInfo.result;
+          this.formData.weight = this.detailInfo.weight;
+          this.formData.scoreExpression = this.detailInfo.scoreExpression;
+          this.formData.score = this.detailInfo.task.score;
+          this.formData.content = this.detailInfo.task.content;
+          this.handleDetailInfo = res.data.data;
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'targetConfirm') this.dialogTitle = '确认目标'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'resultInput') this.dialogTitle = '结果录入'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'scoreSelf') this.dialogTitle = '自评'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'scoreEachOther') this.dialogTitle = '互评'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'score') this.dialogTitle = '评分'
+          if(this.detailInfo && this.detailInfo.task && this.detailInfo.task.nodeType === 'review') this.dialogTitle = '审批'
+          this.comment = this.detailInfo.task.comment;
+          this.detailInfo.userInfo = this.$getEmployeeMapItem(this.detailInfo.employeeId)
+          this.detailInfo.deptList = this.$getEmployeeMapItem(this.detailInfo.employeeId).employee_detail.dept_list
+        }
+      })
+    },
+
+    goMyTarget() {
+      this.$router.push({name: 'myTarget', query: { ids: JSON.stringify(this.okrs) }});
+    },
+
+    // 返回布尔值
+    beforeRead(file) {
+      const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+      if (!isJPG) {
+        this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+      }
+      return isJPG;
+    },
+
+    afterRead(files, detail) {
+      console.log(files, detail);
+    },
+
+    // 文本框失去焦点事件 - 暂存
+    onFieldBlur(e, val, type) {
+      let reviewIndicatorId = this.reviewIndicatorId;
+      let { nodeType } = this.detailInfo.task;
+      // 请求参数
+      let data = {
+        taskId: this.taskId,
+       }
+      // 自评,互评,评分获取评分
+      if (type === 'scoreSelf' || type === 'scoreEachOther' || type === 'score') {
+          data['score'] = val;
+      }else {
+        data[type] = val;
+      }
+
+      let url;
+      switch (nodeType) {
+        // 确认目标
+        case 'targetConfirm':
+          url = `/performance/review/target/confirm/${type}/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 录入结果值
+        case 'resultInput':
+          url = `/performance/review/result/Input/${type}/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 自评
+        case 'scoreSelf':
+          url = `/performance/review/score/self/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 互评
+        case 'scoreEachOther':
+          url = `/performance/review/score/each/other/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 评分
+        case 'score':
+          url = `/performance/review/score/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        default:
+          break;
+      }
+
+      this.$axiosUser('post', url, data, 'contentTypeJson').then(res => {
+        if(res.data.code === 1) {
+          // this.detailInfo = res.data.data;
+        }else {
+          this.$toast.fail(res.data.message)
+        }
+        this.isFocus = false
+      })
+
+    },
+
+    onFocus() {
+      this.isFocus = true
+    },
+
+
+    async confirmCommentDialog(type) {
+        // 阻止事件冒泡,避免触发全局点击事件
+        // event.stopPropagation();
+        // if(this.loading) return
+        // let { reviewIndicatorId } = this.dialogData;
+        let reviewIndicatorId = this.reviewIndicatorId;
+        let taskId = this.taskId;
+        let { nodeType } = this.handleDetailInfo.task;
+        let url;
+        switch (nodeType) {
+          case 'targetConfirm':
+            url = `/performance/review/target/confirm/complete/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          case 'resultInput':
+            url = `/performance/review/result/Input/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          // 自评
+          case 'scoreSelf':
+            url = `/performance/review/score/self/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          // 互评
+          case 'scoreEachOther':
+            url = `/performance/review/score/each/other/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          // 评分
+          case 'score':
+            url = `/performance/review/score/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          case 'review':
+            // 驳回
+            if (this.reject) url = `/performance/review/review/refuse/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            // 通过
+            else url = `/performance/review/review/pass/${this.$userInfo().site_id}/${reviewIndicatorId}`
+            break;
+          default:
+            break;
+        }
+
+        let data = {
+            taskId,
+            comment: this.comment,
+            complete: type == 1 ? false : true // false 暂存,true 提交
+        }
+
+        // 提交时,提醒用户要提交附件
+        if (type == 2) {
+          if (this.img_fileList && this.img_fileList.length > 0) {
+            let res = await this.comfirmUploadFiles()
+            console.log("上传附件")
+            console.log(res)
+            if(res.data.code !== 1) {
+              this.img_fileList = []
+              return this.$toast.fail('上传附件失败,请稍后重试')
+            }
+          }
+        }
+
+        this.$axiosUser('post', url, data, 'contentTypeJson').then(res => {
+          console.log("提交数据")
+          console.log(res)
+          // 暂存
+          if (type == 1) {
+              if (res.data.code == 1) {
+                this.type = "entering"
+                this.getTaskDetails();
+              }
+              else this.$toast.fail(res.message || '操作失败');
+          // 提交
+          } else {
+              if (res.data.code == 1) {
+                this.$toast.success('操作成功');
+                this.type = "noEntering"
+                this.getTaskDetails();
+                // this.$emit("handleSuccess")
+                // this.$emit('close-dialog', false);
+                this.isShowHandle = false;
+                this.comment = "";
+                // this.reject = false; // 驳回标识
+                this.img_fileList = [];
+              } else {
+                this.$toast.fail(res.message || '操作失败');
+              }
+          }
+            // this.handleBlur();
+        })
+    },
+
+    // 各个任务节点 文件上传
+    async comfirmUploadFiles() {
+      let reviewIndicatorId = this.reviewIndicatorId;
+      let taskId = this.taskId;
+      let { nodeType } = this.handleDetailInfo.task;
+      let url;
+
+      switch (nodeType) {
+        // 结果值附件录入
+        case 'resultInput':
+          url = `/performance/review/result/Input/result/file/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 自评附件录入
+        case 'scoreSelf':
+          url = `/performance/review/score/self/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 互评附件录入
+        case 'scoreEachOther':
+          url = `/performance/review/score/each/other/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 评分附件录入
+        case 'score':
+          url = `/performance/review/score/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        // 审批附件录入
+        case 'review':
+          url = `/performance/review/review/files/${this.$userInfo().site_id}/${reviewIndicatorId}`
+          break;
+        default:
+          break;
+      }
+
+        let data = {
+          taskId,
+          files: this.img_fileList
+        }
+        let res = await this.$axiosUser('post', url, data, 'contentTypeJson')
+        return res
+        // let { code } = res
+        // if (code == 1) {
+
+        // }  else {
+        //   this.img_fileList = []
+        //   this.$toast.fail('上传附件失败, 请稍后重试')
+        // }
+    },
+
+
+    downWgt (url,name) {
+      let self = this
+      if(!window.plus){
+          window.open(url, '_blank');
+          return false
+      }
+      let dtask = plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
+        function (d, status) {
+          if (status == 200) {
+            plus.runtime.openFile(d.filename,{},(err)=>{
+              // console.log(JSON.stringify(err))
+            });
+          } else {
+            self.$toast.clear()
+            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
+          }
+        }
+      )
+      dtask.start();
+    },
+
+    returnStr(time){
+      let date=`${time}000`
+      let res = moment(Number(date)).format('YYYY/MM/DD HH:mm');
+      return this.fnTime(res);
+    },
+
+
+    fnTime( time ){
+        let staer=time.slice(0,11);
+        let ptime = new Date(time).getTime()
+        const twentyFourHours = 24 * 60 * 60 * 1000;
+        const fortyEightHours = 24 * 60 * 60 * 1000 * 2;
+        const today = moment().format('YYYY/MM/DD');
+
+        const todayTime = new Date(today).getTime();
+        const yesterdayTime = new Date(todayTime - twentyFourHours).getTime();
+        const lastYesterdayTime = new Date(todayTime - fortyEightHours).getTime();
+
+        if( ptime >= todayTime ){
+            return '今天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < todayTime && yesterdayTime <= ptime ){
+            return '昨天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < yesterdayTime && lastYesterdayTime <= ptime ){
+            return '前天 '+time.split(' ')[1]+' 更新了执行计划';
+        }else if(this.dateSum(this.day,staer)>30){
+            return '近30天无计划更新';
+        } else{
+            return time+' 更新了执行计划';
+        }
+    },
+
+
+    dateSum(sDate1, sDate2){   //sDate1和sDate2是2008-12-13格式
+        var aDate, oDate1, oDate2, iDays
+        aDate = sDate1.split("-")
+        oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])   //转换为12-13-2008格式
+        aDate = sDate2.split("-")
+        oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
+        iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 /24)   //把相差的毫秒数转换为天数
+        return iDays
+    },
+
+    openImg(imgs, index) {
+      let imgArr = imgs.map(item => {
+        return item.url;
+      });
+      ImagePreview({
+        images: imgArr,
+        startPosition: index
+      });
+    },
+
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+
+
+
+    unfold() {
+      // 展开记录
+      this.recordList = this.recordAllList;
+    },
+
+    packUp() {
+      // 收起记录
+      let listtre = [];
+      this.recordAllList.forEach((item, index) => {
+        if (index < 3) {
+          listtre.push(item);
+        }
+      });
+      this.recordList = listtre;
+    },
+
+
+  },
+
+};
+</script>
+
+<style scoped lang="less">
+
+  .all {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    .scroller {
+      position: relative;
+      flex: 1;
+    }
+  }
+
+
+.isIos {
+  padding-bottom: 0.4rem !important;
+}
+
+/deep/ .overall {
+  height: calc(100% - 1.92rem) !important;
+  position: relative;
+  overflow-y: scroll;
+}
+
+.title {
+  height: 0.8rem;
+  line-height: 0.8rem;
+  font-size: 0.28rem !important;
+  color: #8a8a8a;
+  padding: 0 0.1rem;
+  box-sizing: border-box;
+}
+
+.user-info-box {
+  width: 96%;
+  margin: 0 auto 0.2rem auto;
+  background-color: #fff;
+  padding: 0.2rem;
+  box-sizing: border-box;
+  border-radius: 6px;
+  // margin-bottom: 0.2rem;
+  .user-info {
+    font-size: 0.28rem;
+    color: #89919F !important;
+    margin: 0 0 0 0.2rem;
+  }
+
+  .info-item {
+    margin-bottom: 0.2rem;
+    font-size: 0.28rem;
+    .cycle-type {
+      padding: 0.08rem;
+      border-radius: 0.1rem;
+      color: #26a2ff;
+      box-sizing: border-box;
+      background-color: #ecf5ff;
+    }
+  }
+}
+
+
+.footer {
+
+  padding: 0.2rem;
+  border-top: 0.02rem solid #f1f1f1;
+  background: #fff;
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: 999;
+  box-shadow: 0px -3px 0.15rem #f7f8fa;
+  box-sizing: border-box;
+  .btn {
+    border-radius: 0.5rem;
+    padding: 0.16rem 0.14rem;
+    // border: 0.02rem solid #26A2FF;
+    color: #fff;
+    text-align: center;
+    background: #26A2FF;
+    font-size: 0.3rem;
+    box-sizing: border-box;
+  }
+}
+
+
+</style>

+ 133 - 0
src/performance-07-19/components/public/OperateLog.vue

@@ -0,0 +1,133 @@
+<template>
+  <div>
+    <!-- 记录 -->
+      <div v-if="logList && logList.length > 0">
+        <div class="modTit">操作日志</div>
+        <div class="modCont" style="">
+          <div
+            v-for="(item, index) in logList"
+            :key="index"
+            :style="index != logList.length - 1 ? 'min-height: 1rem;' : ''"
+            style="position: relative; padding-bottom: .2rem;"
+          >
+
+            <van-row gutter="10">
+              <van-col span="15">
+                <div v-if="item.employeeId"  style="display:flex;">
+                  <userImage class="about-me__avatar" :id="item.employeeId" :user_name="item.name" fontSize=".24" width="0.5rem" height="0.5rem" font_min></userImage>
+                  <span  style="font-size:.255rem;padding: .06rem 0 0 .07rem;" class="font-flex-word">{{ item.name }}</span>
+                </div>
+                <div v-else style="display:flex;">
+                  <img src="static/images/robot.png" alt="" style="width: 0.5rem; height: 0.5rem;"/>
+                  <span style="font-size:.255rem;padding: .06rem 0 0 .07rem;" class="font-flex-word">系统操作</span>
+                </div>
+
+                <div v-if="index != logList.length - 1" class="bian"></div>
+              </van-col>
+              <van-col span="9" style="font-size:.24rem;color:#ababab; padding:.06rem 0 0 0; text-align: right;">{{ item.createTime }}</van-col>
+            </van-row>
+            <van-row>
+              <van-col offset="2" span="" style="font-size:.255rem;padding-top:.06rem;white-space:normal;">
+                <div style="color:#ababab;width: 100%;word-break:break-all;" v-if="item.content">{{ item.content }}</div>
+              </van-col>
+            </van-row>
+          </div>
+          <span style="font-size: .26rem;color: #5699ff;" @click="unfold" v-if="logList.length <= 3 && recordAllList.length > 3">全部记录</span>
+          <span style="font-size: .26rem;color: #5699ff;" @click="packUp" v-if="logList.length > 3">收起</span>
+        </div>
+      </div>
+
+  </div>
+</template>
+
+<script>
+  export default {
+    props: {
+      reviewId: {
+        type: String | Number,
+        default: ''
+      },
+      reviewIndicatorId: {
+        type: String | Number,
+        default: ''
+      }
+    },
+
+    data() {
+      return {
+        logList: [],
+        params: {
+          reviewId: '',
+          page: 1,
+          pageSize: 1000,
+        },
+      }
+    },
+
+
+    created() {
+      this.params.reviewId = this.reviewId
+      this.getLogData()
+    },
+
+
+    methods: {
+      getLogData() {
+        let url = `/performance/statistics/logs/${this.$userInfo().site_id}/${this.reviewId}`
+        let requestParams = {}
+
+        if (this.reviewIndicatorId) {
+          requestParams = { ...this.params, reviewIndicatorId: this.reviewIndicatorId }
+        } else {
+          requestParams = { ...this.params }
+        }
+        this.$axiosUser("get", url, requestParams).then(res => {
+          console.log(res);
+          let record = res.data.data.list;
+          if(record && record.length > 0) {
+            record = record.reverse()
+            this.recordAllList = record;
+            record.forEach((item, index) => {
+              if (index < 3) {
+                this.logList.push(item);
+              }
+            });
+          }
+
+          // this.total = res.data.data.total
+        })
+      },
+
+      unfold() {
+        // 展开记录
+        this.logList = this.recordAllList;
+      },
+      packUp() {
+        // 收起记录
+        let listtre = [];
+        this.recordAllList.forEach((item, index) => {
+          if (index < 3) {
+            listtre.push(item);
+          }
+        });
+        this.logList = listtre;
+      },
+    },
+  }
+</script>
+
+<style scoped lang="less">
+  .modTit {
+    background-color: #efefef;
+    height: 0.8rem;
+    line-height: 0.8rem;
+    font-size: 0.28rem;
+    color: #8a8a8a;
+    padding-left: 0.1rem;
+    box-sizing: border-box;
+  }
+  .modCont {
+    padding: 0.3rem;
+    background-color: #fff;
+  }
+</style>

+ 40 - 0
src/performance-07-19/components/public/VanSkeleton.vue

@@ -0,0 +1,40 @@
+<template>
+  <div style="display:inline;">
+    <van-skeleton :row="5" :loading="skeLoad">
+      <slot></slot>
+    </van-skeleton>
+  </div>
+</template>
+
+<script>
+import Vue from "vue";
+import { Skeleton } from "vant";
+Vue.use(Skeleton);
+export default {
+  props: {
+    skeLoad: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {};
+  },
+  components: {},
+  watch: {},
+  methods: {},
+  created() {},
+  mounted() {}
+};
+</script>
+
+<style scoped lang="less">
+/deep/ .van-skeleton__content {
+// height: 100%;
+  padding: 0.3rem 0;
+  .van-skeleton__row {
+    height: 0.7rem;
+    margin: 1.2rem 0;
+  }
+}
+</style>

+ 289 - 0
src/performance-07-19/components/statementcontent/statement_details.vue

@@ -0,0 +1,289 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar :title="barTItle" left-text="" left-arrow @click-left="$route_back"></van-nav-bar>
+    <header class="performanceList" v-if="moduleshow">
+      <van-row>
+        <van-col span="24">
+          <van-search v-model="keyword" placeholder="请输入员工姓名搜索" @input="keyInput" style="padding: 0.2rem 0.32rem .2rem .32rem;" />
+        </van-col>
+      </van-row>
+    </header>
+    <div class="headScreen flex-no-wrap" v-if="moduleshow">
+      <span v-for="(item, index) in smdsHead" :key="index" @click="smdsFiltrate(item)" :class="{ active: item.id == smdsins }">{{ item.name }}</span>
+    </div>
+    <div class="all" style="position: relative;height: calc(100vh - 3.46rem);">
+      <scroller ref="work_bench_scroller" noDataText="我也是有底线的" :list="asstabData" :on-refresh="refresh" :on-infinite="infinite">
+        <div style="padding-bottom:1rem;">
+          <div v-if="moduleshow" style="height:.2rem;background-color:#f5f7fa;"></div>
+          <div v-if="!moduleshow" style="height:.7rem;background-color:#f5f7fa;color: #848484;padding-left: .3rem;line-height:.7rem;font-size:.28rem;">
+            {{ itemparams.name }} ({{ itemparams.val }}人)
+          </div>
+          <van-empty description="暂无绩效考核数据" v-if="asstabData.length == 0" />
+          <div v-else>
+            <div
+              v-for="(item, index) in asstabData"
+              :key="index"
+              @click="unreadCli(item)"
+              :style="'z-index:' + (asstabData.length - index)"
+              class="performanceList flex-box flex-d-center wld_list"
+            >
+              <div class="flex-box">
+                <div class="me_list_img">
+                  <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize="0.32" width="0.65rem" height="0.65rem"></userImage>
+                </div>
+                <div style="padding-left:.25rem;">
+                  <span style="font-size:.3rem;">{{ item.employee_name }}</span>
+                  <br />
+                  <span class="font-flex-word" style="width: 4rem;display:inline-block;">
+                    <span style="font-size:.25rem;color:#828282;" v-for="(arr, att) in item.dept_list" :key="att">
+                      {{ arr.dept_name || arr.name }}
+                      <span v-if="item.dept_list.length - att > 1">,</span>
+                    </span>
+                  </span>
+                </div>
+              </div>
+              <div v-if="item.doing_id == 11 || !item.doing_id" class="wld_tag_green wld_tag">考核结束</div>
+              <div v-else class="wld_tag_bisque wld_tag">
+                {{
+                  item.doing_id == 1
+                    ? '目标制定'
+                    : item.doing_id == 2
+                    ? '目标确定'
+                    : item.doing_id == 3
+                    ? '执行中'
+                    : item.doing_id == 4
+                    ? '结果值录入'
+                    : item.doing_id == 5
+                    ? '评分'
+                    : item.doing_id == 9
+                    ? '审批'
+                    : item.current_node_name
+                }}
+              </div>
+            </div>
+          </div>
+        </div>
+      </scroller>
+    </div>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { Tab, Tabs, Search } from 'vant';
+Vue.use(Tab)
+  .use(Tabs)
+  .use(Search);
+import { _debounce } from '@/utils/auth';
+export default {
+  data() {
+    return {
+      smdsins: 0,
+      smdsHead: [
+        { id: 0, name: '参与人数'},
+        { id: 1, name: '目标制定'},
+        { id: 2, name: '目标确认'},
+        { id: 3, name: '执行中'},
+        { id: 4, name: '结果值录入'},
+        { id: 5, name: '评分'},
+        { id: 9, name: '审批'},
+        { id: 11, name: '考核结束'}
+      ],
+      barTItle: '', // 顶部标题
+      moduleshow: true,
+      itemparams: {},
+      asstabData: [],
+      nowAssList: {}, // 当前绩效包信息
+      keyword: '', //搜索关键字
+      paramsList: {
+        package_id: 0,
+        doing_id: 0,
+        page: 1,
+        page_size: 20,
+        employee_ids: [],
+        dept_ids: [],
+      },
+      employee_List: [],
+    };
+  },
+  methods: {
+    //搜索
+    keyInput: _debounce(function(val) {
+      let arr = []
+      if(val == ''){
+        arr = []
+      }else{
+        this.employee_List.forEach(item =>{
+          if(item.name.indexOf(val) != -1){
+            arr.push(item.id)
+          }
+        })
+        arr = arr.length == 0 ? [0] : arr
+      }
+      this.paramsList.employee_ids = JSON.stringify(arr)
+      this.paramsList.page = 1
+      this.listV3()
+    }),
+    Ketdept(item) {
+      //筛选部门-暂时不用
+      return item.some(arr => {
+        return (arr.dept_name || arr.name).indexOf(this.keyword) >= 0;
+      });
+    },
+    unreadCli(item) {
+      this.$router.push({
+        name: 'performanceDetails',
+        query: {
+          assId: this.nowAssList.id,
+          staffId: item.employee_id,
+          Tit: this.nowAssList.name
+        }
+      });
+    },
+    smdsFiltrate(item) {
+      this.smdsins = item.id;
+      this.paramsList.doing_id = item.id
+      this.paramsList.page = 1
+      this.listV3()
+      // this.navNewPitch(this.smdsins);
+    },
+
+    // 上拉刷新
+    refresh(done) {
+      this.paramsList.page = 1;
+      this.listV3(done);
+    },
+    // 下拉加载
+    infinite(done) {
+      this.paramsList.page++;
+      this.listV3(done);
+    },
+
+    //绩效详情V3
+    listV3(done){
+      let params = this.paramsList
+      if(!params.package_id){
+       done && done(false);
+        return false
+      }
+      let hasMore = false;
+      this.$toast.loading({
+        loadingType: 'spinner',
+        message: '加载中'
+      })
+      this.$axiosUser('get', '/api/pro/per/package/info_v3', params).then(res => {
+        if (res.data.code == 1) {
+          let list = res.data.data.list
+          list.forEach(item =>{
+            let empall = this.$getEmployeeMapItem(item.employee_id)
+            item.employee_name = empall.name || ''
+            item.dept_list = empall.employee_detail.dept_list || []
+          })
+          if(this.paramsList.page == 1){
+            this.asstabData = list
+          }else{
+            this.asstabData = this.asstabData.concat(list)
+          }
+          hasMore = list.length !== 20;
+          done && done(hasMore);
+        }
+      }).finally(_=>{
+        done && done(hasMore);
+        this.$toast.clear()
+      })
+    },
+    //绩效详情V3协助
+    info_v3_aid(){
+      if(!this.paramsList.package_id){
+        return false
+      }
+      let params = {
+        package_id: this.paramsList.package_id,
+      }
+      this.$axiosUser('get', '/api/pro/per/package/info_v3_aid', params).then(res => {
+        if (res.data.code == 1) {
+          this.employee_List = res.data.data.employees
+        }
+      })
+    },
+  },
+  created() {
+    let obj = this.$getCache('statement_details');
+    if (obj.paths == 'statdeEcharts') {
+      this.barTItle = '考核人数列表';
+      this.moduleshow = false;
+      this.itemparams.name = obj.dept_o.name;
+      this.itemparams.val = obj.dept_o.tak;
+      this.paramsList.dept_ids = JSON.stringify(obj.dept_o.id)
+    } else if (obj.paths == 'personnelDetail') {
+      this.moduleshow = true;
+      this.barTItle = '人员明细';
+      this.smdsins=obj.index;
+    }
+    this.paramsList.doing_id = obj.index
+    let baoID = JSON.parse(obj.asslist)
+    this.paramsList.package_id = baoID.id
+    this.listV3()
+    this.nowAssList = JSON.parse(obj.asslist);
+  },
+  mounted() {
+    this.info_v3_aid()
+  }
+};
+</script>
+
+<style scoped lang="less">
+header {
+  background-color: #fff;
+  z-index: 1;
+}
+
+.headScreen {
+  span {
+    display: inline-block;
+    font-size: 0.28rem;
+    background-color: #ffffff;
+    color: #616161;
+    margin: 0.2rem 0.07rem 0.1rem 0.13rem;
+    padding: 0.04rem 0.15rem 0.04rem 0.15rem;
+    border-radius: 0.05rem;
+  }
+  .active {
+    background-color: #26a2ff;
+    color: rgb(255, 255, 255);
+  }
+}
+.wlddeptperson {
+  background-color: rgb(245, 245, 245);
+  padding: 0.13rem 0.2rem;
+  span {
+    color: #8c8c8c;
+    font-size: 0.25rem;
+  }
+}
+.wld_tag {
+  width: 1.5rem;
+  font-size: 0.25rem;
+  height: 0.4rem;
+  text-align: center;
+  line-height: 0.4rem;
+  margin-top: 0.3rem;
+}
+.wld_tag_bisque {
+  background-color: #fff1e0;
+  color: #f7b461;
+}
+.wld_tag_green {
+  background-color: #e2e2e2;
+  color: #929292;
+}
+.wld_list {
+  padding: 0.15rem 0.3rem;
+  .me_list_img {
+    margin-top: 0.15rem;
+  }
+}
+// .active{
+//     color:red
+// }
+</style>

+ 308 - 0
src/performance-07-19/components/workbenchcontent/affirm.vue

@@ -0,0 +1,308 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="绩效确认" left-arrow @click-left="$route_back">
+       <span @click="submit" slot="right" v-if="!info.status" style="color: #fff;">提交</span>
+    </van-nav-bar>
+    <div class="all" style="position: relative;">
+      <header class="flex-box-ce">
+        <div style="font-size: 0.32rem;font-weight: 700;max-width: 4rem;" class="black font-flex-word">{{level_name}}</div>
+        <span v-if="info.status" class="btn">已确认</span>
+        <span v-else class="btn" style="background-color: #FF9600;">待确认</span>
+        <span class="flex-1"></span>
+        <span class="blue" style="font-size: 0.28rem;"  v-if="!info.status"  @click="isShowText=true">提交要求<van-icon name="arrow" /></span>
+      </header>
+      <van-search placeholder="请输入姓名" v-model="form.name" style="border-bottom: 1px solid #f1f1f1;"/>
+      <van-dropdown-menu style="font-size: 0.28rem;">
+        <van-dropdown-item v-model="form.level_name" :options="levels" />
+        <van-dropdown-item v-model="form.sort_type" :options="optionsFw"/>
+      </van-dropdown-menu>
+      <div style="height: calc(100% - 3.6rem) !important;position: relative;">
+        <scroller ref="scroller" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢!" :list="list">
+          <van-cell-group>
+            <div class="flex-box-ce list-item flex-d-wrap"  v-for="(item, index) in list" :key="index">
+              <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" :img_url="item.userInfo.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+              <div class="flex-1" style="margin-left: 0.24rem;">
+                 <div >{{item.userInfo.name}}</div>
+                 <div class="fontColorC font-flex-word" style="font-size: 0.28rem;width: 2.5rem;margin-top: 0.1rem;" v-if="item.dept_list.length>0">
+                     <span v-for="item2 in item.dept_list" :key="item2.dept_id">{{ item2.dept_name }}</span>
+                 </div>
+              </div>
+              <div class="flex-1" style="text-align: center;"><span v-if="item.final_point">{{item.final_point}}</span><span v-else>--</span></div>
+              <div class="flex-1" style="text-align: center;"><span v-if="item.final_level">{{item.final_level}}</span><span v-else>--</span></div>
+              <div style="text-align: center;width: 0.6rem;">
+                <template v-if="($userInfo().id==info.owner_id||$isAuthoritys_jx($9))&&item.doing_id==11&&!info.status">
+                  <van-popover placement="left" v-model="item.isShow" trigger="click" :actions="actions" @select="onSelect($event,item)">
+                    <template #reference>
+                      <van-icon name="weapp-nav" class="fontColorC"/>
+                    </template>
+                  </van-popover>
+                </template>
+              </div>
+            </div>
+          </van-cell-group>
+          <van-empty description="暂无内容" v-if="list.length == 0" />
+        </scroller>
+      </div>
+    </div>
+    <van-dialog v-model:show="isShowText">
+      <div style="padding: 0.2rem;">
+        <template v-if="info.config.scope.enable==1">
+          <div style="font-size: 16px;font-weight: 600;margin-bottom: 10px;">分值要求</div>
+          <div style="margin-bottom: 20px;">分值要求:{{info.config.scope.min}}≤分值≤{{info.config.scope.max}}</div>
+        </template>
+        <template v-if="info.config.levels.enable==1">
+          <div style="font-size: 16px;font-weight: 600;margin-bottom: 10px;">等级分布人数要求</div>
+          <div style="margin-bottom: 20px;" v-if="info.config.levels.levels">人数分布要求:
+            <span v-for="(item,index) in info.config.levels.levels">
+             <span class="blue" style="font-weight: 600;">{{item.name}}</span> {{item.count}}人,
+            </span>
+          </div>
+        </template>
+      </div>
+    </van-dialog>
+    <!-- 修改评分 -->
+    <van-popup v-model:show="isShowUpdatePoint" round position="bottom" :style="{ height: '90%',background:'#fff' }" @close="isShowUpdatePoint=false">
+       <div>
+         <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+           <div class="blue" @click="isShowUpdatePoint=false">取消</div>
+           <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">调整评分</div>
+           <div class="blue" @click="savecomtheResults">确定</div>
+         </header>
+         <div>
+            <van-cell-group>
+              <van-cell title="员工姓名" :value="selectItem.userInfo.name" />
+              <van-cell title="原考核结果" :value="selectItem.final_point" />
+            </van-cell-group>
+            <van-field input-align="right" v-model="point" label="新考核结果" placeholder="请输入新考核结果"  @input="[(point = point.match(/\d+(\.\d{0,2})?/) ? point.match(/\d+(\.\d{0,2})?/)[0] : '')]"/>
+         </div>
+       </div>
+    </van-popup>
+    <!-- 修改等级 -->
+    <van-popup v-model:show="isShowUpdateLevel" round position="bottom" :style="{ height: '90%',background:'#fff' }" @close="isShowUpdateLevel=false">
+       <div>
+         <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+           <div class="blue" @click="isShowUpdateLevel=false">取消</div>
+           <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">调整等级</div>
+           <div class="blue" @click="savecomtheResults">确定</div>
+         </header>
+         <div>
+            <van-cell-group>
+              <van-cell title="员工姓名" :value="selectItem.userInfo.name" />
+              <van-cell title="原绩效等级" :value="selectItem.final_level" />
+              <van-cell title="新绩效等级" is-link @click="isShowLevel=true">
+                <span v-if="level">{{level}}</span>
+                <span v-else class="input-ccc">请选择</span>
+              </van-cell>
+            </van-cell-group>
+         </div>
+       </div>
+    </van-popup>
+    <!-- 目标类型 -->
+    <van-action-sheet v-model="isShowLevel" :actions="levels2" @select="activelevels" cancel-text="取消" close-on-click-action/>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import {Tab, Tabs,Search,Circle,Icon,DropdownMenu,DropdownItem,DatetimePicker,Popover} from 'vant'
+Vue.use(Tabs).use(Tab).use(Search).use(Circle).use(Icon).use(DropdownMenu).use(DropdownItem).use(DatetimePicker).use(Popover);
+import {_debounce} from '@/utils/auth';
+export default {
+  data() {
+    return {
+      userInfo:this.$userInfo(),
+      form: {
+        pl_id:'',//	是	int	绩效等级配置id
+        page:1,//	是	int	当前页数
+        page_size:10,//	是	int	每页数据量最高100
+        name:'',//	否	string	人名
+        level_name:'全部等级',//	否	string	等级名称
+        sort_type:2,//	否	int	排序类型 1-分数升序 2-分数降序
+      },
+      optionsFw: [
+        { name: '分数降序',value:2,text:'分数降序'},
+        { name: '分数升序',value:1,text:'分数升序'},
+      ],
+      actions: [{ text: '调整分数' }, { text: '调整等级' }],
+      levels:[],
+      levels2:[],
+      theResults: 1, //结果点击按钮
+      theResultsList: {}, //点击的结果
+      comtheResults: false, //切换结果控制
+      theResultInp: '', //调整考核结果值
+      level:'',
+      theResultsButid:false,
+      level_name:'',
+      package_id:0,
+      info:{owner_id:0,config:{levels:{enable:0},scope:{enable:0}},record:[],can_submit:false,status:0},
+      isShowRecord:false,
+      list:[],
+      isShowText:false,
+      isShowUpdatePoint:false,
+      isShowUpdateLevel:false,
+      selectItem:{userInfo:{}},
+      point:'',
+      level:'',
+      theResults:1,
+      isShowLevel:false,
+    };
+  },
+  watch: {
+    'form.level_name'(val) {
+      this.pullDown();
+    },
+    'form.sort_type'(val) {
+      this.pullDown();
+    },
+    'form.name':{
+      deep: true,
+      handler: _debounce(function(val) {
+        this.pullDown();
+      })
+    },
+  },
+  created() {
+    if (this.$route.query.pl_id) {
+      this.form.pl_id = this.$route.query.pl_id;
+      this.level_name = this.$route.query.level_name;
+      this.package_id=this.$route.query.package_id;
+    }
+    this.getList();
+  },
+  methods: {
+    activelevels(item){
+      this.level=item.name
+    },
+    savecomtheResults() {
+      let data = {
+        pl_id: this.info.id,
+        pe_id: this.selectItem.id,
+      };
+      if(this.theResults==1){
+        if(!this.point){
+          this.$toast('请输入分值');
+          return false
+        }
+        data.point=this.point
+        data.level=this.selectItem.final_level
+      }else{
+        if(!this.level){
+          this.$toast('请选择等级');
+          return false
+        }
+        data.point=this.selectItem.final_point
+        data.level=this.level
+      }
+      this.$axiosUser('post', '/api/pro/per/package/plc/result', data).then(res => {
+        this.isShowUpdatePoint=false;
+        this.isShowUpdateLevel=false;
+        this.pullDown();
+      })
+    },
+    onSelect(e,item){
+      this.selectItem=item;
+      this.point='';
+      this.level='';
+      if(e.text=='调整分数'){
+        this.isShowUpdatePoint=true;
+        this.theResults=1;
+      }else{
+        this.theResults=2;
+        this.isShowUpdateLevel=true;
+      }
+    },
+    submit(){
+      if(!this.info.can_submit){
+        this.$toast('不符合提交条件,请查看 “提交要求”');
+        return false
+      }
+      this.$axiosUser('post', '/api/pro/per/package/plc/finish', {pl_id:this.form.pl_id}).then(res => {
+        this.pullDown();
+      })
+    },
+    pullDown(){
+      setTimeout(() => {
+        this.$refs.scroller.triggerPullToRefresh();
+      }, 50);
+    },
+    getList(is,callback) {
+      let hasMore = false
+      is? '':this.form.page=1;
+      let form=JSON.parse(JSON.stringify(this.form));
+      if(form.level_name=='全部等级'){
+        form.level_name='';
+      }
+      this.$axiosUser('get', 'api/pro/per/package/plc/statistics',form).then(res => {
+        let list=res.data.data.list;
+        list.forEach(item=>{
+           item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+           item.dept_list=this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
+           item.isShow=false
+        })
+        if (this.form.page === 1) {
+          this.list = list
+        } else {
+          this.list = this.list.concat(list)
+        }
+        if(this.levels.length==0){
+          let levels=[{ name: '全部等级',value:'全部等级',text:'全部等级'}];
+          let levels2=[]
+          res.data.data.levels.forEach(item=>{
+            levels.push({name: item.name,value:item.name,text:item.name})
+            levels2.push({name: item.name,value:item.name,text:item.name})
+          })
+          this.levels =levels
+          this.levels2 =levels2
+        }
+
+        this.info = res.data.data.info;
+        hasMore = list.length !== 10
+        callback && callback(hasMore)
+      })
+    },
+    // 上拉刷新
+    refresh (done) {
+      this.getList(false,done)
+    },
+    // 下拉加载
+    infinite (done) {
+      this.form.page++;
+      this.getList(true,done)
+    },
+  },
+};
+</script>
+
+<style scoped lang="less">
+  .label{
+    color: #89919F;
+    width: 1.8rem;
+    text-align: right;
+    margin-right: 0.24rem;
+  }
+.all {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  padding:0.3rem 0.2rem;
+  background-color: #fff;
+  font-size: 0.3rem;
+  // border-bottom: 1px solid #f1f1f1;
+  margin-bottom: 0.2rem;
+}
+.btn{
+  padding:0.01rem 0.1rem;
+  color: #fff;
+  border-radius: 2px;
+  font-size: 0.26rem;
+  background-color: #238dfa;
+  margin-left: 0.14rem;
+}
+.list-item{
+  padding: 0.24rem 0.32rem;
+  font-size: 0.32rem;
+  border-bottom: 1px solid #f1f1f1;
+}
+</style>

+ 232 - 0
src/performance-07-19/components/workbenchcontent/backlog - 副本 (2).vue

@@ -0,0 +1,232 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="待办事项" left-text="" left-arrow @click-left="routerBak" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <template>
+        <van-tabs v-model="type">
+          <van-tab title="待处理" name="noEntering"></van-tab>
+          <van-tab title="已处理" name="entering"></van-tab>
+        </van-tabs>
+
+        <!-- <header class="performanceList flex-box-ce" v-show="type=='noEntering'">
+          <div class="flex-1">
+            当前待办:
+            <span v-if="commission > 0" style="color: #e42000;font-size: .29rem;">{{ commission }}条</span>
+          </div>
+          <div class="selector" @click="selectPfTIme">
+            <span>{{ selectPftiText }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+        </header> -->
+        <scroller v-show="type == 'noEntering'" ref="work_bench_scroller" class="all" style="position: relative" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="noEnteringList">
+          <template v-if="noEnteringList && noEnteringList.length > 0">
+            <div class="flex-box-ce list-item" v-for="(item, index) in noEnteringList" :key="index">
+              <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-right: 0.08rem;"></userImage>
+              <div class="flex-1 flex-box-ce">{{ item.reviewTitle }}绩效考核,被考核人{{item.employeeName}}的指标{{ item.title }},需要您确认</div>
+              <div class="flex-box" style="align-items: center; height: 100%; color: #b1b1b1;"><van-icon name="arrow" size="16px"/></div>
+            </div>
+          </template>
+          <van-empty v-else description="暂无绩效考核数据" />
+        </scroller>
+
+        <!-- <scroller v-show="type == 'noEntering'" ref="work_bench_scroller" class="all" style="position: relative" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="backlogList">
+
+
+         <van-empty description="暂无绩效考核数据" v-if="backlogList.length == 0" />
+         <template v-if="backlogList.length > 0">
+            <div v-for="(item, index) in backlogList" :key="index">
+              <div class="backlog_list_tit">{{ item.time }}</div>
+              <div v-for="(arr, keys) in item.list" :key="keys" :style="'z-index:' + (item.list.length - keys)" class="performanceList backlog_list" @click="clickPush(arr)">
+                <van-row class="flex-box">
+                  <van-col span="3">
+                    <userImage  class="about-me__avatar" :id="arr.userInfo.id" :img_url="arr.userInfo.img_url"  :user_name="arr.userInfo.name" fontSize="0.24"  width="0.65rem"  height="0.65rem"></userImage>
+                  </van-col>
+                  <van-col span="20"><span>{{ arr.content }}</span></van-col>
+                  <van-col span="1"><div class="flex-box" style="align-items: center; height: 100%; color: #b1b1b1;"><van-icon name="arrow" /></div></van-col>
+                </van-row>
+              </div>
+            </div>
+          </template>
+          <div style="height: 0.5rem;"></div>
+        </scroller> -->
+
+      </template>
+    </VanSkeleton>
+
+    <van-dialog v-model="selectpfdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="doSthForData.node_type">
+        <van-radio
+          v-for="(item, index) in selectpfList"
+          :key="index"
+          :name="item.value"
+          @click="clickpfTime(item)"
+          style="margin:.3rem 0 .3rem .4rem;font-size:.3rem"
+          icon-size="16px"
+        >
+          <span style="margin-left:.3rem">{{ item.label }}</span>
+        </van-radio>
+      </van-radio-group>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { mapGetters, mapState } from 'vuex';
+import moment from 'moment';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import {Tab, Tabs, Search} from 'vant'
+Vue.use(Tab).use(Tabs).use(Search)
+export default {
+  data() {
+    return {
+      skeletonLoad: false, // 过度骨架屏
+      backlogList: [],
+      commission: 0,
+      doSthForData: {
+        siteId: this.$userInfo().site_id,
+        employeeId: this.$userInfo().id,
+        page: 1, // 当期页
+        pageSize: 10, // 一页多少数据
+        type: 0
+      },
+      theBackupList: [],
+      // 分类相关
+      selectpfList: [
+        // 选择时间选项
+        { label: '全部待办', value: 0 },
+        { label: '目标制定', value: 1 },
+        { label: '指标确认', value: 2 },
+        { label: '结果录入', value: 4 },
+        { label: '评分', value: 5 },
+        { label: '审批', value: 9 },
+        { label: '绩效确认', value: 10 }
+      ],
+      selectpfdlg: false,
+      selectPftiText: '全部待办', // 默认值
+      pendingList: [] ,//提供给考核详情上下切换人员列表
+      plcList:[],
+      userInfo: this.$userInfo(),
+      type:'noEntering',
+      noEnteringList: [],
+      enteringList:[],
+      enteringList2:[],
+      page:1,
+    };
+  },
+
+  computed: {
+    ...mapGetters(['site_info'])
+  },
+  components: { VanSkeleton },
+  watch:{
+
+  },
+
+  created() {
+    console.log("获取未待办列表")
+    // this.getNoEntering()
+  },
+
+  methods: {
+    getNoEntering(callback) {
+      let hasMore = false;
+      let url = `/performance/review/job/employee/app/${this.$userInfo().site_id}/${this.$userInfo().id}`
+
+      this.$axiosUser('get', url, this.doSthForData).then(res => {
+        if(res.data.code == 1) {
+          let list = res.data.data.list;
+          this.skeletonLoad = false;
+          if(list && list.length > 0) {
+            list.forEach(item => {
+              let userInfo = this.$getEmployeeMapItem(item.employeeId)
+              item.userInfo = userInfo
+            })
+            if (this.doSthForData.page === 1) {
+              this.noEnteringList = list;
+            } else {
+              this.noEnteringList = this.noEnteringList.concat(list);
+            }
+            hasMore = list.length !== 10;
+            callback && callback(hasMore);
+          }
+        }
+      })
+    },
+
+    clickpfTime(item) {
+      // this.selectPftiText = item.label;
+      // this.doSthForData.page = 1;
+      // setTimeout(() => {
+      //   this.$refs.work_bench_scroller.triggerPullToRefresh();
+      // }, 50);
+      // this.selectpfdlg = false;
+    },
+
+    selectPfTIme() {
+      this.selectpfdlg = true;
+    },
+
+
+    // 上拉刷新
+    refresh(done) {
+      this.doSthForData.page = 1;
+      this.getNoEntering();
+    },
+    // 下拉加载
+    infinite(done) {
+      this.doSthForData.page++;
+      this.getNoEntering();
+    },
+
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+  },
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  height: calc(100% - 2.64rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+.all2{
+  height: calc(100% - 1.84rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  padding: 0.2rem;
+  background-color: #fff;
+  padding-left: 0.2rem;
+  font-size: 0.3rem;
+  z-index: 1;
+}
+.backlog_list_tit {
+  background-color: #f5f7fa;
+  padding: 0.2rem 0 0.2rem 0.2rem;
+  font-size: 0.28rem;
+}
+.backlog_list {
+  padding: 0.32rem 0.3rem 0.32rem 0.45rem;
+  box-sizing: border-box;
+  span {
+    font-size: 0.29rem;
+  }
+}
+
+.mb-2 {
+  margin-bottom: 0.2rem;
+}
+
+.list-item {
+  padding: 0.2rem;
+  background-color: #fff;
+  box-sizing: border-box;
+  border-bottom: 1px solid #f1f1f1;
+  font-size: 0.26rem;
+}
+</style>

+ 410 - 0
src/performance-07-19/components/workbenchcontent/backlog-副本.vue

@@ -0,0 +1,410 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="待办事项" left-text="" left-arrow @click-left="routerBak" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <template>
+        <van-tabs v-model="type">
+          <van-tab title="待处理" name="noEntering"></van-tab>
+          <van-tab title="已处理" name="entering"></van-tab>
+        </van-tabs>
+        <header class="performanceList flex-box-ce" v-show="type=='noEntering'">
+          <div class="flex-1">
+            当前待办:
+            <span v-if="commission > 0" style="color: #e42000;font-size: .29rem;">{{ commission }}条</span>
+          </div>
+          <div class="selector" @click="selectPfTIme">
+            <span>{{ selectPftiText }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+        </header>
+
+        <scroller v-show="type=='noEntering'" ref="work_bench_scroller" class="all" style="position: relative" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="backlogList">
+
+         <template v-if="plcList.length > 0 && doSthForData.node_type == 0 || doSthForData.node_type == 10">
+            <div class="backlog_list_tit">绩效确认</div>
+            <div v-for="(arr, keys) in plcList" :key="arr.id" :style="'z-index:' + (plcList.length - keys)" class="performanceList backlog_list" @click="openAffirm(arr)">
+              <van-row class="flex-box">
+                <van-col span="3">
+                  <userImage class="about-me__avatar" :id="userInfo.id" :img_url="userInfo.img_url"  :user_name="userInfo.name"  fontSize="0.24"  width="0.65rem"  height="0.65rem"></userImage>
+                </van-col>
+                <van-col span="20"><span>{{ arr.package_name }}【{{ arr.level_name }}】的绩效评分和等级,需要你检查确认</span></van-col>
+                <van-col span="1"><div class="flex-box" style="align-items: center; height: 100%; color: #b1b1b1;"><van-icon name="arrow" /></div></van-col>
+              </van-row>
+            </div>
+         </template>
+
+         <van-empty description="暂无绩效考核数据" v-if="backlogList.length == 0&&plcList.length==0" />
+         <template v-if="backlogList.length > 0">
+            <div v-for="(item, index) in backlogList" :key="index">
+              <div class="backlog_list_tit">{{ item.time }}</div>
+              <div v-for="(arr, keys) in item.list" :key="keys" :style="'z-index:' + (item.list.length - keys)" class="performanceList backlog_list" @click="clickPush(arr)">
+                <van-row class="flex-box">
+                  <van-col span="3">
+                    <userImage  class="about-me__avatar" :id="arr.userInfo.id" :img_url="arr.userInfo.img_url"  :user_name="arr.userInfo.name" fontSize="0.24"  width="0.65rem"  height="0.65rem"></userImage>
+                  </van-col>
+                  <van-col span="20"><span>{{ arr.content }}</span></van-col>
+                  <van-col span="1"><div class="flex-box" style="align-items: center; height: 100%; color: #b1b1b1;"><van-icon name="arrow" /></div></van-col>
+                </van-row>
+              </div>
+            </div>
+          </template>
+          <div style="height: 0.5rem;"></div>
+        </scroller>
+        <scroller v-show="type=='entering'" ref="work_bench_scroller2" class="all2" :on-refresh="refresh2" :on-infinite="infinite2" noDataText="我也是有底线的" :list="enteringList">
+            <div>
+              <div style="height: 0.2rem;background-color: rgb(245, 247, 250);"></div>
+              <div v-for="(item, index) in enteringList" :key="index"  class="performanceList backlog_list mb-2" @click="clickPush2(item)">
+                <van-row class="flex-box">
+                  <van-col span="3">
+                    <userImage  class="about-me__avatar" :id="item.userInfo.id" :img_url="item.userInfo.img_url"  :user_name="item.userInfo.name" fontSize="0.24"  width="0.65rem"  height="0.65rem"></userImage>
+                  </van-col>
+                  <van-col span="20">
+                    <div><span>{{ item.content }}</span></div>
+                    <div class="fontColorC" style="margin-top: 0.1rem;">{{item.update_time}}</div>
+                  </van-col>
+                  <van-col span="1"><div class="flex-box" style="align-items: center; height: 100%; color: #b1b1b1;">
+                    <van-icon name="arrow" /></div>
+                  </van-col>
+                </van-row>
+              </div>
+              <van-empty description="暂无绩效考核数据" v-if="enteringList.length == 0" />
+              <div v-else style="height: 0.5rem;"></div>
+            </div>
+        </scroller>
+      </template>
+    </VanSkeleton>
+
+    <van-dialog v-model="selectpfdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="doSthForData.node_type">
+        <van-radio
+          v-for="(item, index) in selectpfList"
+          :key="index"
+          :name="item.value"
+          @click="clickpfTime(item)"
+          style="margin:.3rem 0 .3rem .4rem;font-size:.3rem"
+          icon-size="16px"
+        >
+          <span style="margin-left:.3rem">{{ item.label }}</span>
+        </van-radio>
+      </van-radio-group>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { mapGetters, mapState } from 'vuex';
+import moment from 'moment';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import {Tab, Tabs, Search} from 'vant'
+Vue.use(Tab).use(Tabs).use(Search)
+export default {
+  data() {
+    return {
+      skeletonLoad: false, // 过度骨架屏
+      backlogList: [],
+      commission: 0,
+      doSthForData: {
+        status: 0, // 周期类型
+        page: 1, // 当期页
+        page_size: 10, // 一页多少数据
+        node_type: 0
+      },
+      theBackupList: [],
+      // 分类相关
+      selectpfList: [
+        // 选择时间选项
+        { label: '全部待办', value: 0 },
+        { label: '目标制定', value: 1 },
+        { label: '指标确认', value: 2 },
+        { label: '结果录入', value: 4 },
+        { label: '评分', value: 5 },
+        { label: '审批', value: 9 },
+        { label: '绩效确认', value: 10 }
+      ],
+      selectpfdlg: false,
+      selectPftiText: '全部待办', // 默认值
+
+      pendingList: [] ,//提供给考核详情上下切换人员列表
+      plcList:[],
+      userInfo: this.$userInfo(),
+      type:'noEntering',
+      enteringList:[],
+      enteringList2:[],
+      page:1,
+    };
+  },
+
+  computed: {
+    ...mapGetters(['site_info'])
+  },
+  components: { VanSkeleton },
+  watch:{
+    type(val){
+      this.page = 1;
+      this.doSthForData.page = 1;
+      if(val == 'noEntering'){
+        console.log("请求待处理数据")
+        setTimeout(() => {
+          this.$refs.work_bench_scroller.triggerPullToRefresh();
+        }, 50);
+      }else{
+        setTimeout(() => {
+          this.$refs.work_bench_scroller2.triggerPullToRefresh();
+        }, 50);
+      }
+    },
+  },
+  methods: {
+    openAffirm(item){
+      this.$router.push({ path: '/affirm', query: { pl_id: item.id,level_name:item.level_name,package_id: item.package_id } });
+    },
+
+    clickPush2(arr) {
+      let query={};
+      if(arr.node_type==4){
+        let name=arr.content.split(',')[0];
+        query={
+          pe_ids:JSON.stringify(arr.pe_ids.concat(arr.done_pe_ids)),
+          isUpdate:true,
+          Tit:name,
+          pendingList: JSON.stringify(this.enteringList2),
+          package_id:arr.package_id,
+          page:this.doSthForData.page,
+          activeName:this.doSthForData.node_type,
+        }
+      }else{
+        query={
+          id: arr.remark.packageEmployee_id,
+          Tit: arr.remark.package_name,
+          pendingList: JSON.stringify(this.enteringList2),
+          page:this.doSthForData.page,
+          activeName:this.doSthForData.node_type,
+        }
+      }
+      this.$router.push({ name:'performanceDetails',query:query});
+    },
+
+    clickPush(arr) {
+      let query={};
+      if(arr.node_type==4){
+        let name=arr.content.split(',')[0];
+        query={
+          pe_ids:JSON.stringify(arr.pe_ids.concat(arr.done_pe_ids)),
+          Tit:name,
+          pendingList: JSON.stringify(this.pendingList),
+          package_id:arr.package_id,
+          page:this.doSthForData.page,
+          activeName:this.doSthForData.node_type,
+        }
+      }else{
+        query={
+          id: arr.remark.packageEmployee_id,
+          Tit: arr.remark.package_name,
+          pendingList: JSON.stringify(this.pendingList),
+          page:this.doSthForData.page,
+          activeName:this.doSthForData.node_type,
+        }
+      }
+      this.$router.push({ name:'performanceDetails',query:query});
+    },
+
+    clickpfTime(item) {
+      this.selectPftiText = item.label;
+      this.doSthForData.page = 1;
+      setTimeout(() => {
+        this.$refs.work_bench_scroller.triggerPullToRefresh();
+      }, 50);
+      this.selectpfdlg = false;
+    },
+
+    selectPfTIme() {
+      this.selectpfdlg = true;
+    },
+
+    // 获取待办列表
+    getPlc() {
+      this.$axiosUser('get', '/api/pro/per/package/plc/list', {status: 0, page: 1, page_size: 1000 }).then(res => {
+        this.commission = this.commission + res.data.data.total; // 待办总数量
+        this.plcList = res.data.data.list
+      })
+    },
+
+    doSthForSb(callback) {
+      // 代办数量
+      let hasMore = false;
+      let params = this.doSthForData;
+      this.commission = 0;
+      this.plcList=[];
+      if(params.node_type==0||params.node_type==10){
+        this.getPlc()
+        if(params.node_type==10){
+          this.backlogList=[];
+          callback && callback(true);
+          return false
+        }
+      }
+      this.$axiosUser('get', '/api/pro/per/package/msg/agency', params,'v2').then(res => {
+          if (res.data.code == 1) {
+            let list = res.data.data.list;
+            let pendingList = [];
+            list.forEach(item => {
+              if(item.node_type==4){
+                let userInfo = this.$getEmployeeMapItem(item.first_employee_id)
+                item.userInfo = userInfo;
+                let name = item.content.split(',')[0]
+                pendingList.push({ name: userInfo.name, employeeID: '结果',pe_ids:item.pe_ids.concat(item.done_pe_ids),package_name: name,package_id:item.package_id });
+                return false
+              }
+              if (item.remark.employee_id) { // 被考核人
+                let userInfo = this.$getEmployeeMapItem(item.remark.employee_id)
+                item.userInfo = userInfo;
+                pendingList.push({ name: userInfo.name, employeeID: item.remark.packageEmployee_id, package_name: item.remark.package_name });
+              }
+            });
+            this.pendingList = pendingList;
+
+            this.commission = this.commission + res.data.data.total;
+            if (this.doSthForData.page === 1) {
+              this.theBackupList = list;
+            } else {
+              this.theBackupList = this.theBackupList.concat(list);
+            }
+            hasMore = list.length !== 10;
+            callback && callback(hasMore);
+            let data = this.theBackupList; //数据源
+            data.forEach(item => {
+              // 转换展示的时间格式
+              if (/\d{4}/g.exec(item.update_time)[0] == moment().format('YYYY')) {
+                item.tineKind = moment(new Date(item.update_time.replace(/-/g, '/')).getTime()).format('MM月DD日');
+              } else {
+                item.tineKind = moment(new Date(item.update_time.replace(/-/g, '/')).getTime()).format('YYYY年MM月DD日');
+              }
+            });
+            // 转换成可用格式
+            let bbt = [];
+            data.forEach(item => {
+              if (bbt[item.tineKind]) {
+                bbt[item.tineKind].list.push(item);
+              } else {
+                bbt[item.tineKind] = true;
+                bbt[item.tineKind] = {
+                  time: item.tineKind,
+                  list: []
+                };
+                bbt[item.tineKind].list.push(item);
+              }
+            });
+            let listdata = [];
+            for (let i in bbt) {
+              listdata.push(bbt[i]);
+            }
+            this.$nextTick(() => {
+              this.backlogList = listdata;
+            });
+            this.skeletonLoad = false;
+          }
+      })
+    },
+
+    getEnteringList(callback) {
+      // 代办数量
+      let hasMore = false;
+      let params = {
+        node_type: 0,
+        status: 1,
+        page: this.page,
+        page_size: 10
+      }
+      this.$axiosUser('get', '/api/pro/per/package/msg/agency', params,'v2').then(res => {
+            let list = res.data.data.list;
+            let pendingList=[]
+            list.forEach(item => {
+              if(item.node_type==4){
+                let userInfo = this.$getEmployeeMapItem(item.first_employee_id)
+                item.userInfo = userInfo;
+                let name=item.content.split(',')[0]
+                pendingList.push({ name: userInfo.name, employeeID: '结果',pe_ids:item.pe_ids.concat(item.done_pe_ids),package_name: name,package_id:item.package_id });
+                return false
+              }
+              if (item.remark.employee_id) { // 被考核人
+                let userInfo = this.$getEmployeeMapItem(item.remark.employee_id)
+                item.userInfo = userInfo;
+                pendingList.push({ name: userInfo.name, employeeID: item.remark.packageEmployee_id, package_name: item.remark.package_name });
+              }
+            });
+
+
+            this.enteringList2=pendingList
+            if (this.page === 1) {
+              this.enteringList = list;
+            } else {
+              this.enteringList = this.enteringList.concat(list);
+            }
+            hasMore = list.length !== 10;
+            callback && callback(hasMore);
+      })
+    },
+    // 上拉刷新
+    refresh(done) {
+      this.doSthForData.page = 1;
+      this.doSthForSb(done);
+    },
+    // 下拉加载
+    infinite(done) {
+      this.doSthForData.page++;
+      this.doSthForSb(done);
+    },
+    // 上拉刷新
+    refresh2(done) {
+      this.page = 1;
+      this.getEnteringList(done);
+    },
+    // 下拉加载
+    infinite2(done) {
+      this.page++;
+      this.getEnteringList(done);
+    },
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+  },
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  height: calc(100% - 2.64rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+.all2{
+  height: calc(100% - 1.84rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  padding: 0.2rem;
+  background-color: #fff;
+  padding-left: 0.2rem;
+  font-size: 0.3rem;
+  z-index: 1;
+}
+.backlog_list_tit {
+  background-color: #f5f7fa;
+  padding: 0.2rem 0 0.2rem 0.2rem;
+  font-size: 0.28rem;
+}
+.backlog_list {
+  padding: 0.32rem 0.3rem 0.32rem 0.45rem;
+  box-sizing: border-box;
+  span {
+    font-size: 0.29rem;
+  }
+}
+
+.mb-2 {
+  margin-bottom: 0.2rem;
+}
+</style>

+ 359 - 0
src/performance-07-19/components/workbenchcontent/backlog.vue

@@ -0,0 +1,359 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="待办事项" left-text="" left-arrow @click-left="routerBak" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <template>
+        <van-tabs v-model="type">
+          <van-tab title="待处理" name="noEntering"></van-tab>
+          <van-tab title="已处理" name="entering"></van-tab>
+        </van-tabs>
+
+        <header class="flex-box-ce">
+          <div class="flex-1">
+            当前待办:
+            <span v-if="commission > 0" style="color: #e42000; font-size: .29rem;">{{ commission }}条</span>
+          </div>
+          <div class="selector" @click="selectPfTIme">
+            <span>{{ selectPftiText }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+        </header>
+
+        <scroller v-if="type == 'noEntering'" ref="work_bench_scroller" class="all" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="noEnteringList">
+          <template v-if="noEnteringList && noEnteringList.length > 0">
+            <div class="list-item" v-for="(item, index) in noEnteringList" :key="index" @click="goHandlePage(item.reviewId, item.reviewIndicatorId, item.taskId, 'entering')">
+              <div class="node-type">
+                {{ item.nodeType | formatNodeType }}
+              </div>
+              <div class="flex-box-ce">
+                <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-right: 0.08rem;"></userImage>
+                <div class="flex-1 flex-box-ce">{{ item.reviewTitle }}绩效考核,被考核人{{item.employeeName}}的指标{{ item.title }},需要您确认</div>
+                <div class="flex-box" style="align-items: center; height: 100%; color: #b1b1b1;"><van-icon name="arrow" size="16px"/></div>
+              </div>
+            </div>
+          </template>
+          <van-empty v-else description="暂无绩效考核数据" />
+          <div style="height: 0.5rem;"></div>
+        </scroller>
+
+        <scroller v-if="type == 'entering'" ref="work_bench_scroller2" class="all" :on-refresh="refresh2" :on-infinite="infinite2" noDataText="我也是有底线的" :list="enteringList">
+
+              <template v-if="enteringList && enteringList.length > 0">
+                <div class="list-item" v-for="(item, index) in enteringList" :key="index" @click="goHandlePage(item.reviewId, item.reviewIndicatorId, item.taskId, 'noEntering')">
+                  <div class="node-type">
+                    {{ item.nodeType | formatNodeType }}
+                  </div>
+                  <div class="flex-box-ce">
+                    <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-right: 0.08rem;"></userImage>
+                    <div class="flex-1 flex-box-ce">{{ item.reviewTitle }}绩效考核,被考核人{{item.employeeName}}的指标{{ item.title }},已处理完毕</div>
+                    <div class="flex-box" style="align-items: center; height: 100%; color: #b1b1b1;"><van-icon name="arrow" size="16px"/></div>
+                  </div>
+                </div>
+              </template>
+
+              <van-empty description="暂无绩效考核数据" v-if="enteringList.length == 0" />
+              <div style="height: 0.5rem;"></div>
+        </scroller>
+
+      </template>
+    </VanSkeleton>
+
+    <van-dialog v-model="selectpfdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="doSthForData.type">
+        <van-radio
+          v-for="(item, index) in selectpfList"
+          :key="index"
+          :name="item.value"
+          @click="clickpfTime(item)"
+          style="margin:.3rem 0 .3rem .4rem;font-size:.3rem"
+          icon-size="16px"
+        >
+          <span style="margin-left:.3rem">{{ item.label }}</span>
+        </van-radio>
+      </van-radio-group>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { mapGetters, mapState } from 'vuex';
+import moment from 'moment';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import {Tab, Tabs, Search} from 'vant'
+Vue.use(Tab).use(Tabs).use(Search)
+export default {
+  data() {
+    return {
+      skeletonLoad: false, // 过度骨架屏
+      backlogList: [],
+      commission: 0,
+      doSthForData: {
+        siteId: this.$userInfo().site_id,
+        employeeId: this.$userInfo().id,
+        page: 1, // 当期页
+        pageSize: 15, // 一页多少数据
+        type: 0 // 0-全部 1-确认目标 2-录入结果 3-自评 4-互评 5-评分 6-审批 7-考核面谈
+      },
+      theBackupList: [],
+      // 分类相关
+      selectpfList: [
+        // 选择时间选项
+        { label: '全部', value: 0 },
+        { label: '确认目标', value: 1 },
+        { label: '录入结果', value: 2 },
+        { label: '自评', value: 3 },
+        { label: '互评', value: 4 },
+        { label: '评分', value: 5 },
+        { label: '审批', value: 6 }
+      ],
+      selectpfdlg: false,
+      selectPftiText: '全部', // 默认值
+      pendingList: [] ,//提供给考核详情上下切换人员列表
+      plcList:[],
+      userInfo: this.$userInfo(),
+      type:'noEntering',
+      noEnteringList: [],
+      enteringList:[],
+      enteringList2:[],
+      page: 1,
+    };
+  },
+
+  computed: {
+    ...mapGetters(['site_info'])
+  },
+
+  components: { VanSkeleton },
+
+  filters: {
+    formatNodeType(val) {
+      // targetConfirm-确认目标 resultInput-录入结果值 scoreSelf-自评 scoreEachOther-互评 score-评分 review-审批
+      if(val === 'targetConfirm') return '确认目标'
+      if(val === 'resultInput') return '录入结果'
+      if(val === 'scoreSelf') return '自评'
+      if(val === 'scoreEachOther') return '互评'
+      if(val === 'score') return '评分'
+      if(val === 'review') return '审批'
+    }
+  },
+
+  watch:{
+    type(val){
+      this.page = 1;
+      this.doSthForData.page = 1;
+      this.doSthForData.type = 0;
+      this.selectPftiText = '全部'; // 默认值
+      if(val == 'noEntering'){
+        console.log("请求待处理数据")
+        setTimeout(() => {
+          this.$refs.work_bench_scroller.triggerPullToRefresh();
+        }, 50);
+      }else{
+        setTimeout(() => {
+          this.$refs.work_bench_scroller2.triggerPullToRefresh();
+        }, 50);
+      }
+    },
+  },
+
+  activated() {
+    this.page = 1;
+    this.doSthForData.page = 1;
+    this.doSthForData.type = 0;
+    this.selectPftiText = '全部'; // 默认值
+    if(this.type == 'noEntering'){
+      console.log("请求待处理数据")
+      setTimeout(() => {
+        this.$refs.work_bench_scroller.triggerPullToRefresh();
+      }, 50);
+    }else{
+      setTimeout(() => {
+        this.$refs.work_bench_scroller2.triggerPullToRefresh();
+      }, 50);
+    }
+  },
+
+  created() {
+    console.log("获取未待办列表")
+    // this.getEnteringList()
+    // this.getNoEntering()
+  },
+
+  methods: {
+    getNoEntering(callback) {
+      let hasMore = false;
+      let url = `/performance/review/job/employee/app/${this.$userInfo().site_id}/${this.$userInfo().id}`
+      this.commission = 0;
+      this.$axiosUser('get', url, this.doSthForData).then(res => {
+        if(res.data.code == 1) {
+          this.commission = res.data.data.total;
+          let list = res.data.data.list;
+          this.skeletonLoad = false;
+          if(list && list.length > 0) {
+            list.forEach(item => {
+              let userInfo = this.$getEmployeeMapItem(item.employeeId)
+              item.userInfo = userInfo
+            })
+          }
+
+          if (this.doSthForData.page === 1) {
+            this.noEnteringList = list;
+          } else {
+            this.noEnteringList = this.noEnteringList.concat(list);
+          }
+          hasMore = list.length !== 10;
+          callback && callback(hasMore);
+        }
+      })
+    },
+
+    getEnteringList(callback) {
+      let hasMore = false;
+      this.commission = 0;
+      let url = `/performance/review/job/employee/app/history/${this.$userInfo().site_id}/${this.$userInfo().id}`
+      this.$axiosUser('get', url, this.doSthForData).then(res => {
+        if(res.data.code == 1) {
+          this.commission = res.data.data.total;
+          let list = res.data.data.list;
+          this.skeletonLoad = false;
+          if(list && list.length > 0) {
+            list.forEach(item => {
+              let userInfo = this.$getEmployeeMapItem(item.employeeId)
+              item.userInfo = userInfo
+            })
+          }
+
+          if (this.doSthForData.page === 1) {
+            this.enteringList = list;
+          } else {
+            this.enteringList = this.enteringList.concat(list);
+          }
+          hasMore = list.length !== 10;
+          callback && callback(hasMore);
+        }
+      })
+    },
+
+    clickpfTime(item) {
+      this.selectPftiText = item.label;
+      this.doSthForData.page = 1;
+      if(this.type === "noEntering") {
+        setTimeout(() => {
+          this.$refs.work_bench_scroller.triggerPullToRefresh();
+        }, 50);
+      }else {
+        setTimeout(() => {
+          this.$refs.work_bench_scroller2.triggerPullToRefresh();
+        }, 50);
+      }
+
+      this.selectpfdlg = false;
+    },
+
+    selectPfTIme() {
+      this.selectpfdlg = true;
+    },
+
+    goHandlePage(reviewId, reviewIndicatorId, taskId, type) {
+      this.$router.push({ name:'performanceDetails',query: { reviewId, reviewIndicatorId, taskId, type } });
+    },
+
+
+    // 上拉刷新
+    refresh(done) {
+      this.doSthForData.page = 1;
+      this.getNoEntering(done);
+    },
+
+    // 下拉加载
+    infinite(done) {
+      this.doSthForData.page++;
+      this.getNoEntering(done);
+    },
+
+
+
+    // 返回上一页
+    routerBak() {
+      this.$route_back();
+    },
+
+    // 上拉刷新
+    refresh2(done) {
+      this.doSthForData.page = 1;
+      this.getEnteringList(done);
+    },
+
+    // 下拉加载
+    infinite2(done) {
+      this.doSthForData.page++;
+      this.getEnteringList(done);
+    },
+
+  },
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  height: calc(100% - 2.64rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+.all2{
+  height: calc(100% - 1.84rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  padding: 0.2rem;
+  background-color: #fff;
+  padding-left: 0.2rem;
+  font-size: 0.3rem;
+  z-index: 1;
+  box-sizing: border-box;
+  border-bottom: 1px solid #f1f1f1;
+  border-top: 1px solid #f1f1f1;
+}
+
+.backlog_list_tit {
+  background-color: #f5f7fa;
+  padding: 0.2rem 0 0.2rem 0.2rem;
+  font-size: 0.28rem;
+}
+.backlog_list {
+  padding: 0.32rem 0.3rem 0.32rem 0.45rem;
+  box-sizing: border-box;
+  span {
+    font-size: 0.29rem;
+  }
+}
+
+.mb-2 {
+  margin-bottom: 0.2rem;
+}
+
+.list-item {
+  padding: 0.4rem 0.2rem 0.2rem 0.2rem;
+  background-color: #fff;
+  box-sizing: border-box;
+  border-bottom: 1px solid #f1f1f1;
+  font-size: 0.28rem;
+  position: relative;
+  .node-type {
+    position: absolute;
+    top: 0;
+    left: -0.2rem;
+    background-color: #ecf5ff;
+    width: 1.2rem;
+    text-align: center;
+    padding: 0.01rem 0.1rem;
+    color: #fff;
+    border-radius: 2px;
+    font-size: 0.26rem;
+    color: #26a2ff;
+    margin-left: 0.14rem;
+  }
+}
+</style>

+ 229 - 0
src/performance-07-19/components/workbenchcontent/messageInform.vue

@@ -0,0 +1,229 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="消息通知" left-text="" left-arrow @click-left="routerBak" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <template>
+        <header class="performanceList">
+          <van-tabs v-model="active" @change="minFormTabs" swipeable>
+            <van-tab v-for="(item, index) in minFormactive" :key="index">
+              <template #title>
+                <div style="position: relative;">
+                  {{item.name}}
+                  <em v-if="item.age > 0" class="cunt" :class="{ cunts: item.age > 99 }">
+                    <i v-if="item.age < 100">{{ item.age }}</i>
+                    <i v-else>99+</i>
+                  </em>
+                </div>
+              </template>
+            </van-tab>
+          </van-tabs>
+        </header>
+        <scroller ref="work_bench_scroller" class="all"  :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="backlogList">
+          <div>
+            <van-empty description="暂无绩效考核数据" v-if="backlogList.length == 0" />
+            <div v-else v-for="(item, index) in backlogList" :key="index">
+              <div class="backlog_list_tit">{{ item.time }}</div>
+              <div v-for="(arr, keys) in item.list" :key="keys" @click="unreadCli(arr)" :style="'z-index:' + (item.list.length - keys)" class="performanceList backlog_list">
+                <div class="flex-box">
+                  <userImage
+                    class="about-me__avatar"
+                    :id="arr.userInfo.id"
+                    :img_url="arr.userInfo.img_url"
+                    :user_name="arr.userInfo.name"
+                    fontSize="0.24"
+                    width="0.65rem"
+                    height="0.65rem"
+                  >
+                  </userImage>
+                  <span v-html="arr.content"></span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </scroller>
+      </template>
+    </VanSkeleton>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import moment from 'moment'
+import VanSkeleton from '@/performance/components/public/VanSkeleton'
+import { Tab, Tabs } from 'vant'
+Vue.use(Tab).use(Tabs)
+export default {
+  data () {
+    return {
+      skeletonLoad: false, // 过度骨架屏
+      minFormactive: [{ name: '未读', age: 0 }, { name: '已读' }],
+      active: 0,
+      backlogList: [],
+
+      unread: [], // 未处理
+      read: [], // 已处理
+      ccData: {
+        type: '1,2',
+        status: 0, // 状态
+        page: 1, // 当期页
+        page_size: 10 // 一页多少数据
+      },
+      theBackupListcc: []
+    }
+  },
+  components: { VanSkeleton },
+  methods: {
+    unreadCli (item) {
+      if (this.active == 0) {
+        let data = {
+          id: item.id,
+          type: item.type,
+          employee_id: item.employee_id
+        }
+        this.$router.push({
+          name: 'performanceDetails',
+          query: { id: item.remark.packageEmployee_id, Tit: item.remark.package_name, paths: 'messageInform', data: JSON.stringify(data) }
+        })
+      } else {
+        this.$router.push({ name: 'performanceDetails', query: { id: item.remark.packageEmployee_id, Tit: item.remark.package_name } })
+      }
+    },
+    cc (callback) {
+      // 抄送
+      let hasMore = false
+      let params = this.ccData
+      this.$axiosUser('get', '/api/pro/per/package/msg/cc', params).then(res => {
+        if (res.data.code == 1) {
+          let list = res.data.data.list
+          list.forEach(item => {
+            if (item.remark.employee_id) { // 被考核人
+              item.userInfo = this.$getEmployeeMapItem(item.remark.employee_id)
+            }
+          })
+          if (this.ccData.page === 1) {
+            this.theBackupListcc = list
+          } else {
+            this.theBackupListcc = this.theBackupListcc.concat(list)
+          }
+          hasMore = list.length !== 10
+          callback && callback(hasMore)
+          let data = this.theBackupListcc
+          if (this.active == 0) {
+            this.minFormactive[0].age = res.data.data.total
+          }
+          this.format(data)
+          this.skeletonLoad = false
+        }
+      })
+    },
+    minFormTabs (key) {
+      this.ccData.page = 1
+      this.ccData.status = key
+      this.cc()
+    },
+    format (data) {
+      data.forEach(item => {
+        // 转换展示的时间格式
+        if (/\d{4}/g.exec(item.update_time)[0] == moment().format('YYYY')) {
+          item.tineKind = moment(new Date(item.update_time.replace(/-/g, '/')).getTime()).format('MM月DD日')
+        } else {
+          item.tineKind = moment(new Date(item.update_time.replace(/-/g, '/')).getTime()).format('YYYY年MM月DD日')
+        }
+      })
+      // 转换成可用格式
+      let bbt = []
+      data.forEach(item => {
+        if (bbt[item.tineKind]) {
+          bbt[item.tineKind].list.push(item)
+        } else {
+          bbt[item.tineKind] = true
+          bbt[item.tineKind] = {
+            time: item.tineKind,
+            list: []
+          }
+          bbt[item.tineKind].list.push(item)
+        }
+      })
+      let listdata = []
+      for (let i in bbt) {
+        listdata.push(bbt[i])
+      }
+      this.$nextTick(() => {
+        this.backlogList = listdata
+      })
+    },
+    // 上拉刷新
+    refresh (done) {
+      this.ccData.page = 1
+      this.cc(done)
+    },
+    // 下拉加载
+    infinite (done) {
+      this.ccData.page++
+      this.cc(done)
+    },
+    vantabTit (data) {
+      let num = data.age ? '(' + data.age + ')' : ''
+      return data.name + num
+    },
+    // 返回上一页
+    routerBak () {
+      this.$route_back()
+    }
+  },
+}
+</script>
+
+<style scoped lang="less">
+.all {
+  height: calc(100% - 1.82rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  background-color: #fff;
+  padding-left: 0.2rem;
+  font-size: 0.3rem;
+  z-index: 1;
+}
+.backlog_list_tit {
+  background-color: #f5f7fa;
+  padding: 0.2rem 0 0.2rem 0.2rem;
+  font-size: 0.28rem;
+}
+.backlog_list {
+  padding: 0.32rem 0.45rem;
+  span {
+    padding-left: 0.25rem;
+    font-size: 0.29rem;
+  }
+}
+.cunt {
+  background-color: #f15532;
+  text-align: center;
+  line-height: 0.39rem;
+  width: 0.4rem;
+  height: 0.4rem;
+  border-radius: 50%;
+  position: absolute;
+  top: 0.26rem;
+  left: 2.1rem;
+  color: #fff;
+  font-size: 0.24rem;
+  font-style: normal;
+  i {
+    font-style: normal;
+  }
+}
+.cunts {
+  // padding: 0 0.04rem !important;
+  // width: auto !important;
+  // max-width: 0.8rem;
+  // overflow: hidden;
+  // text-overflow: ellipsis;
+  // white-space: nowrap;
+  width: auto !important;
+  padding: 0 .04rem 0 .08rem !important;
+  border-radius: .8rem !important;
+}
+</style>

+ 322 - 0
src/performance-07-19/components/workbenchcontent/workList_details.vue

@@ -0,0 +1,322 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar :title="titName" left-text="" left-arrow @click-left="$route_back"></van-nav-bar>
+    <VanSkeleton :skeLoad="skeletonLoad">
+     <header class="performanceList">
+        <div class="flex-box-ce selectItem">
+          <div class="flex-1" @click="selectUser = true">
+            <span>{{ userName }}</span>
+            <van-icon name="arrow-down" class="arrow-down" />
+          </div>
+          <div class="flex-1" @click="show_dept_selector = true">
+            <span>{{ deptName }}</span>
+            <van-icon name="arrow-down" class="arrow-down" />
+          </div>
+          <div class="flex-1" @click="selectType = true">
+            <span>{{ doingText }}</span>
+            <van-icon name="arrow-down"  class="arrow-down"/>
+          </div>
+        </div>
+      </header>
+      <scroller :isInitRefresh="false" ref="work_bench_scroller" class="all" noDataText="我也是有底线的" :list="workList_details" :on-refresh="refresh" :on-infinite="infinite">
+<!--        <div class="wlddeptperson">
+          <span v-if="selected_data.dept.length > 0">筛选条件:{{ selected_data.dept[0].dept_name }} | 共{{ workList_details.length }}人</span>
+          <span v-else>参与考核:{{ workList_details.length }}人</span>
+        </div> -->
+        <van-empty description="暂无绩效考核数据" v-if="workList_details.length == 0" />
+        <div v-else>
+          <div
+            v-for="(item, index) in workList_details"
+            :key="index"
+            @click="unreadCli(item)"
+            :style="'z-index:' + (workList_details.length - index)"
+            class="performanceList flex-box flex-d-center wld_list"
+          >
+            <div class="flex-box">
+              <div class="me_list_img">
+                <userImage
+                  class="about-me__avatar"
+                  :id="item.employee_id"
+                  :img_url="item.img_url"
+                  :user_name="item.name"
+                  fontSize="0.25"
+                  width="0.65rem"
+                  height="0.65rem"
+                ></userImage>
+              </div>
+              <div style="padding-left:.25rem;">
+                <span style="font-size:.3rem;">{{ item.name }}</span>
+                <br />
+                <span v-if="item.dept_list.length > 0" class="font-flex-word" style="width: 4rem;display:inline-block;">
+                  <span style="font-size:.25rem;" v-for="(arr, att) in item.dept_list" :key="att">
+                    {{ arr.dept_name }}
+                    <span v-if="item.dept_list.length - att > 1">,</span>
+                  </span>
+                </span>
+                <div style="font-size:.25rem;color:#828282;" v-if="!item.relevance_group.delete_time">{{ item.relevance_group.name }}</div>
+                <div style="font-size:.25rem;color:#F15532;" v-else>该考评模板已被删除</div>
+              </div>
+            </div>
+            <div class="wld_tag_bisque wld_tag">{{ getStr(item.doing_id) }}</div>
+          </div>
+        </div>
+      </scroller>
+    </VanSkeleton>
+    <!-- 类型 -->
+    <van-dialog v-model="selectType" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="bagParams.doing_id">
+        <div v-for="(item, index) in typeOption" :key="index">
+          <van-radio :name="item.value" @click="onChangeType(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.text }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+    <!-- 人员选择 -->
+    <EmployeeSelector
+      title="选择人员"
+      :visible.sync="selectUser"
+      @confirm="confirmCreator"
+      :can_select_dept="false"
+      :multi="false"
+      :selected.sync="selected_data2"
+      :employee_list="employee_list"
+      :is_employee_list="true"
+    ></EmployeeSelector>
+     <!-- 部门选择 -->
+   <EmployeeSelector
+      :multi="false"
+      :close_clear_data="false"
+      ref="selector"
+      :can_select_employee="false"
+      :can_select_dept="true"
+      :dept_multi="false"
+      @confirm="confirm"
+      :visible.sync="show_dept_selector"
+      :selected.sync="selected_data"
+      :append_body="true"
+      :isShowDepts="true"
+    ></EmployeeSelector>
+  </div>
+</template>
+
+<script>
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import { _debounce } from '@/utils/auth';
+export default {
+  components: {EmployeeSelector, VanSkeleton},
+  data() {
+    return {
+      skeletonLoad: true, //过度骨架屏
+      workList_details: [],
+      workDbackords: [],
+      keyword: '', //搜索关键字
+      selected_data: { dept: [], employee: [] }, //传入已选部门
+      show_dept_selector: false, //选择部门开关
+      bagParams: {
+        package_id: this.$route.query.bagId,
+        // dept_ids: null,
+        dept_ids: [], //部门id
+        group_ids: [], //考评模板ID
+        doing_id: 0, //状态ID
+        employee_ids: [], //搜索人员ID
+        page: 1,
+        page_size: 10
+      },
+      titName: this.$route.query.bagName,
+      deptName: '全公司',
+      selectType: false,
+      typeOption: [
+        //导航
+        { value: 0, text: '全部' },
+        { value: 1, text: '目标制定' },
+        { value: 2, text: '目标确认' },
+        { value: 3, text: '执行中' },
+        { value: 4, text: '结果值录入' },
+        { value: 5, text: '评分' },
+        { value: 9, text: '审批' },
+        { value: 11, text: '结束' }
+      ],
+      doingText: '全部',
+
+      userName:'全部人员',
+      selectUser: false,
+      employee_list:[],
+      selected_data2: { dept: [], employee: [] }, //传入已选部门
+    };
+  },
+  methods: {
+    confirmCreator(data) {
+      let employee_ids = [];
+      this.userName = '全部人员';
+      if (data.employee !== null && data.employee.length != 0) {
+        employee_ids.push(data.employee[0].id);
+        this.userName = data.employee[0].name;
+      }
+      this.selected_data2 = data;
+      this.bagParams.employee_ids = JSON.stringify(employee_ids);
+      this.selectUser = false;
+      this.$refs.work_bench_scroller.triggerPullToRefresh();
+    },
+    onChangeType(e) {
+      this.doingText = e.text;
+      this.selectType = false;
+      this.$refs.work_bench_scroller.triggerPullToRefresh();
+    },
+    getStr(type) {
+      let is = '';
+      switch (type) {
+        case 1:
+          is = '目标制定';
+          break;
+        case 2:
+          is = '目标确认';
+          break;
+        case 3:
+          is = '执行中';
+          break;
+        case 4:
+          is = '结果值录入';
+          break;
+        case 5:
+          is = '评分';
+          break;
+        case 9:
+          is = '审批';
+          break;
+        case 11:
+          is = '结束';
+          break;
+      }
+      return is;
+    },
+    unreadCli(item) {
+      this.$router.push({ name: 'performanceDetails', query: { assId: this.bagParams.package_id, staffId: item.employee_id, Tit: this.titName } });
+    },
+    confirm(data) {
+      //筛选部门
+      let dept_ids = [];
+      this.deptName = '全公司';
+      if (data.dept !== null && data.dept.length != 0) {
+        dept_ids.push(data.dept[0].dept_id);
+        this.deptName = data.dept[0].dept_name;
+      }
+      this.selected_data = data;
+      this.bagParams.dept_ids = JSON.stringify(dept_ids);
+      this.show_dept_selector = false;
+      this.$refs.work_bench_scroller.triggerPullToRefresh();
+    },
+    bagList(callback) {
+      let params = this.bagParams;
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/info_v3', params)
+        .then(res => {
+          let list = res.data.data.list;
+          list.forEach(item => {
+            let user = this.$getEmployeeMapItem(item.employee_id)
+            item.dept_list = user.employee_detail.dept_list;
+            item.name = user.name;
+            item.img_url = user.img_url;
+          });
+          if (params.page === 1) {
+            this.workList_details = list;
+          } else {
+            this.workList_details = this.workList_details.concat(list);
+          }
+          hasMore = list.length !== 10;
+          callback && callback(hasMore);
+        })
+        .finally(() => {
+          this.skeletonLoad = false;
+        });
+    },
+    // 上拉刷新
+    refresh(done) {
+      this.bagParams.page = 1;
+      this.bagList(done);
+    },
+    // 下拉加载
+    infinite(done) {
+      this.bagParams.page++;
+      this.bagList(done);
+    },
+    keyInp: _debounce(function() {
+      this.workList_details = this.workDbackords.filter(item => item.employee_name.includes(this.keyword));
+    }),
+    getInitData(){
+      this.$axiosUser('get', '/api/pro/per/package/info_v3_aid', {package_id:this.bagParams.package_id}).then(res => {
+        this.employee_list=res.data.data.employees;
+      })
+    },
+  },
+  mounted() {
+    this.bagParams.package_id = this.$route.query.bagId;
+    this.titName = this.$route.query.bagName;
+    this.getInitData();
+  },
+  activated() {
+  	this.skeletonLoad = true;
+  	this.bagList();
+  }
+  
+};
+</script>
+
+<style scoped lang="less">
+.arrow-down{
+  position: relative;
+  top: -3px;
+}  
+.selectItem {
+  font-size: 0.32rem;
+  text-align: center;
+  padding: 0.24rem 0;
+}
+.selectItem span {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: inline-block;
+  max-width: 2rem;
+}
+.all {
+  height: calc(100% - 2rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+header {
+  background-color: #fff;
+  z-index: 1;
+}
+.wlddeptperson {
+  background-color: rgb(245, 245, 245);
+  padding: 0.13rem 0.2rem;
+  span {
+    color: #8c8c8c;
+    font-size: 0.25rem;
+  }
+}
+.wld_tag {
+  min-width: 1.5rem;
+  font-size: 0.25rem;
+  height: 0.4rem;
+  text-align: center;
+  line-height: 0.4rem;
+  margin-top: 0.3rem;
+}
+.wld_tag_bisque {
+  background-color: #fff1e0;
+  color: #f7b461;
+}
+.wld_tag_green {
+  background-color: #e2e2e2;
+  color: #929292;
+}
+.wld_list {
+  padding: 0.15rem 0.3rem;
+  .me_list_img {
+    margin-top: 0.15rem;
+  }
+}
+</style>

+ 199 - 0
src/performance-07-19/utils/auth.js

@@ -0,0 +1,199 @@
+import store from '@/store'
+import {getUserData} from '@/utils/auth'
+/* 角色*/
+/*
+创始人 creator
+主管理员 masterAdministrator
+子管理员 childAdministrator
+部门管理员 deptManager
+员工 employee
+*/
+// 权限
+/*
+1   绩效考核
+2   OKR
+3   管理范围 全公司
+4   管理范围 所在部门以及下级部门
+5   管理范围 特定部门
+6   考核管理 可见考核结果
+7   考核管理 发起考核
+8   考核管理 开始评分
+9   考核管理 调整结果
+10  考核管理 调整等级
+11  考核管理 导出报表
+12  指标库管理
+13  指定考评模板管理
+14  全部考评模板管理
+15  基础设置
+16  绩效报表
+*/
+
+// 获取当前登录者在绩效系统中的身份
+export function getRole(type) {
+  /* type为判断哪些角色*/
+
+  var role = window.plus ? plus.storage.getItem('role') : localStorage.getItem('role')
+  let is = false;
+  switch (type) {
+    case 1: // 判断是否是主子管理员
+      if (role == 'masterAdministrator' || role == 'childAdministrator') {
+        is = true
+      }
+      break
+    case 2: // 判断是否是部门管理员
+      if (role == 'deptManager') {
+        is = true
+      }
+      break
+    case 3: // 判断是否是员工
+      if (role == 'employee') {
+        is = true
+      }
+      break
+    case 4: // 判断是否是创始人
+      if (role == 'creator') {
+        is = true
+      }
+      break
+  }
+  return is
+}
+// 判断当前登录者是否有某项权限
+export function getPermis(type) {
+  /* type为传入的权限id*/
+  let jurisdictions = getUserData().per_permission.permission.map((item) => {
+    return item.id
+  })
+  return jurisdictions.indexOf(type) >= 0
+}
+
+// 判断是否具有权限
+export function isAuthoritys_jx(id, arr) { // 判断是否为某项权限:id为权限ID,arr为数据源
+  var jurisdictions
+  if (arr) {
+    jurisdictions = arr.map((item) => {
+      return item.id
+    })
+  } else { // 当没有指定数据源,代表判断当前登录者,如果登陆者是创始人,直接返回真
+    jurisdictions = getUserData().per_permission.permission.map((item) => {
+      return item.id
+    })
+  }
+  if (typeof(id) === 'number') { // 单个权限
+    return jurisdictions.indexOf(id) >= 0
+  } else { // 多个权限一起判断,如果有一个真就返回真
+    const is = jurisdictions.some(item => {
+      if (id.indexOf(item) >= 0) {
+        return true
+      }
+    })
+    return is
+  }
+}
+
+// 自动积分相关
+export function returnStr3(item, index, arr = [], expression) { //列举 百分比
+  let str = '';
+  let point = returnPoint(item.point); //得分
+  let Lieh = expression.compare == 1 ? '【结果值】' : expression.compare == 2 ? '【结果值/目标值】' : '【结果值-目标值】'
+  let jiajian = item.selectVal == 1 ? '加' : '扣';
+  // 公式开始
+  if (index == 0) {
+    str = `${Lieh}比【目标值】每增加${item.plusNum}时,【得分=${point}】${jiajian}${item.numVal},最多${jiajian}${item.maxNum}<br/>`
+    return str
+  }
+  if (index == 1) { //公式中间
+    str = `${Lieh}比【目标值】每减少${item.plusNum}时,【得分=${point}】${jiajian}${item.numVal},最多${jiajian}${item.maxNum}<br/>`
+    return str
+  }
+  //公式结束
+  if (index == 2) {
+    str = `${Lieh}${item.selectVal=='1'?'>':'<'}${item.plusNum},得分=0<br/>`
+    return str
+  }
+};
+export function returnStr2(item, index, arr = [], expression) { //列举 公式
+  let str = '';
+  let point = returnPoint(item.point); //得分
+  let Lieh = expression.compare == 1 ? '【结果值】' : expression.compare == 2 ? '【结果值/目标值】' : '【结果值-目标值】'
+  let val = expression.reference == '1' ? item.selectRefer : '【' + item.referStr + '】'
+  // 公式开始
+  if (index == 0) {
+    str = `${Lieh}==${val},得分=${point}<br/>`
+    return str
+  }
+  //公式结束
+  if (index == arr.length - 1) {
+    str = `否在,得分=${point}<br/>`
+    return str
+  }
+  if (index != 0 && index != arr.length - 1) { //公式中间
+    str = `${Lieh}==${val},得分=${point}<br/>`
+    return str
+  }
+};
+export function returnStr(item, index, arr = [], expression) { //连续区间 公式
+  let str = '';
+  let point = returnPoint(item.point); //得分
+  let Lieh = expression.compare == 1 ? '【结果值】' : expression.compare == 2 ? '【结果值/目标值】' : '【结果值-目标值】'
+  let val = expression.reference == '1' ? item.selectRefer : '【' + item.referStr + '】'
+  let slectSymbol = item.slectSymbol == '>' ? '>=' : item.slectSymbol == '≥' ? '>' : '='
+  // 公式开始
+  if (index == 0) {
+    str = `${Lieh}${slectSymbol}${val},得分=${point}<br/>`
+    return str
+  }
+  //公式结束
+  if (index == arr.length - 1) {
+    str = `${item.refer}${item.symbol}${Lieh},得分=${point}<br/>`
+    return str
+  }
+  if (index != 0 && index != arr.length - 1) {
+    let upItemVal = expression.reference == '1' ? arr[index - 1].selectRefer : '#' + arr[index - 1].referStr +
+      '#'; //上一个数据
+    //公式中间
+    let symbol = item.symbol == '≥' ? '>=' : item.symbol
+    if (item.slectSymbol == '=') {
+      str = `${Lieh}==${val},得分=${point}<br/>`
+    } else {
+      str = `${upItemVal}${symbol}${Lieh}${slectSymbol}${val},得分=${point}<br/>`
+    }
+    return str
+  }
+};
+export function returnPoint(point) {
+  let str = '';
+  if (!point) {
+    return str
+  }
+  point.forEach(e => {
+    str += e
+  })
+  return str
+};
+export function getExpressionStr(arr) {
+  let expressionStr = '';
+  if (arr.logic_type == 1) {
+    let logic_section = JSON.parse(JSON.stringify(arr.logic_section))
+    logic_section.forEach((item, index) => {
+      expressionStr += returnStr(item, index, logic_section, arr)
+    })
+  }
+  if (arr.logic_type == 2) {
+    let logic_enum = JSON.parse(JSON.stringify(arr.logic_enum))
+    logic_enum.forEach((item, index) => {
+      expressionStr += returnStr2(item, index, logic_enum, arr)
+    })
+  }
+  if (arr.logic_type == 3) {
+    let logic_percent = JSON.parse(JSON.stringify(arr.logic_percent))
+    logic_percent.forEach((item, index) => {
+      expressionStr += returnStr3(item, index, logic_percent, arr)
+    })
+  }
+  if (arr.logic_type == 4) {
+    let logic_eq = JSON.parse(JSON.stringify(arr.logic_eq))
+    expressionStr = `得分=${returnPoint(logic_eq)}`;
+  }
+  return expressionStr
+};

+ 216 - 0
src/performance-07-19/view/handleDetails - 副本.vue

@@ -0,0 +1,216 @@
+<template>
+  <div class="all">
+    <van-nav-bar title="处理详情" left-text="返回" left-arrow @click-left="$route_back" />
+   <div class="steps">
+   	  <div class="step-item">
+   	    <span class="step-dot"></span>
+   	    <div class="step-content">
+   	      <div class="step-title">
+            确认目标
+          </div>
+   	      <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+   	      <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+   	      <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+   	      <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+   	      <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+   	    </div>
+   	    <div class="step-line"></div> <!-- 添加这一行 -->
+   	  </div>
+   		<div class="step-item">
+   		  <span class="step-dot"></span>
+   		  <div class="step-content">
+   		    <div class="step-title">录入结果</div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+   		  </div>
+   		  <div class="step-line"></div> <!-- 添加这一行 -->
+   		</div>
+   		<div class="step-item">
+   		  <span class="step-dot"></span>
+   		  <div class="step-content">
+   		    <div class="step-title">自评</div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+          <div class="step-desc">
+            <div>张三,已处理</div>
+            <div>意见,暂无意见</div>
+          </div>
+   		  </div>
+   		  <div class="step-line"></div> <!-- 添加这一行 -->
+   		</div>
+   	</div>
+
+
+  </div>
+</template>
+
+<script>
+
+  export default {
+    data() {
+      return {
+        showData: [],
+        recordList: [
+          {content: null, employee_id: 1977, remark:"调整目标(修改内容)", target_ids: [], time:"2025-02-15 17:35:56"},
+          {content: null, employee_id: 1977, remark:"调整目标(修改内容)", target_ids: [], time:"2025-02-15 17:35:21"},
+        ]
+      }
+    },
+    created() {
+      this.showData = this.$route.query.showData;
+    }
+  }
+</script>
+
+<style scoped lang="less">
+  .all {
+    width: 100%;
+    height: 100%;
+  }
+  // .handle-list {
+  //   width: 100%;
+  //   background-color: red;
+  //   .line {
+  //     margin: 0.2rem;
+  //     width: 10px;
+  //     height: auto;
+  //     background-color: #ccc;
+  //   }
+      .step-item {
+  		  position: relative;
+  		  display: flex;
+  		  align-items: center;
+  		  margin-bottom: 0.1rem;
+        padding: 0.2rem;
+        box-sizing: border-box;
+  		}
+
+  		.step-dot {
+  		  width: 0.2rem;
+  		  height: 0.2rem;
+  		  border-radius: 50%;
+  		  background-color: #3c9cff;
+  		  margin-right: 0.2rem;
+  		  flex-shrink: 0; /* 防止圆点挤压内容 */
+  		  align-self: flex-start; /* 将圆点对齐到左上角 */
+  		}
+
+  		.step-content {
+        flex: 1;
+  		  display: flex;
+  		  flex-direction: column;
+  		}
+
+  		.step-title {
+        width: 1.6rem;
+        text-align: center;
+  		  font-weight: bold;
+  		  font-size: 0.28rem;
+        padding: 0.05rem 0.1rem;
+        box-sizing: border-box;
+        color: #3c9cff;
+        border: 1px solid #3c9cff;
+        border-radius: 5px;
+        margin-bottom: 0.2rem;
+  		}
+  		.step-desc {
+  		  font-size: 0.26rem;
+  		  margin-bottom: 0.1rem;
+        background-color: #f7f7f7;
+        padding: 0.1rem;
+        box-sizing: border-box;
+        border-radius: 5px;
+  		  color: #999;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+  		}
+
+  		.step-line {
+  		  position: absolute;
+  		  top: 0.5rem; /* 根据圆点的尺寸调整 */
+  		  left: 0.28rem; /* 将竖线居中对齐 */
+  		  bottom: -20px; /* 调整竖线的长度 */
+  		  width: 1px;
+        border-left: 1px dashed #ccc;
+  		}
+  		.step-item:last-child .step-line{
+  			display: none;
+  		}
+
+
+
+      .modTit {
+        background-color: #efefef;
+        padding: 0.27rem 0.3rem 0.15rem;
+        font-size: 0.28rem;
+        color: #8a8a8a;
+      }
+      .modCont {
+        padding: 0.3rem;
+        background-color: #fff;
+      }
+      .stanif {
+        .stanTit {
+          font-size: 0.26rem;
+          color: #222;
+          margin: 0.2rem 0 0.08rem 0;
+        }
+        .standara {
+          border: 1px solid #efefef;
+          border-radius: 5px;
+          .standarapad {
+            display: inline-block;
+            padding: 0.2rem;
+            font-size: 0.27rem;
+          }
+        }
+      }
+</style>

+ 612 - 0
src/performance-07-19/view/handleDetails.vue

@@ -0,0 +1,612 @@
+<template>
+  <div class="all">
+    <van-nav-bar title="处理详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="overall">
+      <scroller>
+        <div class="modTit">
+          审批详情
+        </div>
+        <ol class="steps">
+          <template v-for="node in showData.nodes">
+            <template v-if="node.type === 'targetConfirms'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'target_confirm' ? 'active' : ''">
+                  1.确认目标{{ showData.businessStatus === 'target_confirm' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.children && node.children.length > 0">
+                    <div class="content-info" v-for="child in node.children" :key="child.id">
+                      <div class="user-type" v-if="child.tasks && child.tasks.length > 0">
+                        {{ child.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-if="child.tasks && child.tasks.length > 0">
+                        <div class="info" v-for="task in child.tasks" :key="task.taskId">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <!-- <el-tooltip effect="dark" placement="right">
+                              <div v-html="task.comment" slot="content" style="max-width: 300px">
+                              </div>
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </el-tooltip> -->
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                          </div>
+
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                  <div class="content" v-else>
+                    未开始
+                  </div>
+                </li>
+              </template>
+
+              <template v-if="!node.enable">
+                <li class="title">1.确认目标</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+            </template>
+
+            <template v-if="node.type === 'resultInput'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'result_input' ? 'active' : ''">
+                  2.录入结果{{ showData.businessStatus === 'result_input' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.tasks && node.tasks.length > 0">
+                    <div class="content-info">
+                      <div class="user-type">
+                        {{ node.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-for="task in node.tasks" :key="task.taskId">
+                        <div class="info">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }},结果值:{{ task.result || '--'}}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                           <!-- <el-tooltip effect="dark" placement="right">
+                              <div v-html="task.comment" slot="content" style="max-width: 300px">
+                              </div>
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </el-tooltip> -->
+                          </div>
+                        </div>
+
+                        <div class="files" v-if="task.files && task.files.length > 0">
+                          <div class="file-title">附件列表</div>
+                          <div class="file-list">
+                            <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                              <!-- {{ file | filterFileName }} -->
+                              {{ '附件' + (index + 1) }}
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+
+
+                  </div>
+                  <div v-else class="content">
+                    未开始
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">2.录入结果</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'scoreSelf'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'score_self' ? 'active' : ''">
+                  3.自评{{ showData.businessStatus === 'score_self' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.tasks && node.tasks.length > 0">
+                    <div class="content-info">
+                      <div class="user-type">
+                        {{ node.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-for="task in node.tasks" :key="task.taskId">
+                        <div class="info">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }},评分:{{ task.score || '--' }}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            <!-- <el-tooltip effect="dark" placement="right">
+                              <div v-html="task.comment" slot="content" style="max-width: 300px">
+                              </div>
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </el-tooltip> -->
+                          </div>
+                        </div>
+
+                        <div class="files" v-if="task.files && task.files.length > 0">
+                          <div class="file-title">附件列表</div>
+                          <div class="file-list">
+                            <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                              <!-- {{ file | filterFileName }} -->
+                              {{ '附件' + (index + 1) }}
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                  <div v-else class="content">
+                    未开始
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">3.自评</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'scoreEachOther'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'score_each_other' ? 'active' : ''">
+                  4.互评{{ showData.businessStatus === 'score_each_other' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.tasks && node.tasks.length > 0">
+                    <div class="content-info">
+                      <div class="user-type">
+                        {{ node.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-for="task in node.tasks" :key="task.taskId">
+                        <div class="info">
+                          <div class="info-left">
+                            <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                              {{ task.state === 'created' ? '进行中' : '已完成' }},
+                            </span>
+                            {{ task.assigneeName }},评分:{{ task.score || '--' }}
+                          </div>
+                          <div class="info-right" v-if="task.comment">
+                            <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            <!-- <el-tooltip effect="dark" placement="right">
+                              <div v-html="task.comment" slot="content" style="max-width: 300px">
+                              </div>
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </el-tooltip> -->
+                          </div>
+                        </div>
+
+                        <div class="files" v-if="task.files && task.files.length > 0">
+                          <div class="file-title">附件列表</div>
+                          <div class="file-list">
+                            <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                              {{ '附件' + (index + 1) }}
+                            </div>
+                          </div>
+                        </div>
+
+                      </div>
+                    </div>
+                  </div>
+                  <div v-else class="content">
+                    未开始
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">4.互评</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'scores'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'score' ? 'active' : ''">
+                  5.评分{{ showData.businessStatus === 'score' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.children && node.children.length > 0">
+                    <div class="content-info" v-for="child in node.children" :key="child.id">
+                      <div class="user-type" v-if="child.tasks && child.tasks.length > 0">
+                        {{ child.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-if="child.tasks && child.tasks.length > 0">
+                        <template v-for="task in child.tasks">
+                          <div class="info" :key="task.taskId">
+                            <div class="info-left">
+                              <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                                {{ task.state === 'created' ? '进行中' : '已完成' }},
+                              </span>
+                              {{ task.assigneeName }},评分:{{ task.score }}
+                            </div>
+                            <div class="info-right" v-if="task.comment">
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                              <!-- <el-tooltip effect="dark" placement="right">
+                                <div v-html="task.comment" slot="content" style="max-width: 300px">
+                                </div>
+                                <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                              </el-tooltip> -->
+                            </div>
+                          </div>
+
+                          <div class="files" v-if="task.files && task.files.length > 0">
+                            <div class="file-title">附件列表</div>
+                            <div class="file-list">
+                              <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                                {{ '附件' + (index + 1) }}
+                              </div>
+                            </div>
+                          </div>
+                        </template>
+                      </div>
+                      <div v-else>
+                        未开始
+                      </div>
+                    </div>
+
+                  </div>
+
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">5.评分</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+            <template v-if="node.type === 'reviews'">
+              <template v-if="node.enable">
+                <li class="title" :class="showData.businessStatus === 'review' ? 'active' : ''">
+                  6.审批{{ showData.businessStatus === 'review' ? '(进行中)' : '' }}
+                </li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content" v-if="node.children && node.children.length > 0">
+
+                    <div class="content-info" v-for="child in node.children" :key="child.id">
+                      <div class="user-type" v-if="child.tasks && child.tasks.length > 0">
+                        {{ child.assigneeType | filterType }}
+                      </div>
+                      <div class="task-info" v-if="child.tasks && child.tasks.length > 0">
+
+                        <template v-for="task in child.tasks">
+                          <div class="info" :key="task.taskId">
+                            <div class="info-left">
+                              <span :class="task.state === 'created' ? 'orange-color' : 'green-color'">
+                                {{ task.state === 'created' ? '进行中' : '已完成' }},
+                              </span>
+                              {{ task.assigneeName }},评分:{{ task.score }}
+                            </div>
+                            <div class="info-right" v-if="task.comment">
+                              <!-- <el-tooltip effect="dark" placement="right">
+                                <div v-html="task.comment" slot="content" style="max-width: 300px">
+                                </div>
+                                <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                              </el-tooltip> -->
+                              <div class="oneLine">意见:{{ task.comment || '暂无意见' }}</div>
+                            </div>
+                          </div>
+
+                          <div class="files" v-if="task.files && task.files.length > 0">
+                            <div class="file-title">附件列表</div>
+                            <div class="file-list">
+                              <div class="file-item" v-for="(file, index) in task.files" @click="openFileReview(file)">
+                                <!-- {{ file | filterFileName }} -->
+                                {{ '附件' + (index + 1) }}
+                              </div>
+                            </div>
+                          </div>
+                        </template>
+
+
+                      </div>
+                      <div v-else>
+                        未开始
+                      </div>
+                    </div>
+                  </div>
+                </li>
+              </template>
+              <template v-if="!node.enable">
+                <li class="title">6.审批</li>
+                <li class="info-box">
+                  <div class="line"></div>
+                  <div class="content">
+                    未启用
+                  </div>
+                </li>
+              </template>
+
+            </template>
+
+          </template>
+
+
+        </ol>
+
+        <!-- 操作日志 -->
+        <OperateLogVue v-if="reviewId" :reviewId="reviewId" :reviewIndicatorId="reviewIndicatorId"/>
+      </scroller>
+
+
+    </div>
+
+  </div>
+</template>
+
+<script>
+  import Vue from 'vue';
+  import OperateLogVue from '@/performance/components/public/OperateLog.vue'
+  import { ImagePreview } from 'vant';
+  Vue.use(ImagePreview);
+
+  export default {
+
+    components: {
+      OperateLogVue
+    },
+
+    data() {
+      return {
+        reviewIndicatorId: "",
+        reviewId: "",
+        showData: null,
+      }
+    },
+
+    filters: {
+      filterType(v) {
+          if (v == 'leader') return v = "管理员"
+          if (v == 'self') return v = "被考核人"
+          if (v == 'post') return v = "岗位"
+          if (v == 'user') return v = "指定人员"
+          if (v == 'deptLeader') return v = "部门"
+      },
+
+      filterFileName(str) {
+          if (str) {
+              let lastIndex = str.lastIndexOf("/")
+              return str.substr(lastIndex + 1, str.length - 1);
+          }
+      }
+    },
+
+    created() {
+      this.showData = JSON.parse(this.$route.query.showData);
+      this.reviewIndicatorId = this.showData.reviewIndicatorId
+      this.reviewId = this.showData.reviewId
+      console.log("this.showData");
+      console.log(this.showData);
+    },
+    methods: {
+      // 文件预览
+      openFileReview(url) {
+        let file = {
+            url
+        }
+        let imgFiles = ['BMP', 'GIF', 'PNG', 'JPEG', 'JPG', 'bmp', 'gif', 'png', 'jpeg', 'jpg'];
+        let lastIndex = file.url && file.url.lastIndexOf("/") || -1
+        let suffix; //文件后缀名
+
+        if (lastIndex > 0) {
+            suffix = file.url.substr(lastIndex + 1, file.url.length - 1).split(".")[1];
+            if (imgFiles.includes(suffix)) {
+                ImagePreview({
+                  images: [file.url],
+                  startPosition: 0
+                });
+            } else {
+                window.open(file.url, '_blank');
+            }
+        }
+      },
+    }
+  }
+</script>
+
+<style scoped lang="less">
+  .all {
+    width: 100%;
+    height: 100%;
+    .overall {
+      height: calc(100% - 0.92rem) !important;
+      position: relative;
+      overflow-y: scroll;
+    }
+    .modTit {
+      background-color: #efefef;
+      padding-left: 0.1rem;
+      height: 0.8rem;
+      line-height: 0.8rem;
+      font-size: 0.28rem;
+      box-sizing: border-box;
+      color: #8a8a8a;
+    }
+  }
+
+  .green-color {
+      color: #67c23a;
+  }
+
+  .orange-color {
+      color: #e6a23c;
+  }
+
+  .gray-color {
+      color: rgb(144, 147, 153);
+      background: rgb(244, 244, 245);
+      border-color: rgb(144, 147, 153);
+  }
+
+  .show-data-box {
+
+    .item-list {
+      .item {
+
+        .value-box {
+          margin-bottom: 5px;
+
+          .content {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+
+            &-left {
+              display: flex;
+              align-items: center;
+
+              &-status {}
+            }
+          }
+        }
+      }
+    }
+  }
+
+
+  .steps {
+    display: flex;
+    flex-direction: column;
+    margin: 0;
+    padding: 0.2rem;
+    box-sizing: border-box;
+    background-color: #fff;
+    .title {
+      width: 100%;
+      height: 0.5rem;
+      line-height: 0.5rem;
+      font-size: 0.26rem;
+      color: #000;
+    }
+
+    .info-box {
+      display: flex;
+      margin: 0.1rem 0;
+
+      .line {
+        margin: 0 0.2rem;
+        width: 0.02rem;
+        border: 0.02rem dashed #ccc;
+      }
+
+      .content {
+        width: 90%;
+        background-color: #f7f7f7;
+        padding: 0.1rem;
+        color: #89919F !important;
+        box-sizing: border-box;
+        color: #999;
+        font-size: 0.24rem;
+        &-info {
+          display: flex;
+          flex-direction: column;
+
+          .user-type {
+            width: 1.6rem;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            border-radius: 0.4rem;
+            border: 1px solid;
+            height: 0.4rem;
+            font-size: 0.24rem;
+            color: #409eff;
+            background: #ecf5ff;
+            border-color: #b3d8ff;
+          }
+
+          .task-info {
+            margin: 0.1rem 0;
+            color: #89919F !important;
+            font-size: 0.24rem;
+            .info {
+              width: 100%;
+              display: flex;
+              flex-direction: column;
+              font-size: 0.24rem;
+              margin: 0.2rem 0;
+              .info-left {
+              }
+              .info-right {
+              }
+            }
+          }
+        }
+      }
+    }
+
+  }
+
+  .active {
+    color: #409eff !important;
+  }
+
+
+  .files {
+    display: flex;
+    flex-direction: column;
+    border-radius: 6px;
+
+    .file-title {
+      color: #89919F !important;
+      font-weight: 600;
+    }
+
+    .file-item {
+      color: #26a2ff !important;
+      transition: 0.2s;
+      padding-left: 0.1rem;
+      margin-top: 0.1rem;
+      box-sizing: border-box;
+      &:hover {
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
+</style>

+ 104 - 0
src/performance-07-19/view/inits.vue

@@ -0,0 +1,104 @@
+<template>
+  <div class="all">
+    <div v-show="!appNavJx" class="noData flex-box-v flex-center-center">
+      <div class="data-all">
+        <img src="static/images/init.gif" class="appImg" />
+        <div style="font-size: .31rem;">管理执行难,就用功道云</div>
+      </div>
+    </div>
+    <div v-show="appNavJx" class="jxNav">
+      <img :src="'static/images/' + navList[navNew].image + '.png'" />
+      <van-button @click="navNew++" v-if="navNew < 1" type="primary" color="rgb(125 171 255)" block>下一步</van-button>
+      <van-button @click="navPaths" v-else type="primary" color="rgb(125 171 255)" block>进入</van-button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      userInfo: {}, // 绩效接口人员信息
+      userData: {}, // 7.0系统接口人员信息
+      newNav: this.plusStoGet('newNav'),
+      appNavJx: false,
+      navList: [{ image: 'newNav1' }, { image: 'newNav2' }],
+      navNew: 0
+    };
+  },
+  created() {
+    this.$removeCache("addthePlan")
+    this.$removeCache("actionplanDetails")
+    this.$removeCache("actionplanList")
+  },
+  activated() {
+    this.newNav = this.plusStoGet('newNav');
+    this.appNavJx = false;
+    this.setRouters();
+  },
+  methods: {
+    setRouters() {
+        if (this.newNav) {
+          this.$router.replace({ name: 'navigation',query:{index:this.$route.query.index} });
+        } else {
+          this.appNavJx = true;
+        }
+    },
+    navPaths() {
+      this.plusStoSet('newNav', 'true', () => {
+        this.$router.replace({ name: 'navigation',query:{index:this.$route.query.index} });
+      });
+    },
+    plusStoGet(key) {
+      if (window.plus) {
+        return plus.storage.getItem(key);
+      } else {
+        return localStorage.getItem(key);
+      }
+    },
+    plusStoSet(key, val, fun = function() {}) {
+      if (window.plus) {
+        plus.storage.setItem(key, val);
+      } else {
+        localStorage.setItem(key, val);
+      }
+      fun();
+    }
+  }
+};
+</script>
+
+<style scoped="scoped" lang="less">
+.all {
+  background-color: #fff;
+}
+.appImg {
+  width: 200px;
+  height: 200px;
+}
+.noData {
+  text-align: center;
+  position: fixed;
+  left: 0;
+  top: 0;
+  right: 0;
+  bottom: 0;
+}
+.data-all {
+  margin-bottom: 10%;
+  color: #595959;
+}
+.jxNav {
+  width: 100%;
+  height: 100%;
+  img {
+    width: 100%;
+    margin-top: 50px;
+  }
+  button {
+    width: 90%;
+    margin: auto;
+    border-radius: 5px;
+  }
+}
+</style>

+ 863 - 0
src/performance-07-19/view/myTarget/krDetail.vue

@@ -0,0 +1,863 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="KR详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all-box" style="height: calc(100% - 0.92rem);position: relative;">
+      <template >
+        <header class="header">
+          <div class="flex-box">
+            <div class="flex-1" style="font-weight: 600;padding: 0 0.2rem;padding-left: 0.1rem;">{{krDetail.name}}</div>
+          </div>
+          <div class="flex-box-ce fontColorC header-message" style="font-size: 0.26rem;margin-top:0.14rem">
+            <userImage :img_url="krDetail.owner_userInfo.img_url" :user_name="krDetail.owner_userInfo.name" width="0.7rem" height="0.7rem"></userImage>
+            <span>{{ krDetail.owner_userInfo.name }}</span>
+            <van-icon name="star" class="yellow"/>
+            <span>{{krDetail.confident}}分</span>
+            <van-circle layer-color="#E5E9F2" v-model="krDetail.currentRate" :color="krDetail.risk_level==2? '#FF9600':krDetail.risk_level==3? '#f56c6c':' #2879ff'" :rate="krDetail.process" :stroke-width="120" size="20px"/>
+            <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:krDetail.risk_level==2,red:krDetail.risk_level==3}">{{ krDetail.process }}%</span>
+          </div>
+        </header>
+        <div class="scroller">
+          <div class="box" style="border-bottom: 0.2rem solid #f5f7fa;">
+              <div class="title">基本信息</div>
+              <div class="flex-box"><div class="label flex-1">发布人</div><div>{{$getEmployeeMapItem(krDetail.publisher_id).name}}</div></div>
+              <div class="flex-box"><div class="label flex-1">KR权重</div><div>{{krDetail.weight}}%</div></div>
+              <div class="flex-box"><div class="label flex-1">起止时间</div>
+                <div>{{krDetail.start_time}}~{{krDetail.end_time}}</div>
+                <template v-if="krDetail.o_composite_state!=6">
+                  <span v-if="krDetail.day>0" style="padding-left: 0.14rem;">剩余<span class="green">{{krDetail.day}}</span>天</span>
+                  <span v-if="krDetail.day<0" style="padding-left: 0.14rem;">过期<span class="red">{{Math.abs(krDetail.day)}}</span>天</span>
+                </template>
+              </div>
+              <div class="flex-box"><div class="label flex-1">KR评分</div>
+                  <span v-if="krDetail.score===-0.1" class="fontColorC">暂未评分</span>
+                  <span v-else>{{krDetail.score}}分</span>
+              </div>
+              <div class="flex-box">
+                <div class="label flex-1">评分说明</div>
+                <span v-if="krDetail.score_detail" style="max-width: 5.6rem;">{{krDetail.score_detail}}</span>
+                <span v-else class="fontColorC">暂无说明</span>
+              </div>
+              <div class="flex-box">
+                <div class="label">子目标</div>
+                <div class="flex-1" style="text-align: right;">
+                  <span v-if="krOs.length==0" class="fontColorC">暂无子目标</span>
+                  <div v-else class="hoverBlue" style="margin-bottom: 5px;text-align: right;" v-for="(item, index) in krOs" :key="index">
+                    {{item.name}}
+                  </div>
+                </div>
+              </div>
+          </div>
+          <van-tabs v-model="tabActive" class="shadow">
+            <van-tab :title="item.title" :name="item.name" :disabled="item.disabled" v-for="(item, index) in tabs" :key="index"></van-tab>
+            </van-tabs>
+          <div style="margin-top: 0.2rem;">
+            <template v-if="tabActive==1">
+              <div class="list-box" v-for="(item, index) in krsListAll" :key="index">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;border-bottom: 1px solid #f1f1f1;padding-bottom: 0.2rem;">
+                  <span class="flex-1" style="font-size: 0.26rem;" v-if="item.plans.length>0">计划任务<span class="blue">{{returnSum(item.plans)}}</span>/<span>{{item.plans.length}}</span></span>
+                </div>
+                <div style="padding:0 0.1rem;">
+                  <template v-if="item.projects.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index3) in item.projects" :key="task_item.id" @click="openDetail(task_item,3)">
+                        <van-icon name="paid" class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"/>
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD')}} 截止</span>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <template v-if="item.plans.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index2) in item.plans" :key="index2" @click="openDetail(task_item,1)">
+                        <van-icon :name="taskStatus(task_item.composite_state).icon"
+                        class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"
+                        :class="(task_item.day<=0&&$moment(task_item.end_date).format('YYYY-MM-DD')!=$moment().format('YYYY-MM-DD')) ? 'red':''"
+                        />
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD HH:mm')}} 截止</span>
+                            <template v-if="task_item.statistics.plan_total">
+                              <van-icon name="orders-o" />
+                              <span style="font-size: 0.26rem;">
+                                <span class="blue">{{task_item.statistics.plan_finish}}</span>/<span>{{task_item.statistics.plan_total}}</span>
+                              </span>
+                            </template>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <div v-if="item.projects.length==0&&item.plans.length==0" style="text-align: center;margin: 0.2rem 0;font-size: 0.28rem;" class="fontColorC">用“任务”推动目标达成,合理规划安排工作</div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive==2">
+              <Evolve v-if="kr_id" :isOperation="isOperation && !krDetail.process_conf.enable_automatic && krDetail.can_edit" readonly :process="Number(krDetail.process)" :target_id="Number(kr_id)" :target_type="2" style="padding: 0 0.2rem;"></Evolve>
+            </template>
+          </div>
+          <div style="height: 3rem;"></div>
+        </div>
+        <!-- <div class="aite" @click="openCommunication"><van-icon name="more" class="fontColorB" /></div> -->
+        <footer class="footer">
+          <div class="flex-box-ce" v-if="isOperation">
+            <van-icon name="chat-o" @click="openCommunication" style="margin-left: 0.2rem;font-size:0.6rem;" class="fontColorC"/>
+          </div>
+          <div v-else class="fontColorC gt" @click="openCommunication">有事沟通,可@Ta</div>
+        </footer>
+      </template>
+
+    </div>
+    <!-- 关联任务 -->
+    <TaskSearch :visible.sync="isShwoTaskSearch" @confirm="ActiveRelevanceTask"></TaskSearch>
+
+    <!-- 修改KR -->
+    <van-popup v-model:show="isShowUpdateKr" round position="bottom" :style="{ height: '90%',background:'#fff' }" @close="isShowUpdateKr=false">
+       <div>
+         <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+           <div class="blue" @click="isShowUpdateKr=false">取消</div>
+           <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">编辑</div>
+           <div class="blue" @click="confirmUpdateKr">确定</div>
+         </header>
+         <div>
+           <van-field v-model="form.name" rows="3"  type="textarea" maxlength="100"  placeholder="书写建议:KR是可量化的,需要体现行动效果"  show-word-limit/>
+           <van-cell title="开始时间" is-link :value="form.start_date" @click="openTime(1)" />
+           <van-cell title="截止时间" is-link :value="form.end_date" @click="openTime(2)"/>
+           <van-cell title="负责人" is-link @click="openSelectUser(2)"><div>{{form.owner_name}}</div></van-cell>
+           <van-cell title="信心指数" is-link @click="isShowSelectConfidence=true"><div>{{form.confident}}分</div></van-cell>
+         </div>
+       </div>
+    </van-popup>
+    <!-- 信心 -->
+    <van-action-sheet v-model="isShowSelectConfidence">
+      <div>
+        <van-picker show-toolbar :columns="pointArr"  @change="onChange" value-key="name" item-height="50px" @confirm="onConfirmConfidence" @cancel="isShowSelectConfidence = false">
+          <template #columns-top>
+              <div style="font-weight: 600;font-size: 0.34rem;text-align: center;">{{pointName}}</div>
+          </template>
+          <template #option="option">
+              <div class="flex-box-ce">
+                <van-rate v-model="option.value" allow-half :size="22" color="#ffd21e" void-icon="star" void-color="#eee" readonly />
+                <div style="padding-left: 0.2rem;">{{option.name}}</div>
+              </div>
+          </template>
+        </van-picker>
+      </div>
+    </van-action-sheet>
+
+    <!-- 选择时间 -->
+    <van-action-sheet v-model="isShowSelectTime">
+      <van-datetime-picker @cancel="isShowSelectTime=false" @confirm="selectConfirm" v-model="currentDate" type="date" :title="timeIndex==1? '开始时间':'截止时间'" :min-date="minDate" :max-date="maxDate"/>
+    </van-action-sheet>
+    <!-- 权重 -->
+    <van-popup v-model:show="isShowUpdateWeight" round position="bottom" :style="{ height: '90%', background: '#fff' }" @close="isShowUpdateWeight=false">
+      <div>
+        <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+          <div class="blue" @click="isShowUpdateWeight=false">取消</div>
+          <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">编辑权重</div>
+          <div class="blue" @click="confirmWeight">确定</div>
+        </header>
+        <div class="wInput">
+            <van-field v-for="(item, index) in krsList" :key="index" v-model="item.weight" input-align="right" @input="[(item.weight = item.weight.match(/\d+(\.\d{0,2})?/) ? item.weight.match(/\d+(\.\d{0,2})?/)[0] : '')]">
+                <template #label>
+                  <div>
+                    <span class="blue" style="padding-right: 3px;">KR{{index+1}}</span>
+                    <span>{{item.name}}</span>
+                  </div>
+                </template>
+                <template #right-icon> <span>%</span></template>
+            </van-field>
+            <div class="flex-box-ce flex-box-end" style="padding:0.24rem 0.32rem;">
+                <div class="updateprocess" @click="pingJun">平均权重</div>
+                <div class="fontColorC" style="margin-left: 0.2rem;font-size: 0.28rem;">总权重:{{getKrWeight}}%</div>
+            </div>
+        </div>
+      </div>
+    </van-popup>
+
+    <!-- 人员选择 -->
+    <EmployeeSelector  :isRequired="true" title="选择人员" :visible.sync="selectUser" @confirm="confirmUser" :can_select_dept="false" :multi="false" :selected.sync="selected_user"></EmployeeSelector>
+
+    <!-- 进度 -->
+    <Progress :visible.sync="isShwoUpdateProgress" :progressData="progressData" @confirm="update"></Progress>
+
+    <!-- 选择 -->
+    <van-action-sheet v-model="isShowbelong" :actions="scopeArr" @select="activebelong" cancel-text="取消" close-on-click-action/>
+    <!-- 评分 -->
+    <van-popup v-model:show="isShowUpdatePoint" round position="bottom" :style="{ height: '90%', background: '#fff' }" @close="isShowUpdatePoint=false">
+      <div>
+        <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+          <div class="blue" @click="isShowUpdatePoint=false">取消</div>
+          <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">KR评分</div>
+          <div class="blue" @click="confirmPoint">确定</div>
+        </header>
+        <div>
+          <van-field label="评分"  ref="input" input-align="right" placeholder="评分(0~10)" type="digit" v-model.trim="pointData.score"> <template #right-icon><span>分</span></template></van-field>
+          <van-field v-model="pointData.score_detail" rows="3" type="textarea" maxlength="500" placeholder="请输入评分说明" show-word-limit />
+          <van-cell title="@ta查看" is-link @click="openSelectUser(1)">
+              <div v-if="employees.length>0">
+                  <span v-for="(item, index) in employees" :key="index">{{ item.name }}<span v-if="employees.length - index > 1">,</span></span>
+              </div>
+              <span v-else class="input-ccc">请选择</span>
+          </van-cell>
+        </div>
+      </div>
+    </van-popup>
+    <!-- @人员 -->
+    <EmployeeSelector title="人员"  :visible.sync="selectUserAll" @confirm="confirmCreator" :selected.sync="selected_user_all"
+      :can_select_dept="false" :dept_multi="false" :append_body="true" :isShowDepts="false"
+    />
+
+    <!-- 可见范围 -->
+    <van-action-sheet v-model="isShowV" :actions="vArr" @select="activevArr" cancel-text="取消" close-on-click-action/>
+
+    <!-- 关联KR -->
+    <TargetSearch :visible.sync="isShwoKrSearch" :showSelectType="2" @confirm="ActiveRelevanceKr"></TargetSearch>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import {Circle,ActionSheet,Rate,Picker,DatetimePicker,Tab, Tabs, } from 'vant';
+Vue.use(Circle).use(ActionSheet).use(Rate).use(Picker).use(DatetimePicker).use(Tabs).use(Tab);
+
+import Evolve from '@/okr/components/public/Evolve';
+import Progress from '@/okr/components/public/Progress';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import {getOperation,taskStatus} from '@/okr/utils/auth';
+import TaskSearch from '@/okr/components/public/TaskSearch';
+import TargetSearch from '@/okr/components/public/TargetSearch';
+
+export default {
+  components:{Progress,EmployeeSelector,Evolve,TaskSearch,TargetSearch},
+  name: 'krDetail',
+  data() {
+    return {
+      taskStatus:taskStatus,
+      isShowbelong:false,
+      isShwoUpdateProgress:false,
+      isShowSelectConfidence:false,
+      isShowUpdatePoint:false,
+      isShowUpdateKr:false,
+      isShowSelectTime:false,
+      isShowUpdateWeight:false,
+      pointData:{kr_id:'',score:'',score_detail:'',to_employee_id:[]},
+      employees:[],
+      selectUserAll:false,
+      selected_user_all: { dept: [], employee: [] },//参与人员
+      selectUser:false,
+      selected_user: { dept: [], employee: [] },//参与人员
+      userInfo: this.$userInfo(),
+      currentDate:'',
+      timeIndex:1,
+      pointArr:[
+        {name:'1分',value:0.5,code:'1'},
+        {name:'2分',value:1,code:'1'},
+        {name:'3分',value:1.5,code:'2'},
+        {name:'4分',value:2,code:'2'},
+        {name:'5分',value:2.5,code:'3'},
+        {name:'6分',value:3,code:'3'},
+        {name:'7分',value:3.5,code:'4'},
+        {name:'8分',value:4,code:'4'},
+        {name:'9分',value:4.5,code:'5'},
+        {name:'10分',value:5,code:'5'},
+      ],
+      minDate: new Date(2020, 0, 1),
+      maxDate: new Date(2050, 10, 1),
+      columns:[],
+      krsList:[],
+      form:{
+        name:'',
+        owner_id:'',
+        owner_name:'',
+        confident:'',
+        start_date:'',//	是	string	开始日期,格式:2022-01-01
+        end_date:'',//	是	string	结束日期,格式:2022-01-01
+      },
+      scopeArr:[{
+          value: 1,
+          name:'KR 评分',
+          disabled: false
+        },
+        {
+          value: 2,
+          name:'更新完成度',
+          disabled: false
+        },
+        {
+          value: 3,
+          name:'编辑基本信息',
+          disabled: false
+        },
+        {
+          value: 4,
+          name:'编辑权重',
+          disabled: false
+        },
+        {
+          value: 5,
+          name:'删除KR',
+          color: '#f56c6c',
+          disabled: false
+        }
+      ],
+      processList: [],
+      kr_id:0,
+      krDetail:{owner_userInfo:{},process:0,publisher_userInfo:{},visible:1,process_conf:{}},
+      krOs:[],
+      progressData:{},
+      sumWeight:0,
+      isOperation:true,
+      pointNameArr:[
+        {name:'不可能完成',code:'1'},
+        {name:'很难完成,需要帮助',code:'2'},
+        {name:'有挑战,可以尝试',code:'3'},
+        {name:'有信心完成',code:'4'},
+        {name:'轻松完成',code:'5'},
+      ],
+      pointName:'不可能完成',
+      tabActive: 0,
+      tabs: [
+        {title:'计划',name:1,disabled:false},
+        {title:'进展',name:2,disabled:false},
+        {title:'',name:0,disabled:true}
+      ],
+      krsListAll:[],//包括任务
+      isShwoTaskSearch:false,
+
+      // 可见范围
+      isShowV:false,
+      vArr:[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}],
+      addTaskIndex:1,
+      selectKr:{},
+      isShwoKrSearch:false,
+    };
+  },
+  computed:{
+    getKrWeight(){
+      let sumWeight=0;
+      this.krsList.forEach(item=>{
+        sumWeight+=Number(item.weight)
+      })
+      this.sumWeight= Math.round(sumWeight)
+      return this.sumWeight
+    }
+  },
+  watch:{
+    tabActive(val){
+      if(val==1){
+        this.getkrTaskList();
+      }
+    },
+  },
+  mounted() {
+    if(this.$route.query.id){
+      this.kr_id=this.$route.query.id;
+      this.getKrDetail();
+    }
+  },
+  activated() {
+  	this.getkrTaskList();
+  },
+  methods: {
+    openDetail(item,type){
+      if(type==1){
+        this.$router.push({name: 'taskDetail', query: {id: item.id, readonly: 1}})
+      }else if(type==3) {
+        return
+        this.$router.push({name: 'projectDetail', query: {id: item.id}})
+      }
+    },
+    //执行
+    getkrTaskList(){
+      if(!this.krDetail.o_id){return false}
+      let data={
+        o_id:this.krDetail.o_id,//	是	string	目标id
+        kr_ids:this.kr_id,
+        plan_calc:1,
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/plan/list/o',data).then(res => {
+        let list=res.data.data.list;
+        list.forEach(e=>{
+          if(e.plans&&e.plans.length>0){
+            e.plans.forEach(item=>{
+              item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
+            })
+          }
+        })
+        this.krsListAll=list;
+      })
+    },
+    //关联母任务
+    ActiveRelevanceTask(item){
+        if(item.id){
+          this.$axiosUser('POST', '/api/pro/okr/plan/relate/other',{plan_id:item.id,target_type:2,target_id:this.kr_id}).then(res => {
+               this.getkrTaskList();
+          })
+        }
+    },
+    //关联项目
+    ActiveRelevanceKr(item){
+      this.$axiosUser('post', '/api/pro/okr/project/bind',{project_id:item.item.id,kr_id:this.selectKr.id}).then(res => {
+           this.getkrTaskList();
+      });
+    },
+    activevArr(item){
+      if(this.addTaskIndex==1){
+        if(item.value==1){
+          let data={
+            target_type:	2,//是	string	计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
+            target_id:this.selectKr.id,//是	integer	绑定的对象id 跟对象种类配对使用
+          }
+          this.$router.push({name: 'addTask', query: data})
+        }else{
+          this.$router.push({name: 'addProject', query: {kr_id:this.selectKr.id}})
+        }
+      }else{
+        if(item.value==1){
+            this.kr_id=this.selectKr.id;
+            this.isShwoTaskSearch=true;
+        }else{
+            this.isShwoKrSearch=true;
+        }
+      }
+    },
+    addTask(item,index){
+      this.addTaskIndex=index;
+      this.selectKr=item;
+      if(index==1){
+        this.vArr=[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}];
+      }else{
+        this.vArr=[{value: 1,name: '关联任务'},{value: 2,name: '关联项目'}];
+      }
+      this.isShowV=true;
+    },
+    returnSum(arr){
+      if(arr.length==0){return 0};
+      let sum=0;
+      arr.forEach(item=>{
+        if(item.composite_state==6){
+          sum++;
+        }
+      })
+      return sum
+    },
+    onChange(e,val) {
+      this.pointNameArr.some(item=>{
+        if(val.code==item.code){
+          this.pointName=item.name
+          return true
+        }
+      })
+    },
+    pingJun(){
+      let weight=Math.floor((100/(this.krsList.length)) * 100) / 100
+      this.krsList.forEach(item=>{
+         item.weight=weight
+      })
+    },
+    // 沟通
+    openCommunication(){
+      let data = {
+        item: JSON.stringify(this.krDetail),
+        target_type:2,
+        readonly: 1
+      }
+      this.$router.push({name: 'communication', query: data})
+    },
+    update(){
+      this.getKrDetail();
+    },
+    //更新完成度
+    updateProgress(){
+        let item=this.krDetail;
+        this.progressData={
+          target_type:2,
+          id:item.id,
+          process:Number(item.process),
+          risk_level:item.risk_level,
+          process_conf:item.process_conf,
+        }
+        this.isShwoUpdateProgress=true;
+    },
+    //目标详情
+    getTargetDateil(){
+      this.$axiosUser('get', '/api/pro/okr/public/obj/detail',{object_id:this.krDetail.o_id}).then(res => {
+        let data=res.data.data;
+        if(!data.can_edit){ //不可编辑权重
+          this.scopeArr.forEach(item=>{
+            if(item.value==4){item.disabled=true}
+          })
+        }
+      })
+    },
+    //KR详情
+    getKrDetail(){
+      this.krOs=[];
+      this.krDetail={owner_userInfo:{},process:0,publisher_userInfo:{},visible:1,process_conf:{}};
+      if(!this.kr_id){return false}
+      this.$axiosUser('get', '/api/pro/okr/public/kr/detail',{kr_id:this.kr_id}).then(res => {
+          let data=res.data.data;
+          data.owner_userInfo=this.$getEmployeeMapItem(data.owner_id);
+          data.publisher_userInfo=this.$getEmployeeMapItem(data.publisher_id);
+          data.day=this.$moment(data.end_time).diff(this.$moment().format('YYYY-MM-DD'), 'day');
+          this.isOperation=getOperation(data.publisher_id,data.owner_id);
+          if(data.statistics.sub_o_total>0){
+            this.getKrTarget(data.id);
+          }
+          this.krDetail=data;
+          if(!data.can_edit){ //不可编辑
+            this.scopeArr.forEach(item=>{
+              if(item.value==3){item.disabled=true}
+            })
+          }
+          if(!this.isOperation){ //完成度
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){item.disabled=true}
+            })
+          }
+          if(!data.can_score){ //不可评分
+            this.scopeArr.forEach(item=>{
+              if(item.value==1){item.disabled=true}
+            })
+          }
+          if(!data.can_delete){ //不可删除
+            this.scopeArr.forEach(item=>{
+              if(item.value==5){item.disabled=true}
+            })
+          }
+          this.getTargetDateil();
+      }).finally(()=>{
+          if(!this.tabActive){
+            this.tabActive=1;
+          }
+      })
+    },
+    //kr 子目标列表
+    getKrTarget(id){
+      this.$axiosUser('get', 'api/pro/okr/public/kr/sub/list', {kr_id:id}).then(res => {
+        this.krOs=res.data.data.os;
+      })
+    },
+    deletekr(){
+      if(this.krsList.length==0){
+        this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.krDetail.o_id}).then(res => {
+            let list=res.data.data.list;
+            if(list.length==1){
+              this.$toast('当前KR为最后一个,不能删除')
+              return false
+            }else{
+              this.$axiosUser('POST', '/api/pro/okr/kr/d',{kr_id:this.kr_id}).then(res => {
+                  setTimeout(()=>{
+                    this.$toast('已删除')
+                    this.$route_back()
+                  },500)
+              })
+            }
+        })
+        return false
+      }else if(this.krsList.length==1){
+        this.$toast('当前KR为最后一个,不能删除')
+        return false
+      }
+      this.$axiosUser('POST', '/api/pro/okr/kr/d',{kr_id:this.kr_id}).then(res => {
+            setTimeout(()=>{
+              this.$toast('已删除')
+              this.$route_back()
+            },500)
+      })
+    },
+    confirmWeight(){
+      let sumWeight=0;
+      let krs=[]
+      this.krsList.forEach(item=>{
+          sumWeight+=Number(item.weight);
+          krs.push({id:item.id,weight:item.weight*100})
+      })
+      sumWeight=Math.round(sumWeight);
+      // if(sumWeight!=100){
+      //    this.$toast("KR权重总和要为100");
+      //    return false
+      // }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_weight',{object_id:this.krDetail.o_id,kr:JSON.stringify(krs)}).then(res => {
+        if(this.krDetail.o_id){ //kr详情调整权重
+          this.getKrDetail();
+        }
+        this.isShowUpdateWeight=false
+      })
+    },
+    selectConfirm(val){
+      if(this.timeIndex==1){
+        this.form.start_date=this.$moment(this.currentDate).format('YYYY-MM-DD');
+      }else{
+        this.form.end_date=this.$moment(this.currentDate).format('YYYY-MM-DD');
+      }
+      this.isShowSelectTime = false;
+    },
+    onConfirmConfidence(v){
+      this.form.confident=v.value*2;
+      this.isShowSelectConfidence=false
+    },
+    confirmUpdateKr(){
+      if(this.form.start_date&&this.form.end_date){
+        if(this.form.start_date>this.form.end_date){
+          this.$toast("开始时间不能大于截止时间")
+          return false
+        }
+      }
+      this.form.kr_id=this.kr_id;
+      this.$axiosUser('post', '/api/pro/okr/kr/ms',this.form).then(res=>{
+         this.isShowUpdateKr=false
+         this.getKrDetail();
+      })
+    },
+    openTime(index){
+      this.timeIndex=index;
+      if(index==1){
+        this.currentDate=new Date(this.form.start_date);
+      }else{
+        this.currentDate=new Date(this.form.end_date);
+      }
+      this.isShowSelectTime = true;
+    },
+    confirmUser(item){
+       let employee=item.employee[0];
+       this.form.owner_id=employee.id;
+       this.form.owner_name=employee.name;
+    },
+    openSelectUser(index){
+      if(index==1){
+        this.selected_user_all.employee=this.employees;
+        this.selectUserAll=true;
+      }else if(index==2){
+        this.selected_user.employee=[{name:this.form.owner_name,id:this.form.owner_id}];
+        this.selectUser=true;
+      }
+    },
+    confirmCreator(item){
+      let employee=item.employee;
+      this.employees=employee;
+      let to_employee_id=employee.map(e=>{
+        return e.id
+      })
+      this.pointData.to_employee_id=to_employee_id.toString();
+    },
+    confirmPoint(){
+      if(this.pointData.score===''){
+        this.$toast("请输入分值");
+        return false
+      }
+      if(this.pointData.score>10){
+        this.$toast("请输入0~10之间数值");
+        return false
+      }
+      let params={
+        kr_id:this.kr_id,
+        score:Number(this.pointData.score),
+      }
+      if(this.employees.length>0){
+        params.to_employee_ids=this.pointData.to_employee_id
+      }
+      if(this.pointData.score_detail){
+        params.score_detail=this.pointData.score_detail;
+      }
+      this.$axiosUser('post', '/api/pro/okr/kr/score',params).then(res => {
+          this.isShowUpdatePoint=false;
+          this.$toast("已评分");
+          this.getKrDetail();
+      })
+    },
+
+    activebelong(item){
+      if(item.value==1){
+        this.pointData={kr_id:'',score:this.krDetail.score==-1? 0:this.krDetail.score,score_detail:this.krDetail.score_detail,to_employee_id:[]};
+        this.isShowUpdatePoint=true;
+        this.$nextTick(() => {
+            setTimeout(()=>{
+              this.$refs.input.focus();
+            },500)
+        });
+      }else if(item.value==2){
+        this.updateProgress();
+      }else if(item.value==3){
+        this.form={
+          name:this.krDetail.name,
+          owner_id:this.krDetail.owner_userInfo.id,
+          owner_name:this.krDetail.owner_userInfo.name,
+          start_date:this.krDetail.start_time,//	是	string	开始日期,格式:2022-01-01
+          end_date:this.krDetail.end_time,//	是	string	结束日期,格式:2022-01-01
+          confident:this.krDetail.confident
+        },
+        this.isShowUpdateKr=true;
+      }else if(item.value==4){
+        this.getKrList()
+      }else{
+        this.$dialog.confirm({ title:'删除', message: 'kr删除操作不可恢复!请谨慎操作'}).then(() => {
+            this.deletekr();
+        });
+      }
+    },
+    getKrList(){
+      this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.krDetail.o_id}).then(res => {
+          let list=res.data.data.list;
+          this.krsList =list;
+          this.isShowUpdateWeight=true;
+      })
+    },
+  },
+};
+</script>
+
+<style scoped lang="less">
+  .btns span {
+    width: 1.4rem;
+    text-align: center;
+    padding: 0.04rem 0.1rem;
+    color: #26A2FF;
+    margin-left: 0.2rem;
+    border: 0.02rem solid #26A2FF;
+    border-radius: 0.06rem;
+    font-size: 0.26rem;
+  }
+  .list-box {
+    // padding: 0.2rem;
+    font-size: 0.32rem;
+    background-color: #fff;
+    border-radius: 5px;
+    margin: 0 0.2rem;
+    margin-top: 0.2rem;
+  }
+  .shadow {
+    border-bottom: 1px solid #f5f7fa;
+  }
+  .footer {
+    padding: 0.14rem 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+  }
+  .footer .gt {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    border: 0.02rem solid #f1f1f1;
+    font-size: 0.32rem;
+  }
+  .footer i{
+    font-size: 0.6rem;
+  }
+  .footer .btn {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    // border: 0.02rem solid #26A2FF;
+    color: #fff;
+    text-align: center;
+    background: #26A2FF;
+    font-size: 0.32rem;
+  }
+.updateprocess {
+    border: 1px solid #409EFF;
+    padding: 2px 6px;
+    border-radius: 25px;
+    font-size: 12px;
+    cursor: pointer;
+    margin-left: 10px;
+    color: #409EFF;
+}
+.wInput /deep/ .van-field__label{
+  width: 5rem;
+}
+.o-content {
+  border-radius: 5px;
+  padding: 5px;
+  margin-left: 16px;
+}
+.o-content:hover {
+  background-color: #f7f8fa;
+}
+.o-content:hover .fontColorC {
+  display: block !important;
+  cursor: pointer;
+}
+.biaos {
+  width: 10px;
+  height: 10px;
+  background-color: #26a2ff;
+  border: 1px solid #fff;
+  border-radius: 100%;
+  box-shadow: 0 0 10px #26a2ff;
+  display: inline-block;
+  margin-right: 10px;
+}
+.biaos2 {
+  background-color: #ff9600;
+  box-shadow: 0 0 10px #ff9600;
+}
+.biaos3 {
+  background-color: #f56c6c;
+  box-shadow: 0 0 10px #f56c6c;
+}
+ .label{
+   color: #89919F;
+ }
+.box{
+   padding:0.24rem;
+   font-size: 0.3rem;
+}
+ .box .flex-box{
+   margin-top: 0.2rem;
+ }
+.title{
+  position: relative;
+  padding-left: 0.14rem;
+}
+.title::after {
+    content: "";
+    position: absolute;
+    width: 0.06rem;
+    height: 0.26rem;
+    border-radius: 0.06rem;
+    background-color: #26A2FF;
+    left: 0;
+    top: 0.07rem;
+}
+.scroller {
+  height: calc(100% - 1.76rem) !important;
+  overflow-y: auto;
+  background-color: #fff;
+}
+.header-message span{
+  padding-left: 5px;
+  padding-right: 10px;
+}
+.aite {
+  width: 1rem;
+  height: 1rem;
+  text-align: center;
+  line-height: 1rem;
+  font-size: 0.6rem;
+  cursor: pointer;
+  display: inline-block;
+  box-shadow: 0 0 3px #89919f;
+  border-radius: 100%;
+  background-color: #fff;
+  position: fixed;
+  z-index: 2;
+  bottom: 0.4rem;
+  right: 0.4rem;
+}
+.aite i {
+  font-size: 0.36rem;
+}
+.header {
+  padding: 0.24rem;
+  background-color: #fff;
+  border-bottom: 1px solid #f1f1f1;
+}
+</style>

+ 606 - 0
src/performance-07-19/view/myTarget/myTarget.vue

@@ -0,0 +1,606 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="目标管理" left-text="返回" @click-left="$route_back" left-arrow>
+      <div slot="right" @click="isShowPopup = true" style="color: #fff;">筛选<van-icon name="list-switch" /></div>
+    </van-nav-bar>
+    <div class="all">
+      <div style="background-color: #fff;">
+        <div style="padding: 0.24rem;border-bottom: 1px solid #f1f1f1;" class="flex-box-ce flex-center-center" @click="openPanel()">
+          <icon name="YMPicker_item_icon" style="margin-right: 6px;width: 0.3rem;height: 0.3rem;" class="fontColorC"></icon>
+          <div>{{ dateParameter.year }}年</div>
+          <div style="margin: 0 6px;">{{ dateParameter.name }}</div>
+          <van-icon name="arrow-down" />
+        </div>
+        <!-- <van-tabs v-model="activeName">
+          <van-tab v-for="(item,index) in tabs" :title="item.title" :name="item.name" :key="index" v-if="item.isShow"></van-tab>
+        </van-tabs> -->
+      </div>
+
+      <template v-if="activeName=='a'">
+        <!-- <div class="flex-box-ce flex-d-wrap" style="padding: 0 0.2rem;margin-top: 0.24rem;">
+          <div class="search-item" style="border-radius: 25px;font-size: 0.28rem;" @click="targetType=item.id" v-for="(item, index) in targetTypeArr" :key="index" :class="item.id==targetType? 'searchActive':''">{{ item.name }}</div>
+        </div> -->
+      </template>
+      <template v-if="activeName=='b'">
+        <div class="selector" @click="isShowDept=true">
+          <span>{{ deptInfo.dept_name }}</span>
+          <van-icon name="arrow-down" />
+        </div>
+        <div style="overflow-x: scroll;margin: 0.2rem;">
+            <div class="flex-box-ce">
+                <div
+                :class="{userActive:ownerUserInfo.id==item.id}"
+                @click="ownerUserInfo = item"
+                style="padding:0.14rem;border-radius: 5px;"
+                class="flex-box-v flex-center-center"
+                v-for="(item,index) in userList" :key="index">
+                  <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                  <div class="clamp userName">{{item.name}}</div>
+                </div>
+            </div>
+        </div>
+      </template>
+      <template v-if="activeName=='c'">
+        <div style="overflow-x: scroll;margin: 0.2rem;">
+            <div class="flex-box-ce">
+                <div class="flex-box-v flex-center-center" style="padding: 0.14rem;" @click="openGz">
+                   <div class="addUser" style="">+</div>
+                   <div class="clamp userName">设置</div>
+                </div>
+
+                <div
+                :class="{userActive:follUserInfo.id==item.id}"
+                @click="follUserInfo=item"
+                style="padding:0.14rem;border-radius: 5px;"
+                class="flex-box-v flex-center-center"
+                v-for="(item,index) in followList" :key="index">
+                  <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                  <div class="clamp userName">{{item.name}}</div>
+                </div>
+            </div>
+        </div>
+      </template>
+      <template v-if="activeName=='d'">
+        <div class="selector" @click="isShowSelectUser=true">
+          <span v-if="selectDataBox.name">{{ selectDataBox.name }}</span>
+          <span v-else class="fontColorC">选择人员或部门</span>
+          <van-icon name="arrow-down" />
+        </div>
+        <div style="height: 0.2rem;"></div>
+      </template>
+      <div class="scroller" :class="{scroller2:activeName=='b',scroller3:activeName=='c',scroller4:activeName=='d'}">
+        <scroller ref="scroller" :isInitRefresh="false" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢" :list="targetList">
+          <div class="list-box" v-for="(item,index) in targetList" :key="index" >
+              <div class="flex-box" @click="openDetail(item,1)">
+                  <div class="huan"><span></span></div>
+                  <div class="flex-1">
+                    <div class="clamp2" style="margin-bottom: 5px;">{{item.name}}</div>
+                    <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                        <van-icon name="contact" v-show="item.belong_type==4"/>
+                        <van-icon name="cluster-o" v-show="item.belong_type==2"/>
+                        <van-icon name="hotel-o" v-show="item.belong_type==1"/>
+                        <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;">{{$getEmployeeMapItem(item.owner_id).name}}</span>
+                        <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.composite_state==6">已结束</span>
+                        <template v-else>
+                          <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.process_ut">{{item.process_ut}} 更新</span>
+                        </template>
+                        <span class="flex-1"></span>
+                        <div class="progress"><div class="progress-inner" :class="{bjYellow:item.risk_level==2,bjRed:item.risk_level==3}" :style="{width:item.process>100? '100%':item.process+'%'}"></div></div>
+                        <span style="padding-left: 0.1rem;font-size: 0.24rem;" class="blue" :class="{orange:item.risk_level==2,red:item.risk_level==3}">{{ item.process }}%</span>
+                    </div>
+                  </div>
+              </div>
+              <div class="flex-box-ce" style="margin-top: 0.2rem;" @click="openDetail(krItem,2)" v-for="(krItem,index2) in item.krs" :key="index2" >
+                  <div class="blue" style="font-size: 0.26rem;margin-right: 0.13rem;">KR{{index2+1}}</div>
+                  <div class="flex-1 font-flex-word" style="padding-right: 0.2rem;font-size: 0.28rem;">{{krItem.name}}</div>
+                  <van-circle layer-color="#E5E9F2" v-model="krItem.currentRate" :color="krItem.risk_level==2? '#FF9600':krItem.risk_level==3? '#f56c6c':' #2879ff'" :rate="krItem.process" :key="index2"  :stroke-width="120" size="20px"/>
+                  <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:krItem.risk_level==2,red:krItem.risk_level==3}">{{ krItem.process }}%</span>
+              </div>
+          </div>
+          <div v-if="targetList.length == 0" style="text-align: center;margin-top: 2rem;" class="fontColorC">
+              <span>未找到相关的目标</span>
+          </div>
+        </scroller>
+      </div>
+
+    </div>
+
+    <!-- 选择部门 -->
+    <van-dialog v-model="isShowDept" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="deptInfo.dept_id">
+        <div v-for="(item, index) in dept_list" :key="index">
+          <van-radio :name="item.dept_id" @click="confirmDept2(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.dept_name }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+    <!-- 周期选择 -->
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel=false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+      </div>
+    </van-action-sheet>
+
+    <!-- 人员选择 -->
+    <EmployeeDeptSelector
+      title="选择人员"
+      :visible.sync="isShowSelectUser"
+      @confirm="confirmUser"
+      :selectDataBox.sync="selectDataBox">
+    </EmployeeDeptSelector>
+
+    <!-- 筛选 -->
+    <van-popup v-model="isShowPopup" position="right" style="height: 100%;left: 20%;">
+      <div style="position: relative;height: 100%;">
+        <div style="border-bottom: 1px solid #f1f1f1;font-size: 16px;font-weight: 700;height: 0.92rem;line-height: 0.92rem;padding: 0 0.2rem;">高级筛选</div>
+        <div style="padding: 10px;">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">类型</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" @click="belong_type=item.id" v-for="(item, index) in targetArr" :key="index" :class="item.id==belong_type? 'searchActive':''">{{ item.name }}</div>
+            </div>
+        </div>
+       <!-- <div style="padding: 10px;">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">状态</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" @click="sortId=item.id" v-for="(item, index) in sortArr" :key="index" :class="item.id==sortId? 'searchActive':''">{{ item.name }}</div>
+            </div>
+        </div> -->
+        <div style="position: fixed;bottom: 0.2rem;left: 0.2rem;right: 0.2rem;">
+          <div class="btn" @click="isShowPopup=false">确认</div>
+        </div>
+      </div>
+    </van-popup>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import {Picker,Popup,Circle,Icon,Tab, Tabs,} from 'vant';
+import { _debounce, _throttle } from '@/utils/auth';
+import { getBelongType,getColumns,cycleTypeArr} from '@/okr/utils/auth';
+
+import EmployeeSelector from '@/components/EmployeeSelector';
+import EmployeeDeptSelector from '@/components/EmployeeDeptSelector';
+Vue.use(Picker).use(Popup).use(Circle).use(Icon).use(Tabs).use(Tab)
+export default {
+  components:{EmployeeSelector,EmployeeDeptSelector},
+  name: 'Target',
+  props: {
+    skeLoad: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      page:1,
+      page_size:10,
+      cycleTypeArr:cycleTypeArr(true),
+      value:5,
+      userId:this.$userInfo().id,
+      userInfo: this.$userInfo(),
+      dept_list:this.$userInfo().employee_detail.dept_list,
+      deptInfo:this.$userInfo().employee_detail.dept_list[0]? this.$userInfo().employee_detail.dept_list[0]:{},
+      isShowDept:false,
+      targetTypeArr: [{ name: '我负责的', id: 1 }, { name: '我参与的', id: 2 }, { name: '我关注的', id: 3 }],
+      targetType:1,
+      dateParameter: {
+        year: '',
+        cycle_type: 0,
+        dateId: 1,
+        name: '全部周期'
+      },
+      selectPftiTheEcho: [0, 0], // 选项回显
+      pullonThePanel:false,
+      columns: getColumns(),
+      isShowPopup:false,
+
+      targetArr: [{ name: '全部类型', id: 0 }, { name: '公司', id: 1 }, { name: '部门', id: 2 },{ name: '个人', id: 4 }],
+      belong_type: 0,
+
+      sortArr: [
+        { name: '全部状态', id: 0,value:'0' },
+        { name: '进行中', id: 1,value:'1,2,3,4,5,7,8,9' },
+        { name: '已结束', id: 2,value:'6' },
+      ],
+      sortId: 0,
+      targetList:[],
+      isShowSelectUser:false,
+      selected_user: { dept: [], employee: [] } ,//传入已选部门
+      selectDataBox:{},
+      tabs:[{title:'我的目标',name:'a',isShow:true},{title:'我的部门',name:'b',isShow:true},{title:'关注的人',name:'c',isShow:true},{title:'全公司',name:'d',isShow:true}],
+      activeName: 'd',
+      userList:[],
+      ownerUserInfo:{},
+      followList:[],
+      follUserInfo:{},
+    };
+  },
+  watch:{
+    isShowSelectUser(val){
+      if(val){
+        this.selected_user.employee=[this.userInfo];
+      }
+    },
+    isShowPopup(val){
+      if(!val){
+        this.pullDown();
+      }
+    },
+    targetType(){
+      this.pullDown();
+    },
+    ownerUserInfo(){
+      this.pullDown();
+    },
+    follUserInfo(){
+      this.pullDown();
+    },
+    activeName(val){
+      if(this.activeName=='a'){
+        this.pullDown();
+      }
+      if(this.activeName=='d'){
+        this.pullDown();
+      }
+      if(this.activeName=='b'){
+        this.get_employee_list();
+      }
+      if(this.activeName=='c'){
+        this.getGzUserList();
+      }
+    },
+  },
+  methods: {
+    openGz(){
+      this.$router.push({name: 'attentionList',query:{index:1}})
+    },
+    getGzUserList(){
+      this.$axiosUser('get', '/api/pro/okr/follow', { type:1 }).then(res=>{
+         this.followList = res.data.data.list;
+         if(this.followList.length>0){
+           this.follUserInfo=this.followList[0];
+         }else{
+           this.follUserInfo={};
+           this.pullDown();
+         }
+      })
+    },
+    confirmDept2(data){
+      this.deptInfo=JSON.parse(JSON.stringify(data));
+      this.get_employee_list();
+      this.isShowDept=false;
+    },
+    get_employee_list() {
+      this.$axiosUser('get', '/api/pro/employee/list', { dept_id:this.deptInfo.dept_id }, 'v2').then(res => {
+        let list=res.data.data.list;
+        list.unshift({name:'全部',id:0})
+        this.userList=list;
+        if(this.userList.length>0){
+          this.ownerUserInfo=this.userList[0];
+        }
+      });
+    },
+
+    openPanel(){
+      this.pullonThePanel=true;
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+
+    confirmUser(item){
+      this.selectDataBox = item;
+      this.pullDown();
+    },
+    openDetail(item,type){
+      if(type==1){
+        this.$router.push({name: 'myTargetDetail', query: {id: item.id}})
+      }else {
+        this.$router.push({name: 'myKrDetail', query: {id: item.id}})
+      }
+    },
+    // 考核包搜索
+    onConfirm (data, list) { // 确认
+      let columns=this.columns[list[0]];
+      let options=this.cycleTypeArr[list[1]]
+      this.selectPftiTheEcho=list
+      this.dateParameter={
+        year: columns.value,
+        cycle_type: options.cycle_type,
+        dateId: options.id,
+        name: options.name
+      };
+      this.pullDown();
+      this.pullonThePanel = false
+    },
+    pullDown(){
+      setTimeout(() => {
+        this.$refs.scroller.triggerPullToRefresh();
+      }, 50);
+    },
+    theEchoVanPicker() { // 回显
+      this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+    },
+
+    getList(is,callback){
+      let hasMore = false
+      is? '':this.page=1;
+      let params = {
+        page:is? this.page:1,
+        page_size: this.page_size,
+        cycle_type:this.dateParameter.cycle_type,
+        year:this.dateParameter.year,
+        belong_type:this.belong_type,
+        quarter:0,
+        half_year:0,
+        month:0,
+        sort_ct:2,
+        ids: []
+      };
+      if(!params.year) delete params.year
+      if(!params.quarter) delete params.quarter
+      if(!params.half_year) delete params.half_year
+      if(!params.month) delete params.month
+      params.ids = this.$route.query.ids || "[]";
+      if(this.activeName=='a'){ //我的目标
+        this.targetType==1? params.owner_id=this.userId:this.targetType==2? params.joiner_id=this.userId:params.follower_id=this.userId;
+      }else if(this.activeName=='b'){//我的部门
+        params.dept=this.deptInfo.dept_id;
+        params.owner_id=this.ownerUserInfo.id;
+      }else if(this.activeName=='c'){//我关注的
+        if(this.follUserInfo.id){
+          params.owner_id=this.follUserInfo.id;
+        }else{
+          this.targetList=[];
+          callback && callback(hasMore)
+          return false
+        }
+      }else if(this.activeName=='d'){//全公司
+        if(this.selectDataBox.type == 'user'){
+          params.owner_id = this.selectDataBox.id;
+        }else if(this.selectDataBox.type=='dept'){
+          params.dept=this.selectDataBox.id;
+        }
+      }
+
+      if(this.sortId){//状态
+          params.composite_states=this.sortId==1? '1,2,3,4,5,7,8,9':'6';
+      }
+      if(this.dateParameter.cycle_type==2){
+        params.quarter=this.dateParameter.dateId
+      }
+      if(this.dateParameter.cycle_type==3){
+        params.half_year=this.dateParameter.dateId
+      }
+      if(this.dateParameter.cycle_type==4){
+        params.month=this.dateParameter.dateId
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/obj/list', params).then(res => {
+          let list=res.data.data.list
+          list.forEach(item=>{
+            item.krs.forEach(e=>{
+              e.currentRate=Number(e.process);
+              e.process=Number(e.process)
+            })
+          })
+          if (this.page === 1) {
+            this.targetList = list
+          } else {
+            this.targetList = this.targetList.concat(list)
+          }
+          hasMore = list.length !== 10
+          callback && callback(hasMore)
+      })
+    },
+    // 上拉刷新
+    refresh (done) {
+      this.getList(false,done)
+    },
+    // 下拉加载
+    infinite (done) {
+      this.page++;
+      this.getList(true,done)
+    },
+    getUnitList(){
+      this.$axiosUser('get', '/api/pro/okr/public/kr/unit_list').then(res => {
+    	let data=res.data.data;
+    	data.reverse()
+       this.$setCache('unitList',data)
+      })
+    },
+  },
+  created() {
+    this.getUnitList();
+    this.columns.forEach((e,index)=>{
+      if(e.value==this.dateParameter.year){
+        this.selectPftiTheEcho[0]=index
+      }
+    })
+    this.tabs=[
+      {title:'我的目标',name:'a',isShow:true},
+      {title:'我的部门',name:'b',isShow:!this.$userInfo().is_okr_manager&&this.dept_list.length>0},
+      {title:'关注的人',name:'c',isShow:true},
+      {title:'全公司',name:'d',isShow:true},
+    ]
+    this.getList();
+  },
+  activated() {
+    if(this.activeName=='c'){
+      this.getGzUserList();
+    }else{
+      this.pullDown();
+    }
+  },
+};
+</script>
+
+<style scoped lang="less">
+.addUser{
+    font-size: .6rem;
+    padding: 0.2rem;
+    border: 0.02rem dashed #89919f;
+    text-align: center;
+    height: 0.4rem;
+    width: 0.4rem;
+    line-height: .4rem;
+    color: #89919f;
+    border-radius: 2rem;
+}
+.userName{
+    font-size: 0.28rem;
+    width: 1rem;
+    text-align: center;
+    color: #89919F;
+}
+.userActive{
+  background-color: #E9F0FD;
+}
+.userActive .userName{
+ color: #26A2FF;
+}
+.selector {
+  z-index: 1;
+  display: flex;
+  justify-content: center;
+  width: 100%;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.28rem;
+  border-top: 1px solid #f1f1f1;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+  span {
+    max-width: 3.5rem;
+    overflow: hidden;
+  }
+}
+.aite{
+    width: 1rem;
+    height: 1rem;
+    text-align: center;
+    line-height: 1rem;
+    font-size: 0.6rem;
+    cursor: pointer;
+    color: #fff;
+    display: inline-block;
+    border-radius: 100%;
+    background-color: #26A2FF;
+    position: absolute;
+    z-index: 2;
+    bottom: 0.4rem;
+    right: 0.4rem;
+}
+.progress {
+  border-radius: 100px;
+  background-color: #ebeef5;
+  overflow: hidden;
+  position: relative;
+  vertical-align: middle;
+  height: 0.2rem;
+  width: 1rem;
+}
+.progress-inner {
+  width: 0%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding-top: 1px;
+  height: 100%;
+  background-image: linear-gradient(to right, #99BBFF 0%, #26A2FF 100%);
+  border-radius: 100px;
+  color: #fff;
+  white-space: nowrap;
+  transition: width 0.6s ease;
+}
+.bjYellow{
+  background-image: linear-gradient(to right, #fedf86 0%, #FF9600 100%);
+}
+.bjRed{
+  background-image: linear-gradient(to right, #FEA2A2 0%, #F16060 100%);
+}
+.huan{
+  position: relative;
+  width: 0.4rem;
+  height: 0.4rem;
+  border-radius: 100%;
+  background-color: #E9F1FE;
+  box-sizing: border-box;
+  text-align: center;
+  margin-right: 0.2rem;
+  padding-top: 0.036rem;
+}
+.huan span{
+  border: 2px solid #26A2FF;
+  border-radius: 100%;
+  width: 0.16rem;
+  height: 0.16rem;
+  display: inline-block;
+}
+.list-box{
+  padding: 0.2rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0.2rem;
+  margin-bottom: 0.24rem;
+}
+.scroller{
+   height: calc(100% - 2.75rem);
+   position: relative;
+}
+.scroller2{
+   height: calc(100% - 4.5rem);
+}
+.scroller3{
+   height: calc(100% - 3.7rem);
+}
+.scroller4{
+   height: calc(100% - 2.84rem);
+}
+.all {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+}
+.search-box {
+  border-radius: 25px;
+  padding:0.1rem;
+  border: 1px solid #f1f1f1;
+  font-size: 0.28rem;
+}
+.header {
+  background-color: #fff;
+  padding: 0.2rem;
+  font-size: 0.28rem;
+  margin-bottom: 0.2rem;
+}
+.search-item{
+  padding: 0.06rem 0.1rem;
+  background-color: #F7F8FA;
+  color: #89919F;
+  width: 1.2rem;
+  text-align: center;
+  margin-right: 0.2rem;
+  margin-bottom: 0.2rem;
+  border-radius: 3px;
+  font-size: 0.3rem;
+}
+.searchActive{
+  color: #26A2FF;
+  background-color: #E9F0FD;
+}
+.btn{
+  background-color: #26A2FF;
+  color: #fff;
+  text-align: center;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  border-radius: 25px;
+}
+</style>

+ 945 - 0
src/performance-07-19/view/myTarget/targetDetail.vue

@@ -0,0 +1,945 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="目标详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all-box">
+      <template v-if="targetDetail.visible==1">
+        <header class="header">
+          <div class="flex-box">
+            <!-- 目标综合状态 1-未开始 2-负责人未接收 3-运行中 4-已延期 5-已达标(进度大于等于100) 6-已结束 -->
+<!--            <span class="status" v-if="targetDetail.composite_state==1">未开始</span>
+            <span class="status" v-if="targetDetail.composite_state==2">未接收</span>
+            <span class="status" v-if="targetDetail.composite_state==3">进行中</span>
+            <span class="status" v-if="targetDetail.composite_state==4">已延期</span>
+            <span class="status" v-if="targetDetail.composite_state==5">已达标</span> -->
+            <span class="status" v-if="targetDetail.composite_state==6">已结束</span>
+            <div class="flex-1" style="font-weight: 600;padding: 0 0.2rem;padding-left: 0.1rem;">{{targetDetail.name}}</div>
+          </div>
+          <div class="flex-box-ce" style="margin: 0.16rem 0;">
+            <div class="progress"><div class="progress-inner" :class="{bjYellow:targetDetail.risk_level==2,bjRed:targetDetail.risk_level==3}" :style="{width:targetDetail.process>100? '100%':targetDetail.process+'%'}"></div></div>
+            <span style="padding-left: 0.1rem;font-size: 0.24rem;" class="blue" :class="{orange:targetDetail.risk_level==2,red:targetDetail.risk_level==3}">{{ targetDetail.process }}%</span>
+            <template v-if="targetDetail.process != targetDetail.process_last">
+              <span v-if="targetDetail.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ targetDetail.updatePro }}%</span>
+              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ targetDetail.updatePro }}%</span>
+            </template>
+            <div class="flex-1"></div>
+            <div class="orange" v-if="targetDetail.score>=0">{{targetDetail.score}}</div>
+          </div>
+          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+            <span>{{$getEmployeeMapItem(targetDetail.owner_id).name}}</span>
+            <span style="margin: 0 0.1rem;padding: 0 0.1rem;border-left: 1px solid #f1f1f1;border-right: 1px solid #f1f1f1;">
+
+                {{targetDetail.belong_type==2? (dept_tree[targetDetail.dept_id]? dept_tree[targetDetail.dept_id].name:''):getBelongType(targetDetail.belong_type).name}}
+            </span>
+            <span class="flex-1">{{targetDetail.year}}年 {{targetDetail.dateStr}}</span>
+          </div>
+          <template v-if="targetDetail.kr_id">
+            <div class="flex-box" v-if="targetDetail.p_kr" style="font-size: 0.26rem;margin-top: 0.2rem;border-top: 1px solid #f1f1f1;padding-top: 0.2rem;height: 0.36rem;">
+                <span class="fontColorC">对齐目标:</span>
+                <div class="flex-1 font-flex-word">{{targetDetail.p_kr.name}}</div>
+            </div>
+          </template>
+          <template v-else-if="targetDetail.o_id">
+            <div class="flex-box" v-if="targetDetail.p_objectives" style="font-size: 0.26rem;margin-top: 0.2rem;border-top: 1px solid #f1f1f1;padding-top: 0.2rem;height: 0.36rem;">
+                <span class="fontColorC">对齐目标:</span>
+                <div class="flex-1 font-flex-word">{{targetDetail.p_objectives.name}}</div>
+            </div>
+          </template>
+        </header>
+        <van-tabs v-model="tabActive" class="shadow"><van-tab :title="item" v-for="(item, index) in tabs" :key="index"></van-tab></van-tabs>
+        <div class="scroller">
+          <scroller ref="scroller">
+            <template v-if="tabActive == 0">
+              <div class="list-box" v-for="(item, index) in krsList" :key="index" @click="openDetail(item,2)">
+                <div class="clamp2" style="margin-bottom: 5px;">{{item.name}}</div>
+                <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                  <span>{{$getEmployeeMapItem(item.owner_id).name}}</span>
+                  <span class="padding-l-r flex-box-ce">{{item.weight}}%</span>
+                  <span class="flex-box-ce" style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;"><van-icon name="star" class="yellow" />{{item.confident}}分</span>
+                  <van-circle :key="item.id" layer-color="#E5E9F2" v-model="item.currentRate" :color="item.risk_level==2? '#FF9600':item.risk_level==3? '#f56c6c':' #2879ff'" :rate="item.process"  :stroke-width="120" size="20px"/>
+                  <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:item.risk_level==2,red:item.risk_level==3}">{{ item.process }}%</span>
+                </div>
+              </div>
+
+            </template>
+            <template v-if="tabActive == 1">
+              <div class="list-box" v-for="(item, index) in krsListAll" :key="index">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;border-bottom: 1px solid #f1f1f1;padding-bottom: 0.2rem;">
+                  <div class="blue" style="font-size: 0.26rem;font-weight: 600;margin-right: 0.1rem;">KR{{index+1}}</div>
+                  <div class="flex-1 font-flex-word" style="padding-right: 0.2rem;font-size: 0.3rem;">{{item.name}}</div>
+                  <!-- <span style="font-size: 0.26rem;" v-if="item.plans.length>0">计划任务<span class="blue">{{returnSum(item.plans)}}</span>/<span>{{item.plans.length}}</span></span> -->
+                </div>
+                <div style="padding:0 0.1rem;">
+
+                  <template v-if="item.projects.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index3) in item.projects" :key="task_item.id" @click="openDetail(task_item,3)">
+                        <van-icon name="paid" class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"/>
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD')}} 截止</span>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <template v-if="item.plans.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index2) in item.plans" :key="index2" @click="openDetail(task_item,1)">
+                        <van-icon :name="taskStatus(task_item.composite_state).icon"
+                        class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"
+                        :class="(task_item.day<=0&&$moment(task_item.end_date).format('YYYY-MM-DD')!=$moment().format('YYYY-MM-DD')) ? 'red':''"
+                        />
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD HH:mm')}} 截止</span>
+                            <template v-if="task_item.statistics.plan_total">
+                              <van-icon name="orders-o" />
+                              <span style="font-size: 0.26rem;">
+                                <span class="blue">{{task_item.statistics.plan_finish}}</span>/<span>{{task_item.statistics.plan_total}}</span>
+                              </span>
+                            </template>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <div v-if="item.projects.length==0&&item.plans.length==0" style="text-align: center;margin: 0.2rem 0;font-size: 0.28rem;" class="fontColorC">用“项目/任务”推动目标达成,合理规划安排工作</div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive == 3">
+              <div style="height: 100%;background-color: #fff;padding: 0.2rem;border-top: 1px solid #f1f1f1;">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;">
+                  <div class="flex-1">
+                    <div class="user-title">发布人</div>
+                    <div class="flex-box-v" style="text-align: center;width: 1.06rem">
+                      <userImage :id="targetDetail.publisher_id" :user_name="$getEmployeeMapItem(targetDetail.publisher_id).name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;" class="font-flex-word">{{ $getEmployeeMapItem(targetDetail.publisher_id).name }}</div>
+                    </div>
+                  </div>
+                  <div class="flex-1">
+                    <div class="user-title">负责人</div>
+                    <div class="flex-box-ce">
+                      <div style="text-align: center;width: 1.06rem">
+                        <userImage :img_url="targetDetail.owner_userInfo.img_url" :user_name="targetDetail.owner_userInfo.name" width="0.7rem" height="0.7rem"></userImage>
+                        <div style="font-size: 0.26rem;padding: 0.1rem 0;" class="font-flex-word">{{ targetDetail.owner_userInfo.name }}</div>
+                      </div>
+                      <div class="zj" v-if="isUpdate" @click="openSelectUser(1)">转交</div>
+                    </div>
+                  </div>
+                </div>
+                <div style="margin-bottom: 0.2rem;">
+                  <div class="user-title">参与人员</div>
+                  <div class="flex-box-ce flex-d-wrap">
+                    <div class="flex-box-v" style="margin-right: 0.2rem;text-align: center;margin-bottom: 0.2rem;position: relative;"  v-for="(item, index) in targetDetail.joiner_employee_items"  :key="index" >
+                      <userImage :img_url="item.img_url" :user_name="item.name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;width: 1.06rem" class="font-flex-word">{{ item.name }}</div>
+                      <!-- <van-icon name="clear" class="delete-user red" /> -->
+                      <div class="zj2" v-if="isUpdate" @click="joinerUpdate(false,item.id)">删除</div>
+                    </div>
+                    <div class="addUser" v-if="isUpdate" @click="openSelectUser(2)">+</div>
+                  </div>
+                </div>
+                <div style="margin-bottom: 0.2rem;">
+                  <div class="user-title">关注人员</div>
+                  <div class="flex-box-ce flex-d-wrap">
+                    <div class="flex-box-v" style="margin-right: 0.2rem;text-align: center;margin-bottom: 0.2rem;" v-for="(item, index) in targetDetail.follower_employee_items" :key="index">
+                      <userImage :img_url="item.img_url" :user_name="item.name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;width: 1.06rem" class="font-flex-word">{{ item.name }}</div>
+                      <div class="zj2" v-if="isUpdate" @click="deleteFollower(false,item.id)">删除</div>
+                    </div>
+                    <div class="addUser" v-if="isUpdate" @click="openSelectUser(3)">+</div>
+                  </div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive == 2">
+              <div style="padding: 0.2rem;background-color: #fff;border-top: 1px solid #f1f1f1;">
+                <div class="flex-box-ce flex-d-wrap">
+                  <div class="search-item" @click="targetType = item.id"  v-for="(item, index) in targetTypeArr" :key="index"  :class="item.id == targetType ? 'searchActive' : ''">{{ item.name }}</div>
+                  <div class="flex-1"></div>
+                </div>
+                <template v-if="targetType==1">
+                  <div v-for="(item, index) in processList" :key="index" style="margin-top: 0.24rem;">
+                    <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                      <span class="biaos" :class="{ biaos2: item.risk_level == 2, biaos3: item.risk_level == 3 }"></span>
+                      <div class="black flex-1" style="font-weight: 700;font-size: 16px;">
+                      {{ item.process }}%
+                        <template v-if="item.process != item.process_last">
+                          <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                          <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                        </template>
+                      </div>
+                      <span class="fontColorC" style="font-size: 0.26rem;">{{ item.create_time }}</span>
+                    </div>
+                    <div class="flex-box o-content">
+                      <pre v-if="item.content" class="flex-1 fontColorB" style="margin: 0px;">{{ item.content }}</pre>
+                      <div v-else class="flex-1 fontColorD">暂无内容</div>
+                    </div>
+                  </div>
+                  <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processList.length==0">目标进展一目了然?赶快更新完成度吧</div>
+                </template>
+                <template v-if="targetType==2">
+                    <div v-for="(item, index) in processData.kr" :key="index" style="margin-top: 0.24rem;">
+                      <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                        <span class="biaos" :class="{biaos2:item.process_info&&item.process_info.risk_level==2,biaos3:item.process_info&&item.process_info.risk_level==3}"></span>
+                        <span class="okr-index">KR{{ index + 1 }}</span>
+                        <div class="font-flex-word fontColorC flex-1" style="padding-right:0.2rem;font-size: 0.28rem;">{{item.name}}</div>
+                        <div class="black" style="font-weight: 700;font-size: 16px;">
+                            {{ item.process }}%
+                            <template v-if="item.process != item.process_last">
+                              <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                            </template>
+                        </div>
+                      </div>
+                      <div v-if="item.process_info">
+                        <div class="o-content fontColorB">
+                            <pre v-if="item.process_info.content" style="margin: 0px;">{{item.process_info.content}}</pre>
+                            <span v-else class="fontColorD" style="font-size: 13px;">暂未更新</span>
+                        </div>
+                        <div style="padding-left: 0.34rem;font-size: 12px;" class="fontColorC">{{item.process_info.create_time}}</div>
+                      </div>
+                      <div class="pre fontColorD" v-else style="font-size: 13px;padding: 5px 0.5rem;">暂未更新</div>
+                    </div>
+                    <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processData.kr==0">暂无进展</div>
+                </template>
+                <template v-if="targetType==3">
+                    <div v-for="(item, index) in processData.objectives" :key="index" style="margin-top: 0.24rem;">
+                      <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                        <span class="biaos" :class="{biaos2:item.process_info&&item.process_info.risk_level==2,biaos3:item.process_info&&item.process_info.risk_level==3}"></span>
+                        <div class="huan"><span></span></div>
+                        <div class="font-flex-word fontColorC flex-1" style="padding-right:0.2rem;font-size: 0.28rem;">{{item.name}}</div>
+                        <div class="black" style="font-weight: 700;font-size: 16px;">
+                            {{ item.process }}%
+                            <template v-if="item.process != item.process_last">
+                              <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                            </template>
+                        </div>
+                      </div>
+                      <div v-if="item.process_info">
+                        <div class="o-content fontColorB">
+                            <per v-if="item.process_info.content" style="margin: 0px;">{{item.process_info.content}}</per>
+                            <span v-else class="fontColorD" style="font-size: 13px;">暂未更新</span>
+                        </div>
+                        <div style="padding-left: 0.34rem;font-size: 12px;" class="fontColorC">{{item.process_info.create_time}}</div>
+                      </div>
+                      <div class="pre fontColorD" v-else style="font-size: 13px;padding: 5px 0.5rem;">暂未更新</div>
+                    </div>
+                    <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processData.objectives==0">暂无进展</div>
+                </template>
+              </div>
+            </template>
+            <div style="height: 3rem;"></div>
+          </scroller>
+          <footer class="footer">
+            <div class="flex-box-ce">
+               <van-icon name="chat-o" @click="openCommunication" style="margin-left: 0.2rem;font-size:0.6rem;" class="fontColorC"/>
+            </div>
+          </footer>
+        </div>
+      </template>
+
+       <van-row type="flex" justify="space-around" class="c" v-else>
+          <van-col span="24">
+            <div style="text-align: center;margin-top: 2rem;margin-bottom: 1rem;">
+              <img src='static/images/noPeople.png' style="width: 3.5rem;"/>
+            </div>
+            <p class="text_center fontColorC">暂无查看权限</p>
+          </van-col>
+        </van-row>
+    </div>
+    <van-dialog v-model="isShowProcess" show-cancel-button :beforeClose="subContent">
+      <van-cell-group>
+        <van-field v-model="processInfo.content" rows="4"  class="textarea-box" type="textarea" maxlength="500" placeholder="请输入进展与障碍" show-word-limit/>
+      </van-cell-group>
+    </van-dialog>
+
+    <!-- 进度 -->
+    <Progress :visible.sync="isShwoUpdateProgress" :progressData="progressData" @confirm="update"></Progress>
+    <!-- 添加KR -->
+    <AddKr :o_id="Number(o_id)" :isShowWeight="false" :visible.sync="isShowAddKr" @confirm="confirmAddkr"></AddKr>
+    <!-- 详情 -->
+    <van-action-sheet v-model="isShowbelong" :actions="scopeArr" @select="activebelong" cancel-text="取消" close-on-click-action/>
+    <!-- 修改基本信息 -->
+    <UpdateTarget :visible.sync="isShwoUpdateDetail" :targetDetail="targetDetail" :o_id="Number(o_id)" @confirm="getTargetDateil"></UpdateTarget>
+    <!-- 关联任务 -->
+    <TaskSearch :visible.sync="isShwoTaskSearch" @confirm="ActiveRelevanceTask"></TaskSearch>
+    <!-- 人员选择 -->
+    <EmployeeSelector :multi="false" :isRequired="true" key="selected_user" title="选择人员" :visible.sync="selectUser" @confirm="confirmUser" :can_select_dept="false" :selected.sync="selected_user"></EmployeeSelector>
+
+    <!-- 可见范围 -->
+    <van-action-sheet v-model="isShowV" :actions="vArr" @select="activevArr" cancel-text="取消" close-on-click-action/>
+
+    <!-- 关联KR -->
+    <TargetSearch :visible.sync="isShwoKrSearch" :showSelectType="2" @confirm="ActiveRelevanceKr"></TargetSearch>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { Tab, Tabs, Circle,ActionSheet } from 'vant';
+import UpdateTarget from '@/okr/components/public/UpdateTarget';
+import TaskSearch from '@/okr/components/public/TaskSearch';
+import AddKr from '@/okr/components/public/AddKr';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import Progress from '@/okr/components/public/Progress';
+import TargetSearch from '@/okr/components/public/TargetSearch';
+
+import {taskStatus,getBelongType,getDateStr,getOperation} from '@/okr/utils/auth';
+Vue.use(Tabs).use(Tab).use(Circle).use(ActionSheet);
+export default {
+  components:{UpdateTarget,AddKr,TaskSearch,EmployeeSelector,Progress,TargetSearch},
+  data() {
+    return {
+      targetDetail:{visible:1},
+      processInfo:{},
+      getBelongType:getBelongType,
+      taskStatus:taskStatus,
+      userInfo: this.$userInfo(),
+      tabActive: 0,
+      tabs: ['OKRs', '计划', '进展','成员'],
+      targetTypeArr: [{ name: '目标进展', id: 1 }, { name: 'KR进展', id: 2 }, { name: '子目标进展', id: 3 }],
+      targetType: 1,
+      isShowbelong:false,
+      isShwoTaskSearch:false,
+      scopeArr:[{value: 0, name:'关注目标', disabled: false},{value: 1, name:'编辑基本信息',disabled: false},{value: 2,name:'结束目标',disabled: false},{value: 4,name:'复制目标',disabled: false},{value: 3,name:'删除目标',color: '#f56c6c',disabled: false}],
+      processList: [],
+      processData:{kr:[],objectives:[]},
+      isShwoUpdateDetail:false,
+      isShowAddKr:false,
+      userId:0,
+      krName:'',
+      weight:0,
+      o_id:0,
+      kr_id:0,
+      krsList:[],
+      krsListAll:[],//包括任务
+      isFollower:false,//是否关注
+      isUpdate:false,
+      selectUser:false,
+      selected_user: { dept: [], employee: [] } ,//传入已选部门
+      isShwoUpdateProgress:false,
+      progressData:{},
+      isShowProcess:false,
+      isOperation:true,
+      dept_tree:{},
+
+      // 可见范围
+      isShowV:false,
+      vArr:[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}],
+      addTaskIndex:1,
+      selectKr:{},
+      isShwoKrSearch:false,
+    };
+  },
+  watch:{
+    isFollower(val){
+      if(val){
+        this.scopeArr.forEach(item=>{
+          if(item.value==0){item.name='取消关注'}
+        })
+      }else{
+        this.scopeArr.forEach(item=>{
+          if(item.value==0){item.name='关注目标'}
+        })
+      }
+    },
+    tabActive(val){
+      if(val==0){
+        this.getKrList();
+      }else if(val==1){
+        this.getkrTaskList();
+      }else if(val==2){
+        this.getProcess();
+      }
+    }
+  },
+  methods: {
+    //关联项目
+    ActiveRelevanceKr(item){
+      this.$axiosUser('post', '/api/pro/okr/project/bind',{project_id:item.item.id,kr_id:this.selectKr.id}).then(res => {
+       this.getkrTaskList();
+      });
+    },
+    activevArr(item){
+      if(this.addTaskIndex==1){
+        if(item.value==1){
+          let data={
+            target_type:	2,//是	string	计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
+            target_id:this.selectKr.id,//是	integer	绑定的对象id 跟对象种类配对使用
+          }
+          this.$router.push({name: 'addTask', query: data})
+        }else{
+          this.$router.push({name: 'addProject', query: {kr_id:this.selectKr.id}})
+        }
+      }else{
+        if(item.value==1){
+            this.kr_id=this.selectKr.id;
+            this.isShwoTaskSearch=true;
+        }else{
+            this.isShwoKrSearch=true;
+        }
+      }
+    },
+    openDetail(item,type){
+
+      if(type==1){
+        this.$router.push({name: 'myTargetDetail', query: {id: item.id}})
+      }else if(type==2){
+        this.$router.push({name: 'myKrDetail', query: {id: item.id}})
+      }else if(type==3){
+        // this.$router.push({name: 'projectDetail', query: {id: item.id}})
+        return
+      }
+    },
+    subContent(action, done){
+       if (action == 'confirm') {
+         this.$axiosUser('post', '/api/pro/okr/process/content',{p_id: this.processInfo.id, content: this.processInfo.content}).then(res => {
+           this.getProcess();
+           this.isShowProcess = false;
+         })
+         done()
+       }else{
+         done()
+       }
+    },
+    compileContent(item){
+      this.processInfo = JSON.parse(JSON.stringify(item));
+      this.isShowProcess = true;
+    },
+    update(){
+      this.getTargetDateil();
+      this.getProcess();
+    },
+    // 沟通
+    openCommunication(){
+      let data = {
+        item: JSON.stringify(this.targetDetail),
+        target_type: 1,
+        readonly: 1
+      }
+      this.$router.push({name: 'communication', query:data})
+    },
+    // 获取部门列表
+    returnArr(list,arr){
+      list.forEach(item=>{
+        arr[item.id]=item
+        if(item.children.length>0){
+          this.returnArr(item.children,arr)
+        }
+      })
+    },
+    // 获取部门列表
+    get_department_list() {
+      this.$axiosUser('get','/api/pro/department/tree','','v2').then((res) => {
+          let list=res.data.data.list
+          let dept_tree={};
+          this.returnArr(list,dept_tree)
+          this.dept_tree=dept_tree
+      })
+    },
+    //更新完成度
+    updateProgress(){
+      let item=this.targetDetail;
+      this.progressData={
+        target_type:1,
+        id:item.id,
+        o_id:item.id,
+        process:Number(item.process),
+        risk_level:item.risk_level,
+        process_conf:item.process_conf,
+      }
+      this.isShwoUpdateProgress=true;
+    },
+    //获取最新字段
+    getProcess(){
+      let axios= this.$axiosUser('get', '/api/pro/okr/public/process/list', {target_type:1,target_id:this.o_id,page:1,page_size:100})
+      let axios2= this.$axiosUser('get', '/api/pro/okr/public/process/sub', {target_type:1,target_id:this.o_id})
+      Promise.all([axios,axios2]).then(res => {
+          let data=res[1].data.data
+          data.objectives=this.updatePro(data.objectives);
+          data.kr=this.updatePro(data.kr);
+          this.processData=data;
+          this.processList=this.updatePro(res[0].data.data.list)
+      })
+    },
+    updatePro(arr){
+      arr.forEach(item=>{
+         item.updatePro=Math.abs(item.process-item.process_last).toFixed(2);
+         item.isUpdatePro=item.process-item.process_last
+      })
+      return arr;
+    },
+    openSelectUser(index){
+      this.selectUserIndex=index;
+      this.selectUser=true;
+    },
+    confirmUser(data) {
+      let user=data.employee[0]
+      if(this.selectUserIndex==1){
+        let params={object_id:this.targetDetail.id,owner_id:user.id,}
+        this.$axiosUser('POST', 'api/pro/okr/obj/change_owner', params).then(res => {
+            this.getTargetDateil();
+        })
+      }else if(this.selectUserIndex==2){
+        this.joinerUpdate(true,user.id);
+      }else{
+        this.deleteFollower(true,user.id);
+      }
+    },
+    //参与者
+    joinerUpdate(is,id){
+      let data={
+        object_id:this.o_id,
+        joiner_id:id,
+        action:is? 'add':'remove',
+      }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_joiner',data).then(res => {
+          this.getTargetDateil();
+      })
+    },
+    //关注者
+    deleteFollower(is,id){
+      let data={
+        object_id:this.o_id,
+        employee_id:id,
+        action:is? 'add':'remove',
+      }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_focus',data).then(res => {
+          this.getTargetDateil();
+      })
+    },
+    //关联母任务
+    ActiveRelevanceTask(item){
+        if(item.id){
+          this.$axiosUser('POST', '/api/pro/okr/plan/relate/other',{plan_id:item.id,target_type:2,target_id:this.kr_id}).then(res => {
+               this.getkrTaskList();
+          })
+        }
+    },
+    addTask(item,index){
+      this.addTaskIndex=index;
+      this.selectKr=item;
+      if(index==1){
+        this.vArr=[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}];
+      }else{
+        this.vArr=[{value: 1,name: '关联任务'},{value: 2,name: '关联项目'}];
+      }
+      this.isShowV=true;
+    },
+    confirmAddkr(item){
+      this.$axiosUser('POST','api/pro/okr/kr/create',item).then(res => {
+         this.$toast("已添加");
+         this.getKrList()
+      })
+    },
+    activebelong(item){
+      if(item.value==0){//关注
+        this.$axiosUser('POST','/api/pro/okr/obj/follow',{o_id:this.o_id}).then(res => {
+           this.$toast(this.isFollower? "已取消":'已关注');
+           this.getTargetDateil();
+        })
+      }else if(item.value==1){//编辑
+        this.isShwoUpdateDetail=true;
+      }else if(item.value==2){//结束目标
+        if(item.name=='结束目标'){
+          this.$dialog.confirm({ title:'结束', message: '确定要结束目标吗?'}).then(() => {
+            this.$axiosUser('post', '/api/pro/okr/obj/to_finish', { object_id: this.o_id }).then(res => {
+                this.getTargetDateil()
+            });
+          });
+        }else{
+          this.$axiosUser('POST', '/api/pro/okr/obj/to_start',{object_id:this.o_id}).then(res => {
+             this.getTargetDateil()
+          })
+        }
+      }else if(item.value==3){//删除
+        this.$dialog.confirm({ title:'删除', message: '目标删除操作不可恢复!请谨慎操作'}).then(() => {
+          this.$axiosUser('post', '/api/pro/okr/public/obj/d', { o_id: this.o_id }).then(res => {
+              this.$toast("已删除");
+              setTimeout(()=>{
+                this.$route_back()
+              },500)
+          });
+        });
+      }else if(item.value==4){//复制目标
+        this.$router.push({name: 'copyTarget', query: {id:this.o_id}})
+      }
+    },
+    returnSum(arr){
+      if(arr.length==0){return 0};
+      let sum=0;
+      arr.forEach(item=>{
+        if(item.composite_state==6){
+          sum++;
+        }
+      })
+      return sum
+    },
+    //执行
+    getkrTaskList(){
+	  if(!this.o_id){
+		  return false
+	  }
+      let data={
+        o_id:this.o_id,//	是	string	目标id
+        plan_calc: 1
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/plan/list/o',data).then(res => {
+        let list=res.data.data.list;
+        list.forEach(e=>{
+          if(e.plans&&e.plans.length>0){
+            e.plans.forEach(item=>{
+              item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
+            })
+          }
+        })
+        this.krsListAll=list;
+      })
+    },
+    //OKRs
+    getKrList(){
+      this.krsList=[];
+      this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.o_id}).then(res => {
+          let list=res.data.data.list;
+          this.krsList=list
+      })
+    },
+    //目标详情
+    getTargetDateil(){
+      this.isFollower=false;
+      this.$axiosUser('get', '/api/pro/okr/public/obj/detail',{object_id:this.o_id}).then(res => {
+          let data=res.data.data;
+          data.dateStr=getDateStr(data)
+          data.owner_userInfo=this.$getEmployeeMapItem(data.owner_id);//负责人
+          data.special_employee_items=data.special_employee_ids.map(e=>{ //可见人员
+              return this.$getEmployeeMapItem(e)
+          })
+          data.joiner_employee_items=data.joiner_ids.map(e=>{//参与人员
+              return this.$getEmployeeMapItem(e)
+          })
+          data.follower_employee_items=data.follower_ids.map(e=>{//关注者
+              return this.$getEmployeeMapItem(e)
+          })
+          if(data.follower_ids.length>0){
+            data.follower_ids.some(e=>{//关注者
+                if(e==this.userInfo.id){
+                   this.isFollower=true;
+                   return true
+                }
+            })
+          }
+          if(data.finish_status!=0){
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){item.name='重启目标'}
+            })
+          }else{
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){ item.name='结束目标' }
+            })
+          }
+
+          // 权限[{value: 0, name:'关注目标'},{value: 1, name:'编辑基本信息'},{value: 2,name:'结束目标'},{value: 3,name:'删除目标',color: '#f56c6c'}],
+          if(!data.can_edit){ //不可编辑
+            this.scopeArr.forEach(item=>{
+              if(item.value==1){
+                item.disabled=true
+              }
+              if(item.value==2&&item.name=='结束目标'){
+                item.disabled=true
+              }
+              // if(item.value==4){
+              //   item.disabled=true
+              // }
+            })
+          }
+          if(!data.can_delete){ //不可删除
+            this.scopeArr.forEach(item=>{
+              if(item.value==3){item.disabled=true}
+            })
+          }
+
+          this.isOperation=getOperation(data.publisher_id,data.owner_id);
+          this.targetDetail=this.updatePro([data])[0];
+      })
+    },
+  },
+  mounted() {
+    this.get_department_list();
+    if(this.$route.query.id){
+      this.o_id=this.$route.query.id;
+      this.getTargetDateil();
+      this.getKrList();
+    }
+  },
+  activated() {
+  	 this.getkrTaskList();
+  }
+};
+</script>
+
+<style scoped lang="less">
+  .textarea-box /deep/ .van-field__control{
+    max-height: 400px;
+  }
+  .footer {
+    padding: 0.14rem 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+  }
+  .footer .gt {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    border: 0.02rem solid #f1f1f1;
+    font-size: 0.32rem;
+  }
+  .footer i{
+    font-size: 0.6rem;
+  }
+  .footer .btn {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    // border: 0.02rem solid #26A2FF;
+    color: #fff;
+    text-align: center;
+    background: #26A2FF;
+    font-size: 0.32rem;
+  }
+  .huan{
+    position: relative;
+    width: 0.4rem;
+    height: 0.4rem;
+    border-radius: 100%;
+    background-color: #E9F1FE;
+    box-sizing: border-box;
+    text-align: center;
+    margin-right: 0.1rem;
+  }
+  .huan span{
+    border: 2px solid #26A2FF;
+    border-radius: 100%;
+    width: 0.16rem;
+    height: 0.16rem;
+    display: inline-block;
+  }
+  .status{
+    position: relative;
+    // top: 1px;
+    font-size: 0.24rem;
+    border-radius: 15px;
+    line-height:0.32rem;
+    color: #26A2FF;
+    height: 0.32rem;
+    padding: 0px 0.04rem;
+    border: 1px solid #26A2FF;
+  }
+  .aite{
+      width: 1rem;
+      height: 1rem;
+      text-align: center;
+      line-height: 1rem;
+      font-size: 0.6rem;
+      cursor: pointer;
+      display: inline-block;
+      box-shadow: 0 0 3px #89919f;
+      border-radius: 100%;
+      background-color: #fff;
+      position: absolute;
+      z-index: 2;
+      bottom: 0.4rem;
+      right: 0.4rem;
+  }
+  .aite i{
+    font-size: 0.36rem;
+  }
+.o-content {
+  border-radius: 5px;
+  padding: 5px;
+  margin-left: 0.24rem;
+  margin-bottom: 5px;
+  font-size: 0.28rem;
+}
+.o-content:hover {
+  background-color: #f7f8fa;
+}
+.o-content:hover .fontColorC {
+  display: block !important;
+  cursor: pointer;
+}
+.biaos {
+  width: 0.14rem;
+  height: 0.14rem;
+  background-color: #26a2ff;
+  border: 1px solid #fff;
+  border-radius: 100%;
+  box-shadow: 0 0 0.14rem #26a2ff;
+  display: inline-block;
+  margin-right: 0.14rem;
+}
+.biaos2 {
+  background-color: #ff9600;
+  box-shadow: 0 0 0.14rem #ff9600;
+}
+.biaos3 {
+  background-color: #f56c6c;
+  box-shadow: 0 0 0.14rem #f56c6c;
+}
+.add-jz {
+  width: 1.4rem;
+  text-align: center;
+  padding: 0.04rem 0.08rem;
+  color: #26a2ff;
+  border: 1px solid #26a2ff;
+  border-radius: 25px;
+  cursor: pointer;
+  font-size: 0.26rem;
+}
+.search-item {
+  padding: 0.06rem 0.1rem;
+  background-color: #f7f8fa;
+  color: #89919f;
+  width: 1.3rem;
+  text-align: center;
+  margin-right: 0.2rem;
+  border-radius: 3px;
+  font-size: 0.3rem;
+  border-radius: 25px;
+  font-size: 0.26rem;
+}
+.searchActive {
+  color: #26A2FF;
+  background-color: #e9f0fd;
+}
+.delete-user {
+  position: absolute;
+  right: -4px;
+  top: -4px;
+  padding: 0;
+}
+.btns span {
+  width: 1.4rem;
+  text-align: center;
+  padding: 0.04rem 0.1rem;
+  color: #26A2FF;
+  margin-right: 0.2rem;
+  border: 0.02rem solid #26A2FF;
+  border-radius: 0.06rem;
+  font-size: 0.26rem;
+}
+.user-title {
+  font-size: 0.28rem;
+  // font-weight: 700;
+  color: #89919f;
+  margin: 0.2rem 0;
+}
+.addUser {
+  font-size: 0.6rem;
+  padding: 0.2rem;
+  border: 1px dashed #89919f;
+  text-align: center;
+  height: 0.4rem;
+  width: 0.4rem;
+  line-height: 0.4rem;
+  color: #89919f;
+  border-radius: 100px;
+}
+.zj {
+  width: 1rem;
+  text-align: center;
+  color: #26A2FF;
+  border: 0.02rem solid #26A2FF;
+  border-radius: 0.04rem;
+  font-size: 0.24rem;
+}
+.zj2 {
+  width: 1rem;
+  text-align: center;
+  color: #f56c6c;
+  border: 0.02rem solid #f56c6c;
+  border-radius: 0.04rem;
+  font-size: 0.24rem;
+}
+.addKr {
+  padding: 0.2rem;
+  font-size: 0.3rem;
+  background-color: #fff;
+  border-radius: 5px;
+  text-align: center;
+  margin: 0 0.2rem;
+  margin-top: 0.2rem;
+}
+.padding-l-r {
+  padding: 0 0.1rem;
+  border-left: 1px solid #f1f1f1;
+  border-right: 1px solid #f1f1f1;
+  margin: 0 0.1rem;
+}
+.scroller {
+  height: calc(100% - 3.58rem) !important;
+  position: relative !important;
+}
+.list-box {
+  padding: 0.2rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0.2rem;
+  margin-top: 0.2rem;
+}
+.shadow {
+  border-bottom: 1px solid #f5f7fa;
+}
+/deep/ .van-tabs__line {
+  width: 20px !important;
+  background-color: #26A2FF;
+}
+/deep/ .van-tab--active {
+  color: #26A2FF;
+}
+.all-box {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+}
+.progress {
+  border-radius: 100px;
+  background-color: #ebeef5;
+  overflow: hidden;
+  position: relative;
+  vertical-align: middle;
+  height: 0.2rem;
+  width: 3rem;
+}
+.progress-inner {
+  width: 0%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding-top: 1px;
+  height: 100%;
+  background-image: linear-gradient(to right, #99bbff 0%, #2879ff 100%);
+  border-radius: 100px;
+  color: #fff;
+  white-space: nowrap;
+  transition: width 0.6s ease;
+}
+  .bjYellow{
+    background-image: linear-gradient(to right, #fedf86 0%, #FF9600 100%);
+  }
+  .bjRed{
+    background-image: linear-gradient(to right, #FEA2A2 0%, #F16060 100%);
+  }
+.header {
+  padding: 0.24rem;
+  background-color: #fff;
+  z-index: 9999;
+  // background-image: linear-gradient(to bottom, #26A2FF 0%, #99BBFF 100%);
+}
+</style>

+ 126 - 0
src/performance-07-19/view/navhome/me - 副本.vue

@@ -0,0 +1,126 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="我的绩效" left-text="返回" left-arrow @click-left="$route_back" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <scroller ref="me_scroller" class="all">
+        <footer style="padding-bottom:1rem;">
+          <div style="height:.2rem; background-color:#f5f7fa;"></div>
+          <van-empty description="暂无绩效考核数据" v-if="meList.length == 0" />
+          <div
+            v-else
+            class="me_list performanceList"
+            v-for="(item, index) in meList"
+            :key="index"
+            :style="'z-index:' + (meList.length - index)"
+            @click="$router.push({ name: 'performanceDetails', query: { id: item.id, Tit: item.package_name } })"
+          >
+            <div class="me_list_img">
+              <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+            </div>
+            <div class="me_list_content">
+              <div class="me_list_tit">{{ item.package_name }}</div>
+              <span v-if="item.current_node == 'result' || !item.current_node" class="me_list_result">
+                <span v-if="item.result">
+                  <span class="me_list_col">绩效结果:</span>
+                  {{ item.result }}
+                  <br />
+                </span>
+                <span v-if="item.grade">
+                  <span class="me_list_col">绩效等级:</span>
+                  {{ item.grade }}
+                  <br />
+                </span>
+                <span class="me_list_resultTit">考核结束</span>
+              </span>
+              <div v-else class="me_list_course">
+                {{
+                  item.current_node == 'target'
+                    ? '目标制定'
+                    : item.current_node == 'confirm'
+                    ? '目标确定'
+                    : item.current_node == 'execution'
+                    ? '执行中'
+                    : item.current_node == 'result_value'
+                    ? '结果值录入'
+                    : item.current_node == 'score' || item.current_node == 'special_scorer'
+                    ? '评分'
+                    : item.current_node == 'review'
+                    ? '审批'
+                    : ''
+                }}
+              </div>
+            </div>
+          </div>
+        </footer>
+      </scroller>
+    </VanSkeleton>
+  </div>
+</template>
+<script>
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+export default {
+  data() {
+    return {
+      skeletonLoad: true,
+      meList: []
+    };
+  },
+  components: { VanSkeleton },
+  methods: {
+    myPerformanceList() {
+      let params = {
+        employee_id: this.$userInfo().id
+      };
+      this.$axiosUser('get', '/api/pro/per/package/employee/list', params).then(res => {
+        if (res.data.code == 1) {
+          let data = res.data.data.list;
+          this.meList = data;
+          this.skeletonLoad = false;
+        }
+      });
+    }
+  },
+  created() {},
+  mounted() {
+    this.myPerformanceList();
+  }
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+  padding-bottom: 0.5rem;
+}
+.me_list {
+  background-color: #fff;
+  display: flex;
+  padding: 0.24rem 0.32rem;
+  margin-bottom: 0.11rem;
+  .me_list_content {
+    padding-left: 0.3rem;
+    .me_list_tit {
+      font-size: 0.33rem;
+    }
+    .me_list_result {
+      font-size: 0.3rem;
+      .me_list_col {
+        color: #adadad;
+      }
+      .me_list_resultTit {
+        display: inline-block;
+        padding-bottom: 0.18rem;
+        color: #3bdf9a;
+      }
+    }
+    .me_list_course {
+      display: inline-block;
+      padding-bottom: 0.18rem;
+      font-size: 0.28rem;
+      color: #ff9439;
+    }
+  }
+}
+</style>

+ 453 - 0
src/performance-07-19/view/navhome/me.vue

@@ -0,0 +1,453 @@
+<template>
+  <div class="all" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="我的绩效" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="overall">
+      <VanSkeleton :skeLoad="skeletonLoad">
+        <scroller>
+          <div class="title">
+              <span>考核信息</span>
+              <span class="more-btn" @click="goMorePage()">
+                查看更多
+                <van-icon name="arrow" />
+              </span>
+
+              </div>
+
+
+          <div class="list-box">
+
+            <div class="flex-box-ce" style="margin-bottom: 0.2rem;">
+              <div>
+                <userImage class="about-me__avatar" :id="showUserInfo.id" :img_url="showUserInfo.img_url"  :user_name="showUserInfo.name"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+              </div>
+              <div class="user-info">
+                <div style="margin-bottom: 0.05rem; color: #000;">{{ showUserInfo.name }}</div>
+                <template v-if="showDeptList && showDeptList.length > 0">
+                  <span v-for="item in showDeptList" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
+                </template>
+              </div>
+            </div>
+
+            <div class="examine-info">
+              <div class="info-item flex-box-ce">
+                考核周期:&nbsp;&nbsp;&nbsp; <div class="cycle-type">{{ cycleType | formatCycleType }}</div>
+              </div>
+              <div class="info-item">
+                <van-icon name="calendar" />考核时间:&nbsp;&nbsp;&nbsp;{{ startTime | formatDate }} 至 {{ endTime | formatDate }}
+              </div>
+              <div class="info-item">
+                考核等级:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ levelName || '-' }}</span>
+              </div>
+              <div class="info-item">
+                考核评分:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ score == undefined  || score == null || score == '' ? '-' : score }}</span>
+              </div>
+            </div>
+
+          </div>
+
+          <div class="title">指标列表</div>
+
+          <div class="list-box">
+            <div class="examine-info" v-for="(item, index) in indicators" :key="item.reviewIndicatorId">
+              <div class="tips">
+                <div class="tip-item" v-if="item.okrs && item.okrs.length > 0" @click="goMyTarget(item.okrs)">过程跟踪</div>
+                <div class="tip-item" @click="goDetails(item)">处理详情</div>
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  审批阶段:
+                </div>
+                <div v-if="item.businessStatus !== 'end'" class="review-node">
+                  {{ item.businessStatus | filterNodeStatus }}
+                </div>
+                <div v-else class="review-node" style="background-color: #FF9600;">
+                  {{ item.businessStatus | filterNodeStatus }}
+                </div>
+
+              </div>
+
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  指标:
+                </div>
+                {{ item.title }}
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  目标:
+                </div>
+                {{ item.target || '-' }} {{ item.target && item.unit ?  item.unit : '' }}
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  结果值:
+                </div>
+                {{ item.result || '-' }}
+              </div>
+
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  权重:
+                </div>
+                {{ item.weight || '-' }}
+              </div>
+              <div class="info-item flex-box-ce">
+                <div class="info-item-title">
+                  单位:
+                </div>
+                {{ item.unit || '-' }}
+              </div>
+
+              <div class="info-item" v-if="item.content">
+                <div class="info-item-title">
+                  规则:
+                </div>
+                <div class="bg-gray">
+                  {{ item.content }}
+                </div>
+              </div>
+
+              <div class="info-item" v-if="item.resultFiles && item.resultFiles.length > 0">
+                <div class="info-item-title" style="width: 2rem;">
+                  结果值附件:
+                </div>
+                <div class="bg-gray">
+                  <div v-for="(item, index) in item.resultFiles">
+                    附件{{ index + 1}}
+                  </div>
+                </div>
+
+              </div>
+
+              <div v-if="index !== indicators.length - 1" class="line"></div>
+            </div>
+          </div>
+
+          <OperateLogVue v-if="reviewId" :reviewId="reviewId"/>
+
+          <div style="width: 100%; height: 1rem;">
+
+          </div>
+        </scroller>
+      </VanSkeleton>
+    </div>
+  </div>
+</template>
+<script>
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import OperateLogVue from '@/performance/components/public/OperateLog.vue'
+import moment from 'moment';
+  export default {
+    components: {
+      VanSkeleton,
+      OperateLogVue
+    },
+
+  data() {
+    return {
+      skeletonLoad: true,
+      userInfo: this.$userInfo(),
+      meList: [],
+      title: "",
+      startTime: "",
+      endTime: "",
+      cycleType: "",
+      score: 0,
+      status: '',
+      levelName: '', // 考核详情信息
+      detailInfo: null,
+      indicators: [],
+      reviewId: '',
+      employeeId: "",
+      performList: [],
+      params: {
+        keyword: '',
+        page: 1,
+        pageSize: 10,
+        startDate: '',
+        endDate: '',
+        employeeId: ''
+      },
+    };
+  },
+
+  filters: {
+    filterNodeStatus(v) {
+      if (v === 'start') return '开始'
+      if (v === 'target_confirm') return '确认目标'
+      if (v === 'result_input') return '录入结果值'
+      if (v === 'score_self') return '自评'
+      if (v === 'score_each_other') return '互评'
+      if (v === 'score') return '评分'
+      if (v === 'review') return '审批'
+      if (v === 'cc') return '抄送'
+      if (v === 'end') return '结束'
+    },
+
+    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 '--'
+    },
+  },
+
+  computed: {
+    showUserInfo() {
+      return this.$getEmployeeMapItem(this.employeeId);
+    },
+    showDeptList() {
+      return this.$getEmployeeMapItem(this.employeeId).employee_detail.dept_list
+    }
+  },
+
+  methods: {
+    getTemplateList() {
+      let that = this
+      let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
+      // const startOfMonth = moment().startOf('month').format('YYYY-MM-DD') // 当月第一天
+      // const endOfMonth = moment().endOf('month').format('YYYY-MM-DD'); // 当月最后一天
+      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) {
+              if (list && list.length > 0) {
+                  that.performList = list;
+                  let { reviewId } = that.performList[0] || '';
+                  if (reviewId) that.getDetails(reviewId);
+              }
+          } else {
+              that.performList = [];
+          }
+      });
+    },
+
+
+    getDetails(reviewId) {
+        // reviewId = reviewId ? reviewId : 24
+        // this.loading = true
+        let url = `/performance/statistics/review/info/${this.$userInfo().site_id}/${reviewId}`
+        this.$axiosUser('get', url).then(res => {
+            this.skeletonLoad = false;
+            let { data: { reviewId, title, indicators, levelName, startTime, endTime, cycleType, score, status }, code } = res.data
+            this.reviewId = reviewId
+            if (code == 1) {
+                console.log(res)
+                this.detailInfo = res.data.data;
+                this.title = title || ''
+                this.cycleType = cycleType || ''
+                this.score = score
+                this.status = status || ''
+                this.startTime = startTime || ''
+                this.endTime = endTime || ''
+                this.levelName = levelName || ''
+                this.indicators = indicators.reverse() || [];
+
+                // 处理附件列表
+                if (this.tableData && this.tableData.length > 0) {
+                    let resultFiles = []
+                    this.tableData.forEach(item => {
+                        if (item.flow.nodes && item.flow.nodes.length > 0) {
+                            let resultInputNode = item.flow.nodes[1] // 取到结果值节点
+                            if (resultInputNode.tasks && resultInputNode.tasks.length > 0) {
+                                resultInputNode.tasks.forEach(task => {
+                                    if (task.files && task.files.length > 0) {
+                                        task.files.forEach(file => {
+                                            resultFiles.push(file)
+                                        })
+                                    }
+                                })
+                                item.resultFiles = resultFiles
+                            }
+                        }
+                    })
+                }
+            }
+
+        });
+    },
+
+    goMorePage() {
+      this.$router.push("/more")
+    },
+
+    goMyTarget(okrs) {
+      this.$router.push({name: 'myTarget', query: {ids: JSON.stringify(okrs)}});
+    },
+
+    goDetails(item) {
+      console.log(item);
+      let { reviewId, reviewIndicatorId, flow: { nodes } } = item
+      let showData = {
+        nodes,
+        reviewId,
+        reviewIndicatorId
+      }
+      this.$router.push({ path: "/handleDetails", query: {showData: JSON.stringify(showData)} })
+    },
+  },
+
+  watch: {
+    // 路由参数变化(浏览器返回/前进、query 变化)也会再次执行
+    '$route'(to, from) {
+      let reviewId = this.$route.query.reviewId
+      this.employeeId = this.$route.query.employeeId
+      this.employeeId = this.employeeId ? this.employeeId : this.userInfo.id
+      if(reviewId) {
+        this.getDetails(reviewId);
+      }else {
+        this.getTemplateList()
+      }
+    }
+  },
+
+
+  created() {
+    let reviewId = this.$route.query.reviewId
+    this.employeeId = this.$route.query.employeeId
+    this.employeeId = this.employeeId ? this.employeeId : this.userInfo.id
+    if(this.reviewId) {
+      this.getDetails(reviewId);
+    }else {
+      this.getTemplateList()
+    }
+  },
+};
+</script>
+
+<style scoped lang="less">
+.all {
+  width: 100%;
+  height: 100%;
+  position: relative !important;
+  background-color: #f5f7fa;
+  box-sizing: border-box;
+
+  .overall {
+    height: calc(100% - 0.92rem) !important;
+    position: relative;
+    overflow-y: scroll;
+  }
+}
+
+
+
+.title {
+  margin: 0.2rem 0;
+  padding: 0 0.2rem;
+  box-sizing: border-box;
+  font-size: 0.3rem;
+  font-weight: 600;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  .more-btn {
+    font-weight: normal;
+    color: #0597ff;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    i {
+      margin: 0.06rem 0 0 0.02rem;
+    }
+  }
+
+}
+
+
+
+
+.list-box {
+  width: 96%;
+  padding: 0.24rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  box-sizing: border-box;
+  margin: 0.24rem auto;
+  .add-task-title {
+    font-weight: 600;
+    font-size: 0.32rem;
+  }
+
+  .user-info {
+    font-size: 0.28rem;
+    color: #89919F !important;
+    margin: 0 0 0 0.2rem;
+  }
+
+  .cycle-type {
+    padding: 0.08rem;
+    border-radius: 0.1rem;
+    color: #26a2ff;
+    box-sizing: border-box;
+    background-color: #ecf5ff;
+  }
+
+  .examine-info {
+    font-size: 0.28rem;
+    position: relative;
+
+    .tips {
+      position: absolute;
+      top: 0.1rem;
+      right: -0.2rem;
+      .tip-item {
+        padding: 0.1rem;
+        border-top-left-radius: 0.1rem;
+        border-bottom-left-radius: 0.1rem;
+        color: #26a2ff;
+        z-index: 999;
+        box-sizing: border-box;
+        background-color: #ecf5ff;
+        margin-bottom: 0.1rem;
+      }
+    }
+    .info-item {
+      margin-bottom: 0.2rem;
+      color: #89919F !important;
+      .info-item-title {
+        width: 1.4rem;
+        color: #000;
+      }
+      .review-node {
+        padding: 0.01rem 0.1rem;
+        color: #fff;
+        border-radius: 2px;
+        font-size: 0.26rem;
+        background-color: #67c23a;
+        margin-left: 0.14rem;
+      }
+    }
+
+    .line {
+      width: 100%;
+      margin: 0.5rem auto;
+      height: 1px;
+      background-color: #f1f1f1;
+    }
+  }
+
+
+}
+
+.bg-gray {
+  background-color: #f5f5f5;
+  padding: 0.2rem;
+  box-sizing: border-box;
+  margin: 0.1rem;
+  color: #999;
+  border-radius: 5px;
+}
+
+
+</style>

+ 483 - 0
src/performance-07-19/view/navhome/more.vue

@@ -0,0 +1,483 @@
+<template>
+    <div style="width: 100%; height: 100%;" :class="{ bg_fff: skeletonLoad }">
+      <van-nav-bar title="更多考核数据" left-text="返回" left-arrow @click-left="goHomePage" />
+
+      <van-search placeholder="请输入考核表名称" v-model="params.keyword" @input="keyVal()" />
+
+      <!-- 条件筛选 -->
+      <div class="flex-box-ce" style="background-color: white; border-top: 1px solid #f1f1f1; border-bottom: 1px solid #f1f1f1; margin-bottom: 0.2rem;">
+        <!-- 周期筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center" style="border-right: 1px solid #f1f1f1;">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="openPanel()">
+            <div class="cycle-name">{{ dateParameter.name }}</div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 周期筛选 -->
+        <!-- 时间筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center" style="border-right: 1px solid #f1f1f1;">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="calendarOpen()">
+            <div class="cycle-name" v-html="timeStr"></div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 时间筛选 -->
+
+        <!-- 时间筛选 -->
+        <div class="flex-1 flex-box-ce flex-center-center">
+          <div class="cycle-select-box fontColorC flex-box-ce flex-center-center" @click="showStatus = true">
+            <div class="cycle-name">{{ '状态' }}</div>
+            <van-icon name="arrow-down" size="12"/>
+          </div>
+        </div>
+        <!-- 时间筛选 -->
+      </div>
+      <!-- 条件筛选 -->
+
+
+      <!-- 骨架屏 -->
+      <VanSkeleton :skeLoad="skeletonLoad">
+        <scroller class="scroller-box" ref="scroller" :isInitRefresh="false" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢" :list="examineList">
+          <div class="examine-list" v-if="filterExamineList && filterExamineList.length > 0">
+            <div class="examine-item" v-for="(item, index) in filterExamineList" :key="item.reviewId" @click="handleChooseItem(item)">
+              <div v-if="item.status == 1" class="examine-item-status" style="background-color: #FF9600;">
+                已结束
+              </div>
+              <div v-if="item.status == 0" class="examine-item-status" >
+                进行中
+              </div>
+              <div class="flex-1 flex-box-ce flex-d-center">
+                <div class="examine-item-title font-flex-word">
+                  {{ item.title }}
+                </div>
+                <div class="examine-item-info">
+                  {{ item.score || '-' }} / {{ item.levelName || '-' }}
+                </div>
+              </div>
+
+            </div>
+          </div>
+
+          <noData v-else content="无考核记录"></noData>
+        </scroller>
+      </VanSkeleton>
+      <!-- 骨架屏 -->
+
+      <!-- 周期选择弹框 -->
+      <van-action-sheet v-model="pullonThePanel" :closeable="false">
+        <div class="content">
+          <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel = false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+        </div>
+      </van-action-sheet>
+
+      <!-- 日期选择框 -->
+      <van-calendar
+        v-model="showCalendar"
+        type="range"
+        :allow-same-day="true"
+        :min-date="minDate"
+        :max-date="maxDate"
+        :default-date="timeScope"
+        :show-confirm="false"
+        color="#26A2FF"
+        @close="calendarClose"
+        @confirm="calendarConfirm"
+      >
+        <template v-slot:title>
+          <van-row>
+            <van-col span="20">
+              <van-row type="flex" justify="space-between" style="height: 1rem;">
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="success" size="medium" @click="timeScopeThisWeek">本周</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="success" size="medium" @click="timeScopeLastWeek">上周</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="primary" size="medium" @click="timeScopeThisMoth">本月</van-tag>
+                </van-col>
+                <van-col span="6" style="text-align: center; align-self: center;">
+                  <van-tag type="primary" size="medium" @click="timeScopeLastMonth">上月</van-tag>
+                </van-col>
+              </van-row>
+            </van-col>
+          </van-row>
+        </template>
+      </van-calendar>
+
+      <!-- 状态 -->
+      <van-dialog v-model="showStatus" title="" width="300" confirm-button-text="确定" @confirm="handleConfirm" @cancel="handleCancel"  :show-confirm-button="true" closeOnClickOverlay>
+        <van-radio-group v-model="statusId">
+          <div v-for="(item, index) in statusList" :key="index">
+            <van-radio :name="item.value" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+              <span style="margin-left:.3rem">{{ item.text }}</span>
+            </van-radio>
+          </div>
+        </van-radio-group>
+      </van-dialog>
+    </div>
+
+</template>
+
+<script>
+  import { _debounce, _throttle } from '@/utils/auth';
+  import VanSkeleton from '@/performance/components/public/VanSkeleton';
+  import { DropdownMenu, DropdownItem, Calendar, Switch} from 'vant';
+  import moment from "moment/moment";
+
+  export default {
+    components: { VanSkeleton },
+    data() {
+
+      let startDate = new Date();
+      startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * 7);
+      startDate = moment(startDate).format('YYYY-MM-DD');
+      let endDate = moment().format('YYYY-MM-DD');
+
+      let today = new Date();
+      let minDate = new Date();
+      minDate.setTime(today.getTime() - 3600 * 1000 * 24 * 30 * 6);
+      let maxDate = new Date(today.getFullYear(),today.getMonth(),1);
+      maxDate.setMonth(maxDate.getMonth() + 1);
+      maxDate.setDate(0);
+
+
+      return {
+        skeletonLoad: true,
+        keyword: '',
+        examineList: [],
+        filterExamineList: [],
+        pullonThePanel: false,
+        statusList: [
+          {
+            id: 0, text: "全部", value: "-1"
+          },
+          {
+            id: 1, text: "进行中", value: "0"
+          },
+          {
+            id: 2, text: "已结束", value: "1"
+          },
+        ],
+        columns: [
+          {
+            value: "-1",
+            name: "全部",
+            text: "全部"
+          },
+          {
+            value: "0",
+            name: "自定义",
+            text: "自定义"
+          },
+          {
+            value: "1",
+            name: "年度",
+            text: "年度"
+          },
+          {
+            value: "2",
+            name: "半年度",
+            text: "半年度"
+          },
+          {
+            value: "3",
+            name: "季度",
+            text: "季度"
+          },
+          {
+            value: "4",
+            name: "月度",
+            text: "月度"
+          }
+        ],
+        selectPftiTheEcho: [0, 0], // 选项回显
+        dateParameter: {
+          cycleType: '-1',
+          name: '全部'
+        },
+        showCalendar: false,
+        minDate: minDate,
+        maxDate: maxDate,
+        timeScope: [new Date(startDate),new Date(endDate)],
+
+        userInfo: this.$userInfo(),
+        timeStr: "选择时间",
+        from: "me",
+
+        showStatus: false,
+        statusId: 0,
+
+        params: {
+          keyword: '',
+          page: 1,
+          pageSize: 15,
+          cateId: '',
+          startDate: '',
+          endDate: '',
+          employeeId: '',
+        },
+      }
+    },
+
+    beforeDestroy() {
+      this.params = {
+        keyword: '',
+        page: 1,
+        pageSize: 15,
+        cateId: '',
+        startDate: '',
+        endDate: '',
+        employeeId: '',
+      };
+      this.from = 'me'
+      this.timeStr = "选择时间";
+      this.timeScope = [new Date(startDate),new Date(endDate)];
+    },
+
+    created() {
+      this.params.employeeId = this.$route.query.employeeId
+      this.params.employeeId = this.params.employeeId ? this.params.employeeId : this.$userInfo().id
+      this.from = this.$route.query.from || 'me'
+      this.getExamineList();
+    },
+
+    methods: {
+
+      goHomePage() {
+        if(this.from == 'me') this.$router.push("/home")
+        else this.$router.push("/orgExamine")
+      },
+
+      // 周期选择事件
+      handleCellClick(e) {
+        console.log(e.currentTarget.id)
+      },
+
+
+      // 搜索
+      keyVal: _debounce(function() {
+        this.pullDown();
+        // console.log(123)
+      }),
+
+      handleChooseItem(item) {
+        if(this.from == 'me') this.goMePage(item)
+        else this.goOrgExaminePage(item)
+      },
+
+      goOrgExaminePage(item) {
+        this.$router.push({ path: "/orgExamine", query: { reviewId: item.reviewId } })
+      },
+
+      goMePage(item) {
+        this.$router.push({ path: "/me", query: { reviewId: item.reviewId, employeeId:  item.employeeId } })
+      },
+
+      // 获取考核表列表
+      getExamineList(is, callback) {
+        let that = this;
+        let url = `/performance/statistics/reviews/${that.$userInfo().site_id}`
+        let requestdata;
+        if (that.dateParameter.cycleType == '-1') requestdata = { ...that.params }
+        else requestdata = { ...that.params, cycleType: that.dateParameter.cycleType }
+
+        let hasMore = false
+        is ? '' : that.params.page = 1;
+        that.$axiosUser('get', url, requestdata).then(res => {
+          this.skeletonLoad = false;
+          let { data: { data: { list, total }, code } } = res;
+          if (code == 1) {
+            if (requestdata.page === 1) {
+              that.examineList = list
+            } else {
+              that.examineList = that.examineList.concat(list)
+            }
+
+            hasMore = list.length !== 10
+            callback && callback(hasMore)
+          } else {
+            that.examineList = [];
+          }
+          that.filterExamineList = that.examineList;
+        });
+      },
+
+      // 打开周期选择弹框
+      openPanel(){
+        this.pullonThePanel = true;
+        this.$nextTick(() => {
+          this.theEchoVanPicker()
+        })
+      },
+
+      // 回显
+      theEchoVanPicker() {
+        this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+      },
+
+      //  确认周期选择-考核包搜索
+      onConfirm (data, value) {
+        // let columns = this.columns[list[0]];
+        // let options = this.cycleTypeArr[list[1]]
+        // this.selectPftiTheEcho = list
+        this.dateParameter = {
+          cycleType: data.value,
+          name: data.name
+        };
+        // console.log(this.dateParameter);
+        this.pullDown();
+        this.pullonThePanel = false
+      },
+
+      // 上拉刷新
+      refresh (done) {
+        this.getExamineList(false, done)
+      },
+
+      // 下拉加载
+      infinite (done) {
+        this.params.page ++;
+        this.getExamineList(true, done)
+      },
+
+      pullDown(){
+        setTimeout(() => {
+          this.$refs.scroller.triggerPullToRefresh();
+        }, 50);
+      },
+
+      // 日期选择
+      changeDateGetList() {
+        if(this.timeScope && this.timeScope.length > 0) {
+          this.params.startDate = moment(this.timeScope[0]).format('YYYY-MM-DD')
+          this.params.endDate = moment(this.timeScope[1]).format('YYYY-MM-DD')
+          this.timeStr = this.params.startDate + "<br/>" + this.params.endDate
+          this.getExamineList();
+        }
+
+      },
+
+      // 本周
+      timeScopeThisWeek(){
+        this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
+        this.showCalendar= false
+        this.changeDateGetList()
+      },
+      // 上周
+      timeScopeLastWeek(){
+        this.timeScope = [new Date(moment().subtract(1,'week').startOf('week').format('YYYY-MM-DD')),new Date(moment().subtract(1,'week').endOf('week').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+      // 本月
+      timeScopeThisMoth(){
+        this.timeScope = [new Date(moment().startOf('month').format('YYYY-MM-DD')),new Date(moment().endOf('month').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+      // 上周
+      timeScopeLastMonth(){
+        this.timeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
+        this.showCalendar = false
+        this.changeDateGetList()
+      },
+
+
+      calendarOpen(){
+        this.showCalendar = true;
+      },
+
+      calendarClose(){
+        this.showCalendar = false;
+      },
+
+      calendarConfirm(event){
+        const [start,end] = event;
+        this.timeScope = [start, end];
+        this.showCalendar = false;
+        this.changeDateGetList();
+      },
+
+
+      handleConfirm() {
+        if(this.statusId !== '-1') this.filterExamineList = this.examineList.filter(item => item.status == this.statusId)
+        else this.filterExamineList = this.examineList
+        this.showStatus = false
+      },
+
+      handleCancel() {
+        this.showStatus = false
+      }
+
+    }
+  }
+
+
+</script>
+
+<style lang="less" scoped>
+
+  /deep/ .van-calendar__header-subtitle {
+    width: 100%;
+    font-size: 0.28rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .cycle-select-box {
+    width: 100%;
+    padding: 0.2rem 0.1rem;
+    box-sizing: border-box;
+    background-color: #fff;
+    box-sizing: border-box;
+    .icon {
+      margin-right: 6px;
+      width: 0.32rem;
+      height: 0.32rem;
+    }
+    .cycle-name {
+      margin: 0 6px;
+      font-size: 0.3rem;
+    }
+  }
+
+
+  .scroller-box {
+    height: calc(100% - 3rem) !important;
+    position: relative !important;
+    background-color: #f5f7fa;
+    padding-bottom: 0.5rem;
+    box-sizing: border-box;
+
+    .examine-list {
+      width: 100%;
+      .examine-item {
+        width: 100%;
+        height: 1rem;
+        padding: 0 0.2rem;
+        background-color: #fff;
+        box-sizing: border-box;
+        display: flex;
+        align-items: center;
+        border-bottom: 1px solid #f1f1f1;
+        &-status{
+          padding:0.01rem 0.1rem;
+          color: #fff;
+          border-radius: 2px;
+          font-size: 0.26rem;
+          background-color: #67c23a;
+          margin-right: 0.14rem;
+        }
+
+        &-info {
+          font-size: 0.26rem;
+        }
+      }
+    }
+
+
+  }
+</style>
+

+ 610 - 0
src/performance-07-19/view/navhome/organizationExamine.vue

@@ -0,0 +1,610 @@
+<template>
+  <div class="all" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="组织考核" left-text="返回" @click-left="goHomePage" :right-text="right_text" @click-right="multi_option" left-arrow></van-nav-bar>
+    <van-notice-bar
+      left-icon="volume-o"
+      text="默认显示每个人的最新考核数据,可选择人员添加考核数据,也可以移除某个人员的考核数据,或点击人员姓名替换某条考核数据"
+    />
+
+    <div class="search-box flex-box-ce">
+      <div class="flex-1 flex-box-ce flex-center-center fontColorC" @click="openPanel">
+        周期选择 <van-icon name="arrow-down" size="12" style="margin-left: 0.2rem;" />
+      </div>
+      <div class="flex-1 flex-box-ce flex-center-center fontColorC" @click="openPanel2">
+        部门选择
+        <van-icon name="arrow-down" size="12" style="margin-left: 0.2rem;" />
+      </div>
+    </div>
+    <div class="overall">
+      <VanSkeleton :skeLoad="skeletonLoad">
+        <scroller>
+          <div style="padding-bottom: 1rem;">
+
+            <div class="list-box" v-for="(item, index) in employeeList" :key="item.employeeId">
+              <van-checkbox v-if="multi" v-model="item.selected" shape="square" style="margin-bottom: 0.1rem;" />
+              <div class="flex-box-ce" style="margin-bottom: 0.2rem;"  @click="chooseExamineInfo(index, item.employeeId)">
+                <div class="flex-box-ce">
+                  <div>
+                    <userImage class="about-me__avatar" :id="item.userInfo.id" :img_url="item.userInfo.img_url"  :user_name="item.userInfo.name"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+                  </div>
+                  <div class="user-info">
+                    <div style="margin-bottom: 0.05rem; color: #000;">{{ item.employeeName }}</div>
+                    <template v-if="item.deptList && item.deptList.length > 0">
+                      <span v-for="(dept, index) in item.deptList" :key="index">{{ dept }}&nbsp;</span>
+                    </template>
+                  </div>
+                </div>
+                <div v-if="item.status == 1" class="examine-item-status" style="background-color: #FF9600;">
+                  已结束
+                </div>
+                <div v-if="item.status == 0" class="examine-item-status" >
+                  进行中
+                </div>
+
+              </div>
+
+              <div class="examine-info">
+                <div class="info-item flex-box-ce">
+                  考核周期:&nbsp;&nbsp;&nbsp; <div class="cycle-type">{{ item.cycleType | formatCycleType }}</div>
+                </div>
+                <div class="info-item">
+                  <van-icon name="calendar" />考核时间:&nbsp;&nbsp;&nbsp;{{ item.startTime | formatDate }} 至 {{ item.endTime | formatDate }}
+                </div>
+                <div class="info-item">
+                  考核等级:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ item.levelName || '-' }}</span>
+                </div>
+                <div class="info-item">
+                  考核评分:&nbsp;&nbsp;&nbsp; <span style="color: #ff9600;">{{ item.score == undefined  || item.score == null || item.score == '' ? '-' : item.score }}</span>
+                </div>
+                <div class="info-item">
+                  较上次:&nbsp;&nbsp;&nbsp;
+                  <span v-if="item.levelChange && item.levelChange > 0" style="color: #67c23a !important;">
+                    {{ item.levelChange }}
+                  </span>
+                  <span v-else-if="item.levelChange && item.levelChange < 0"  style="color: #f56c6c !important;">
+                    {{ item.levelChange }}
+                  </span>
+                  <span v-else class="gray" style="color: #999;">
+                    --
+                  </span>
+                </div>
+              </div>
+
+            </div>
+
+
+          </div>
+        </scroller>
+      </VanSkeleton>
+    </div>
+
+    <footer class="footer">
+      <div v-if="multi" class="flex-box-ce" style="justify-content: space-around;">
+        <div class="flex-box-ce" style="margin: 0 0.2rem; font-size: 0.28rem;" >
+          <van-checkbox v-model="selectAll" shape="square" style="margin-right: 0.2rem;" />
+          全选
+        </div>
+        <div class="btn flex-1 danger" @click="handleDelete()">删除人员</div>
+      </div>
+
+      <div v-else class="flex-box-ce" style="justify-content: space-around;">
+        <div class="btn" @click="openUserSelector()">添加人员</div>
+        <!-- <div class="btn">删除人员</div> -->
+        <div class="btn plain" @click="resetData()">重置数据</div>
+      </div>
+    </footer>
+
+
+    <!-- 周期选择弹框 -->
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel = false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+      </div>
+    </van-action-sheet>
+
+    <!-- 部门选择 -->
+    <!-- <EmployeeSelector
+      :max="1"
+      :close_clear_data="false"
+      :can_select_employee="false"
+      :dept_multi="false"
+      @confirm="confirmDept"
+      :visible.sync="show_dept_selector"
+      :selected.sync="selected_data"
+      :isShowDepts="true"
+    ></EmployeeSelector> -->
+
+
+    <!-- 人员选择 -->
+    <EmployeeSelector title="人员"
+      :visible.sync="show_user_selector"
+      @confirm="confirmCreator"
+      :selected.sync="selected_user_all"
+      :can_select_dept="false"
+      :dept_multi="false"
+      :append_body="true"
+      :isShowDepts="false"
+      :max='120'
+    />
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { NoticeBar } from 'vant';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import moment from 'moment';
+
+Vue.use(NoticeBar)
+  export default {
+    components: {
+      VanSkeleton,
+      EmployeeSelector
+    },
+
+    data() {
+      return {
+        skeletonLoad: true,
+        employeeList: [],
+        // 周期类型 0-自定义 1-年度 2-半年度 3-季度 4-月度
+        cycleType: '-1',
+        right_text: "批量",
+        columns: [
+          {
+            value: "-1",
+            name: "全部",
+            text: "全部"
+          },
+          {
+            value: "0",
+            name: "自定义",
+            text: "自定义"
+          },
+          {
+            value: "1",
+            name: "年度",
+            text: "年度"
+          },
+          {
+            value: "2",
+            name: "半年度",
+            text: "半年度"
+          },
+          {
+            value: "3",
+            name: "季度",
+            text: "季度"
+          },
+          {
+            value: "4",
+            name: "月度",
+            text: "月度"
+          }
+        ],
+
+        currentValue: '-1', // 选项回显
+
+        pullonThePanel: false,
+        dept_id: 0,
+        show_dept_selector: false,
+        show_user_selector: false,
+
+        selected_data: { dept: [], employee: [] },
+
+        selected_user_all: { dept: [], employee: [] }, //选择人员
+        multi: false,
+        reviewId: '', // 选择的考核信息ID
+        params: {
+          deptIds: '',
+          employeeIds: '',
+          cateId: '',
+          pages: 1,
+          pageSize: 10
+        },
+      }
+    },
+
+    computed: {
+      selectEmployeeIds() {
+        let selectEmployeeIds = this.employeeList.map(item => item.employeeId)
+        selectEmployeeIds = Array.from(
+            new Set(selectEmployeeIds.map(item => JSON.stringify(item)))
+        ).map(item => JSON.parse(item));
+        return selectEmployeeIds
+      },
+
+      selectEmployees() {
+
+        let selectEmployees = this.employeeList.map(item => item.userInfo)
+        selectEmployees = Array.from(
+            new Set(selectEmployees.map(item => JSON.stringify(item)))
+        ).map(item => JSON.parse(item));
+        return selectEmployees
+      },
+
+      // 全选 / 全不选
+      selectAll: {
+        get() {
+          // 所有都选中 → 全选按钮 true
+          return this.employeeList.every(item => item.selected);
+        },
+        set(val) {
+          // 点击全选按钮时,一键同步到所有
+          this.employeeList.forEach(item => (item.selected = val));
+        }
+      }
+    },
+
+    filters: {
+      filterNodeStatus(v) {
+        if (v === 'start') return '开始'
+        if (v === 'target_confirm') return '确认目标'
+        if (v === 'result_input') return '录入结果值'
+        if (v === 'score_self') return '自评'
+        if (v === 'score_each_other') return '互评'
+        if (v === 'score') return '评分'
+        if (v === 'review') return '审批'
+        if (v === 'cc') return '抄送'
+        if (v === 'end') return '结束'
+      },
+
+      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 '--'
+      },
+    },
+
+     watch: {
+      // 路由参数变化(浏览器返回/前进、query 变化)也会再次执行
+      '$route'(to, from) {
+        this.getExamineInfo()
+      }
+    },
+
+    created() {
+      // this.show_dept_selector = true
+      this.getList()
+
+    },
+    methods: {
+
+      goHomePage() {
+        this.$router.push("/home")
+      },
+
+      // 批量操作
+      multi_option () {
+        if (this.multi) {
+          this.multi = false
+          this.right_text = '批量'
+        } else {
+          this.multi = true
+          this.right_text = '取消'
+        }
+      },
+
+      // 获取数据
+      getList() {
+        this.skeletonLoad = true;
+        let url = `/performance/statistics/review/last/${this.$userInfo().site_id}`
+        let requestdata
+        if (this.cycleType == '-1') requestdata = { ...this.params }
+        else {
+            requestdata = { ...this.params, cycleType: this.cycleType }
+        }
+        delete requestdata['employeeIds'] // 删除部门字段
+        this.$axiosUser('get', url, requestdata).then(res => {
+          this.skeletonLoad = false;
+          let { data: { data: { list, total }, code } } = res
+          if (code == 1) {
+              if(list && list.length > 0) {
+                list.forEach(item => {
+                  item.selected = false
+                  item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+                })
+              }
+              this.employeeList = list;
+              // this.total = total
+            }
+        });
+      },
+
+      /* 添加的人员请求考核数据 */
+      getListByPerson() {
+        let url = `/performance/statistics/review/last/${this.$userInfo().site_id}`
+        // this.selected_dept_ids = []
+        // this.params.deptIds = ''
+        // this.params.employeeIds = this.params.employeeIds && this.params.employeeIds.length > 0 ? this.params.employeeIds.toString() : ''
+
+        this.$axiosUser('get', url, this.params).then(res => {
+            // this.loading = false;
+            let { data: { data: { list, total }, code } } = res
+            if (code == 1) {
+                let contactList = [...this.employeeList, ...list];
+                // 去重
+                this.employeeList = Array.from(
+                    new Set(contactList.map(item => JSON.stringify(item)))
+                ).map(item => JSON.parse(item));
+                // this.total = this.tableData.length
+                this.employeeList.forEach(item => {
+                  item.selected = false
+                  item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+                })
+                this.cycleType = '-1';
+            }
+        });
+      },
+
+      // 获取考核信息
+      getExamineInfo() {
+        let reviewId = this.$route.query.reviewId
+        if(!reviewId) return
+        console.log("reviewId")
+        console.log(reviewId)
+        let url = `/performance/statistics/review/info/${this.$userInfo().site_id}/${reviewId}`
+        this.$axiosUser('get', url).then(res => {
+            let { data, code } = res.data
+            if (code == 1) {
+                if (data) {
+                    delete data['deptList'] // 删除部门字段
+                    let replaceData = {
+                        ...this.employeeList[this.currentIndex],
+                        ...data
+                    }
+                    this.employeeList.splice(this.currentIndex, 1, replaceData);
+                }
+            }
+        });
+      },
+
+
+      // 打开周期选择弹框
+      openPanel(){
+        this.pullonThePanel = true;
+        // 等 DOM 渲染完成后设置索引
+        this.$nextTick(() => {
+          const index = this.columns.findIndex(item => item.value == this.currentValue);
+          // 单列只传一个索引
+          this.$refs.van_picker.setIndexes([index]);
+        });
+
+      },
+
+      openPanel2() {
+        this.show_dept_selector = true
+        console.log(this.show_dept_selector)
+      },
+
+      //  确认周期选择
+      onConfirm (data, value) {
+        console.log(data)
+        console.log(value)
+        this.cycleType = data.value
+        this.currentValue = data.value
+        this.getList()
+        this.pullonThePanel = false
+      },
+
+      confirmDept(val){
+        this.selected_data = val;
+        if(val.dept.length > 0){
+          this.dept_id = val.dept[0].dept_id;
+        }else{
+          this.dept_id = 0;
+        }
+        // this.pullDown();
+      },
+
+      openUserSelector() {
+        this.selected_user_all.employee = this.selectEmployees
+        this.show_user_selector = true
+      },
+
+      resetData() {
+        let url = `/performance/statistics/review/last/${this.$userInfo().site_id}`
+        let requestdata
+        this.cycleType = '-1';
+        this.params = {
+            deptIds: '',
+            employeeIds: '',
+            cateId: '',
+            pages: 1,
+            pageSize: 10
+        }
+        // this.selected_dept_ids = []
+        requestdata = { ...this.params }
+        if ('deptIds' in requestdata) delete requestdata['deptIds'] // 删除部门字段
+        this.$axiosUser('get', url, requestdata).then(res => {
+            // this.loading = false;
+            let { data: { data: { list, total }, code } } = res
+            if (code == 1) {
+              if(list && list.length > 0) {
+                list.forEach(item => {
+                  item.selected = false
+                  item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+                })
+              }
+              this.employeeList = list;
+            }
+        });
+      },
+
+      confirmCreator(arr){
+        let target_ids = arr.employee.map(item=>{
+          return item.id
+        }).filter(item => !this.selectEmployeeIds.includes(item)).toString();
+        // target_ids = target_ids.filter(target => )
+        console.log(target_ids)
+        this.params.employeeIds = target_ids;
+        this.getListByPerson();
+        // let data = {
+        //   employeeId: this.$userInfo().id,
+        //   targetIds: target_ids
+        // }
+
+      },
+
+      handleDelete() {
+        this.employeeList = this.employeeList.filter(item => !item.selected)
+      },
+
+      chooseExamineInfo(index, employeeId) {
+        this.currentIndex = index
+        this.$router.push({ path: "/more", query: { employeeId, from: "orgExamine" } })
+      }
+    }
+  }
+</script>
+
+<style scoped lang="less">
+  .all {
+    width: 100%;
+    height: 100%;
+    position: relative !important;
+    background-color: #f5f7fa;
+    box-sizing: border-box;
+    .search-box {
+      width: 100%;
+      height: 0.8rem;
+      background: #fff;
+      font-size: 0.28rem;
+    }
+    .overall {
+      height: calc(100% - 2.52rem) !important;
+      position: relative;
+      overflow-y: scroll;
+
+      .list-box {
+        width: 96%;
+        padding: 0.24rem;
+        font-size: 0.32rem;
+        background-color: #fff;
+        border-radius: 5px;
+        box-sizing: border-box;
+        margin: 0.24rem auto;
+        position: relative;
+        .examine-item-status {
+          position: absolute;
+          top: 0.2rem;
+          right: 0.1rem;
+          padding: 0.01rem 0.1rem;
+          color: #fff;
+          border-radius: 2px;
+          font-size: 0.26rem;
+          background-color: #67c23a;
+          margin-right: 0.14rem;
+        }
+        .add-task-title {
+          font-weight: 600;
+          font-size: 0.32rem;
+        }
+
+        .user-info {
+          font-size: 0.28rem;
+          color: #89919F !important;
+          margin: 0 0 0 0.2rem;
+        }
+
+        .cycle-type {
+          padding: 0.08rem;
+          border-radius: 0.1rem;
+          color: #26a2ff;
+          box-sizing: border-box;
+          background-color: #ecf5ff;
+        }
+
+        .examine-info {
+          font-size: 0.28rem;
+          position: relative;
+
+          .tips {
+            position: absolute;
+            top: 0.1rem;
+            right: -0.2rem;
+            .tip-item {
+              padding: 0.1rem;
+              border-top-left-radius: 0.1rem;
+              border-bottom-left-radius: 0.1rem;
+              color: #26a2ff;
+              z-index: 999;
+              box-sizing: border-box;
+              background-color: #ecf5ff;
+              margin-bottom: 0.1rem;
+            }
+          }
+          .info-item {
+            margin-bottom: 0.2rem;
+            color: #89919F !important;
+            .info-item-title {
+              width: 1.4rem;
+              color: #000;
+            }
+            .review-node {
+              padding: 0.01rem 0.1rem;
+              color: #fff;
+              border-radius: 2px;
+              font-size: 0.26rem;
+              background-color: #67c23a;
+              margin-left: 0.14rem;
+            }
+          }
+
+          .line {
+            width: 100%;
+            margin: 0.5rem auto;
+            height: 1px;
+            background-color: #f1f1f1;
+          }
+        }
+
+
+      }
+    }
+  }
+
+
+  .footer {
+    width: 100%;
+    padding: 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+    box-sizing: border-box;
+    .btn {
+      width: 48%;
+      padding: 0.2rem;
+      // border: 0.02rem solid #26A2FF;
+      color: #fff;
+      text-align: center;
+      background: #26A2FF;
+      font-size: 0.28rem;
+      box-sizing: border-box;
+    }
+    .danger {
+      background-color: transparent;
+      color: rgb(245, 108, 108);
+      border: 1px solid rgb(245, 108, 108);
+    }
+    .plain {
+      background-color: transparent;
+      color: #26A2FF;
+      border: 1px solid #26A2FF;
+    }
+  }
+</style>

+ 429 - 0
src/performance-07-19/view/navhome/perAttentionList.vue

@@ -0,0 +1,429 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar left-text="返回" @click-left="$route_back" :title="'关注的人'"></van-nav-bar>
+    <div class="work_body_com">
+      <header class="flex-box-ce" style="padding: 0.2rem 0.32rem;background-color: #fff;">
+        <div class="flex-1 fontColorB">人员</div>
+        <div class="blue" @click="selectUserAll = true"><van-icon name="plus" /> 添加</div>
+      </header>
+      <div class="scroller">
+        <scroller ref="scroller_com">
+            <div class="employee_item"  v-for="(item,key) in employee_list " :key="key">
+              <van-cell class="employee_cell" :title="item.name">
+                <template slot="icon">
+                  <img :src="item.imgUrl" width="30" height="30" class="imgUrl" v-if="item.imgUrl">
+                  <div class="imgUrl" v-else style="background: #238DFA; color: #fff;">{{item.name.substring(item.name.length - 2)}}</div>
+                </template>
+                <template slot="right-icon">
+                    <span class="blue flex-box flex-h-ce" style="font-size: 0.28rem;" @click="qxAttention(item)">{{ '取消关注' }}</span>
+                </template>
+              </van-cell>
+            </div>
+            <div v-if="employee_list.length==0" style="text-align: center;margin-top: 2rem;" class="fontColorC">
+                <span>暂无数据</span>
+            </div>
+            <div style="height: 1rem;"></div>
+        </scroller>
+      </div>
+    </div>
+    <!-- @人员 -->
+    <EmployeeSelector title="人员"
+      :visible.sync="selectUserAll"
+      @confirm="confirmCreator"
+      :selected.sync="selected_user_all"
+      :can_select_dept="false"
+      :dept_multi="false"
+      :append_body="true"
+      :isShowDepts="false"
+      :max='20'
+    />
+  </div>
+
+</template>
+
+<script type="text/javascript">
+import EmployeeSelector from '@/components/EmployeeSelector'
+export default {
+  name: 'attentionList',
+  components:{EmployeeSelector},
+  data () {
+    return {
+      employee_list: [],
+      selectUserAll:false,
+      selected_user_all: { dept: [], employee: [] },//参与人员
+      index:1,
+    }
+  },
+  mounted() {
+    this.index = this.$route.query.index;
+    this.getUserList()
+  },
+  methods: {
+    getUserList(){
+      this.$axiosUser('get', `/performance/follow/employees/${this.$userInfo().site_id}`).then(res => {
+        this.employee_list = res.data.data.list;
+        this.selected_user_all.employee = this.employee_list;
+      });
+    },
+
+    qxAttention (item) {
+      let str= '取消关注'
+      this.$dialog.confirm({message: `确定${str}吗?`, title: '提示'}).then(() => {
+       let data={
+         employeeId: this.$userInfo().id,
+         targetIds: item.id
+       }
+       this.$axiosUser('post', `/performance/follow/remove/employee/${this.$userInfo().site_id}`, data, 'contentTypeJson').then(res => {
+            this.$toast("已取消")
+            this.getUserList();
+        });
+      }).catch(() => {})
+    },
+
+    confirmCreator(arr){
+      let target_ids = arr.employee.map(item=>{
+        return item.id
+      }).toString();
+      let data = {
+        employeeId: this.$userInfo().id,
+        targetIds: target_ids
+      }
+      this.$axiosUser('post', `/performance/follow/add/employee/${this.$userInfo().site_id}`, data, 'contentTypeJson').then(res => {
+          this.$toast("已设置")
+          this.getUserList();
+      });
+    },
+
+  }
+}
+</script>
+
+<style scoped>
+  .scroller {
+    position: relative;
+    height: calc(100% - 0.84rem);
+  }
+  .department_right_nav /deep/ .van-dropdown-menu__bar {
+    height: 0.92rem !important;
+    background-color: #26A2FF !important;
+  }
+  .department_right_nav /deep/ .van-dropdown-menu__title--active {
+      color: #fff !important;
+  }
+  .van-cell__label{
+    max-width: 4rem;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    margin-top: 0;
+  }
+
+  .manager{
+    background-color: #fff;
+    padding: 0.24rem 0.32rem;
+    padding-top:0.14rem;
+  }
+  .pageIndexBtn{
+    width:100%;
+    text-align: left;
+    padding: 0.1rem 0.4rem 0.05rem;
+    color: #909399;
+    background:rgb(245, 245, 245);
+  }
+
+  .cur_company_name {
+    line-height: 0.8rem;
+    text-indent: 0.5em;
+    cursor: pointer;
+  }
+
+  .menu_title {
+    text-indent: 0.5em;
+    margin-bottom: 0.16rem;
+  }
+
+  .work_body_com {
+    height: calc(100vh - 0.92rem);
+    position: relative;
+    z-index:0;
+  }
+  .work_body_com .search_list{
+    /* background:#FFF;
+    height: 100vh; */
+  }
+
+  .van-radio-group {
+    padding: 0.24rem 0.32rem;
+  }
+
+  .van-radio {
+    height: 0.8rem;
+  }
+
+  .employee_cell_head_img {
+    width: 0.9rem;
+    height: 0.9rem;
+    -webkit-border-radius: 0.1rem;
+    -moz-border-radius: 0.1rem;
+    border-radius: 0.9rem;
+    margin-right: 0.24rem;
+  }
+  .invite_employee_head_img{
+    width: 0.8rem;
+    height: 0.8rem;
+    -webkit-border-radius: 0.1rem;
+    -moz-border-radius: 0.1rem;
+    border-radius: 0.1rem;
+    margin-right: 0.24rem;
+  }
+
+  .employee_cell .message_department{
+    width:0.9rem;
+    height:0.9rem;
+    margin-right: 0.24rem;
+    color:#238dfa;
+  }
+  .employee_cell .message_newinvit{
+    width:0.9rem;
+    height:0.9rem;
+    margin-right: 0.24rem;
+    color:#FFCC00;
+  }
+  .employee_cell .message_newmember{
+    width:0.9rem;
+    height:0.9rem;
+    margin-right: 0.24rem;
+    color:#FF9600;
+  }
+  .employee_cell .van-cell__title{
+    /* line-height: 0.9rem; */
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-orient: vertical;
+    -webkit-flex-flow: column;
+    flex-flow: column !important;
+    justify-content: center;
+    -webkit-justify-content: center;
+    -webkit-box-pack: center;
+    color: #323233;
+  }
+
+  .employee_cell .van-cell__title span{
+    font-size: 0.34rem;
+  }
+  .employee_cell .van-cell__right-icon{
+    line-height: 0.9rem;
+    color: #E4E7ED;
+  }
+  .company_image{
+    background: #fff;
+    padding-bottom: 0.1rem ;
+    margin-bottom: 0.1rem
+  }
+  .company_info,.company_info2{
+    padding: 0.32rem;
+    margin-top:-0.2rem;
+  }
+  .company_info .van-cell__right-icon{
+    line-height: 0.8rem;
+  }
+  .company_info .van-cell__title{
+    padding: 0.05rem 0;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  .company_info2 .van-cell__title{
+    padding: 0.05rem 0;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+  }
+  .company_info .van-cell__title span{
+    font-family: mirsoft Yahei;
+    font-size: 0.38rem;
+    font-weight: 600;
+    letter-spacing: 0.003rem;
+    border-radius: 0.08rem;
+  }
+  .company_info2 .van-cell__title span{
+    font-family: mirsoft Yahei;
+    font-size: 0.38rem;
+    font-weight: 600;
+    letter-spacing: 0.003rem;
+    border-radius: 0.08rem;
+  }
+
+  .company_info .van-cell__title .van-cell__label span{
+    font-size: x-small;
+    color: #fff;
+    margin-right: 0.1rem;
+  }
+  .company_info2 .van-cell__title .van-cell__label span{
+    font-size: x-small;
+    color: #fff;
+    margin-right: 0.1rem;
+  }
+  .company_info i.van-icon{
+    line-height: 1.28rem
+  }
+  .van-hairline--top-bottom:after, .van-hairline-unset--top-bottom:after{
+    border:none;
+  }
+  .company_dept_img{
+    width: 1.08rem;
+    height: 1.08rem;
+    -webkit-border-radius: 0.1rem;
+    -moz-border-radius: 0.1rem;
+    border-radius: 0.125rem;
+    margin-right: 0.26rem;
+  }
+  .qrcode_popup{
+    width: 80vw
+  }
+
+
+  .employee_item:before{
+    position: absolute;
+    left: 0rem;
+    right: 0rem;
+    top:0rem;
+    box-sizing: border-box;
+    content: ' ';
+    pointer-events: none;
+    border-bottom: 0.02rem solid #ebedf0;
+    -webkit-transform: scaleY(.5);
+    transform: scaleY(.5);
+    z-index: 1;
+  }
+  .letter-first:before{
+    border:none !important;
+  }
+  .department_box /deep/ .van-cell__left-icon{
+    color:#323233 !important;
+  }
+  .pageIndexBtnText{font-size:0.24rem;}
+.dept_path a {
+  color: #238dfa;
+  font-size: 0.28rem;
+}
+.dept_path a:nth-last-child(1) {
+  color: #999;
+}
+.dept_path::after {
+  /* content: '';
+  color: #fff!important; */
+}
+.dept_path a * {
+  vertical-align: middle;
+}
+.dept_path {
+  position: relative;
+  font-size: 0.32rem;
+  line-height: 0.4rem;
+  padding: 0.2rem 0.32rem 0.1rem 0.32rem;
+}
+.text_center {
+  font-size: 14px;
+  margin:0;
+  color: #969799;
+}
+.employee_count{
+  font-size: 0.26rem;
+}
+.tag.num9 {
+  padding: 0;
+  width: 0.4rem;
+  height: 0.4rem;
+  border-radius: 50%;
+  display: inline-block;
+  text-align: center;
+}
+.tag.num10 {
+  width: auto;
+  line-height: 1;
+}
+.employee_cell .van-tag{
+  display: inline-table;
+  margin-top: 0.26rem;
+}
+.employee_cell .van-tag+.van-tag{
+  margin-left: 0.2rem;
+}
+ .guild_notice{
+  top:1.6rem;
+  left: 4.3rem;
+  width: 6rem;
+  background: transparent;
+  border-radius: 0.12rem;
+  overflow-y: inherit;
+}
+.guild_notice .list{
+  position: relative;
+  padding: 0.2rem;
+  background: #238dfa;
+  border-radius: 0.12rem;
+}
+.title{
+  font-size:0.32rem;
+  line-height: 0.48rem;
+  color:#ffffff;
+}
+.title:after{
+  position: absolute;
+  top: 0.825rem;
+  content: ' ';
+  width: 90%;
+  border-bottom: 0.02rem #3798fb solid;
+}
+.num{
+  display: block;
+  font-size:0.32rem;
+  line-height: 0.48rem;
+  color:#ffffff;
+}
+.list .des{
+  display:block;
+  margin-top:0.4rem;
+  font-size:0.36rem;
+  font-weight:bold;
+  color:#fff;
+}
+.list .next{
+  margin-top: 0.3rem;
+  color:#238dfa;
+  background:#fff;
+  border-radius:0.12rem;
+}
+.guild_notice .list:after{
+  border:none;
+}
+.guild_down_icon{
+  position: relative;
+  top: 0.1vh;
+  left: 72vw;
+  content: ' ';
+  width: 0;
+  height: 0;
+  border-left: 0.2rem solid transparent;
+  border-right: 0.2rem solid transparent;
+  border-top: 0.2rem solid #238dfa;
+  transform: rotate(180deg);
+}
+.guild_dept_border{
+  position: relative;
+  text-align: center;
+  top: 0vh;
+  left: 69vw;
+  width: 0.7rem;
+  height: 0.7rem;
+  margin-bottom: 2vh;
+  font-size: 0.4rem;
+  font-weight: bold;
+  line-height: 0.7rem;
+  color: #fff;
+  border: 0.04rem #fff dashed;
+  border-radius: 0.12rem;
+}
+</style>

+ 1094 - 0
src/performance-07-19/view/navhome/resultAnalysis.vue

@@ -0,0 +1,1094 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="结果分析" left-text="返回" left-arrow @click-left="$route_back" />
+    <VanSkeleton :skeLoad="skeletonLoad">
+      <template>
+        <header>
+          <!--
+            <div class="selector" @click="statementTIme">
+              <span>{{ selectPftiText }}</span>
+              <van-icon name="arrow-down" />
+            </div>
+          -->
+          <div style="border-bottom: 1px solid #f1f1f1;" class="selector flex-box-ce flex-center-center" @click="openPanel()">
+            <icon name="YMPicker_item_icon" style="margin-right: 6px;width: 0.3rem;height: 0.3rem;" class="fontColorC"></icon>
+            <div>{{ dateParameter.year }}年</div>
+            <div style="margin: 0 6px;">{{ dateParameter.name }}</div>
+            <van-icon name="arrow-down" />
+          </div>
+        </header>
+
+        <scroller ref="me_scroller" class="all">
+          <div style="padding-bottom: 1.5rem;">
+
+            <div class="statementFoot">
+              <van-tabs v-model="active" @change="statementTabs">
+                <van-tab v-for="(item, index) in statementVanTabs" :key="index" :title="item.name"></van-tab>
+              </van-tabs>
+              <!-- 等级分布 -->
+              <div class="statmentAnalysePie" v-show="active == 0">
+                <div style="width: 7.5rem; height: 5rem;" id="statmentAnalysePie" ref="statmentAnalysePie"></div>
+                <div class="PiePropNum">
+                  <div>总人数</div>
+                  <div>{{ userTotal }}人</div>
+                </div>
+              </div>
+
+
+              <!-- 正态分布 -->
+              <div v-show="active == 1">
+                <div class="statementHnum flex-box-ce flex-d-wrap flex-d-center">
+                  <div class="Hnumvfor">
+                    <span class="smHnLtit">总人数</span>
+                    <br />
+                    <span class="smHnLnum">{{ userTotal }}</span>
+                    <br />
+                    <span{{ userComplete }}人已完成</span>
+                  </div>
+                  <div v-for="(item, index) in scoreList" class="Hnumvfor" :key="index">
+                    <span class="smHnLtit">{{ item.name }}</span>
+                    <br />
+                    <span class="smHnLnum">{{users.filter(user => user.scoreResult === item.name).length}}</span>
+                    <br />
+                  </div>
+                </div>
+               </div>
+
+              <div>
+
+              <div>
+
+                  <!-- <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" /> -->
+                  <div class="flex-box-ce">
+                    <div class="selectItem flex-2 font-flex-word" @click="showDept = true">
+                      <span>{{ deptName }}</span>
+                      <van-icon name="arrow-down" />
+                    </div>
+                  </div>
+
+                  <ol v-if="filterUsers && filterUsers.length > 0">
+                    <li @click="openDetail(item)" v-for="(item, index) in filterUsers" :key="index" class="flex-ce-box flex-d-center statmentperson" :style="index != 0 ? 'border-top: 0.02rem solid #e6e6e6;' : ''">
+
+                      <div class="flex-1 flex-box" style="align-items: center; justify-content: space-between;">
+                        <div class="score-result" >{{ item.scoreResult }}</div>
+                        <div class="flex-box-ce flex-1">
+                          <userImage :id="item.employeeId" :user_name="item.employeeName" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-top:.08rem;"></userImage>
+                          <div style="padding-left:.2rem;">
+                            <span style="font-size:.3rem;">{{ item.employeeName }}</span>
+                            <br />
+                            <span class="font-flex-word" style="width: 3.8rem;display:inline-block;" v-if="item.dept_list && item.dept_list.length > 0">
+                              <span style="font-size:.25rem;" v-for="(arr, att) in item.dept_list" :key="att">
+                                {{ arr.dept_name }}
+                                <span v-if="item.dept_list.length - att > 1">,</span>
+                              </span>
+                            </span>
+                          </div>
+                        </div>
+                        <div style="display: flex; align-items: center; flex-direction: column;">
+                          <div v-if="item.status == 0" class="review-status">进行中</div>
+                          <div v-if="item.status == 1" class="review-status" style="background-color: #FF9600;">已结束</div>
+                          <div style="display: flex; align-items: center; white-wrap: no-wrap; font-size:.26rem; text-align:center; overflow: hidden;">
+
+                            <span>{{ item.score == undefined || item.score == null || item.score == ''  ? '-' : item.score }}</span>
+                            &nbsp;/&nbsp;
+                            <span style="color:#ffad67;">{{ item.level ? item.level : '--'}}</span>
+                          </div>
+                        </div>
+                      </div>
+
+                    </li>
+                  </ol>
+                  <noData v-else content="无考核记录"></noData>
+
+
+                </div>
+
+              </div>
+
+
+
+
+            </div>
+
+            <template>
+
+
+
+            <div class="indicator-list-title">指标分析</div>
+
+            <div class="indicator-list">
+              <div class="indicator-item" v-for="(item, index) in tableData2" :key="index">
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">指标名称</div>
+                  <div class="indicator-info-value">{{ item.title }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">目标</div>
+                  <div class="indicator-info-value">{{ item.target }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">均值</div>
+                  <div class="indicator-info-value">{{ item.avgResult }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">超出目标比例</div>
+                  <div v-if="parseInt(item.standardResultRate) > 0" class="indicator-info-value color-green" >{{ item.standardResultRate }}</div>
+                  <div v-else-if="parseInt(item.standardResultRate) < 0" class="indicator-info-value color-red" >{{ item.standardResultRate }}</div>
+                  <div v-else="parseInt(item.standardResultRate) > 0" class="indicator-info-value color-gray" >{{ item.standardResultRate }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">达标数</div>
+                  <div class="indicator-info-value">{{ item.standardCount }}</div>
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">达标率</div>
+                  <div v-if="parseInt(item.standardRate) > 0" class="indicator-info-value color-green" >{{ item.standardRate }}</div>
+                  <div v-else-if="parseInt(item.standardRate) < 0" class="indicator-info-value color-red" >{{ item.standardRate }}</div>
+                  <div v-else="parseInt(item.standardRate) > 0" class="indicator-info-value color-gray" >{{ item.standardRate }}</div>
+
+                </div>
+
+                <div class="indicator-item-info">
+                  <div class="indicator-info-label">平均分</div>
+                  <div class="indicator-info-value">{{ item.avgScore }}</div>
+                </div>
+
+              </div>
+            </div>
+
+            </template>
+          </div>
+        </scroller>
+      </template>
+    </VanSkeleton>
+
+
+
+    <!-- 周期选择 -->
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="cycleOptions" @cancel="pullonThePanel = false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+      </div>
+    </van-action-sheet>
+
+    <!-- 部门搜索 -->
+    <van-dialog v-model="showDept" width="300" confirm-button-text="确定" @confirm="handleConfirm" @cancel="handleCancel" :show-confirm-button="true" closeOnClickOverlay>
+       <div style="height: 8rem; overflow: auto;" class="scroll-bar">
+         <div class="dept-list">
+           <div class="dept-item flex-box-ce" v-for="(item, index) in department_list" :key="index">
+             <van-checkbox shape="square" v-model="item.select" style="margin-right: 0.16rem;"></van-checkbox>
+             <div class="dept-item-name">{{ item.dept_name }}</div>
+           </div>
+         </div>
+       </div>
+    </van-dialog>
+
+  </div>
+</template>
+
+
+<script>
+import Vue from 'vue';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import { getBelongType, getColumns, cycleTypeArr} from '@/okr/utils/auth';
+import { Picker, ActionSheet, Circle, Tab, Tabs, Skeleton, DropdownMenu, DropdownItem, Progress, Calendar } from 'vant';
+import { _debounce } from '@/utils/auth';
+import _ from "lodash"
+
+Vue.use(Picker)
+  .use(ActionSheet)
+  .use(Circle)
+  .use(Tab)
+  .use(Tabs)
+  .use(Skeleton)
+  .use(DropdownMenu)
+  .use(DropdownItem)
+  .use(Progress)
+  .use(Calendar);
+export default {
+  data() {
+    return {
+      skeletonLoad: true, //
+      statementtabshow: false,
+      statementperson: [],
+      statementResult: [],
+      allStatementResult: [],
+      statementVanTabs: [{ name: '等级分布' }, { name: '正态分布' }],
+      active: 0,
+      detailInfo: null,
+      startTime: "",
+      endTime: "",
+      deptIds: [],
+      rank: "",
+      rankList: [],
+      deptList: [],
+      scoreList: [],
+      users: [], //考核人员列表
+      filterUsers: [],
+      tableData1: [], // 考核中的指标列表,
+      tableData2: [], // 按单位/目标/聚合指标列表,
+      filterTableData1: [],
+      filterTableData2: [],
+      distributionId: '',
+      userTotal: 0,
+      userComplete: 0,
+      userIncomplete: 0,
+      infos: [],
+      cycleColumns: getColumns(),
+      cycleTypeArr:cycleTypeArr(true),
+      selectPftiTheEcho: [0, 0], // 选项回显
+      dateParameter: {
+        year: this.$moment().format('YYYY'),
+        cycle_type: 0,
+        dateId: 1,
+        name: '全部周期'
+      },
+
+
+      selectPftiText: '', // 展示名字
+      selectPftiTheEcho: [0, 0], // 选项回显
+      pullonThePanel: false, // 选项面板
+      selectPftiData: {}, // 当前选中项
+
+      keyword: "",
+      deptName: '全部部门',
+      department_list: [],
+      showDept: false,
+      recordList: [],
+      userInfo: this.$userInfo(),
+      gradeLevels: [], // 全局等级配置
+
+      cycleOptions: [
+        { name: "月度", value: "4", id: "4", text: "月度", children: [] },
+        { name: "季度", value: "3", id: "3", text: "季度", children: [] },
+        { name: "半年度", value: "2", id: "2", text: "半年度", children: [] },
+        { name: "年度", value: "1", id: "1", text: "年度", children: [] },
+        { name: "自定义", value: "0", id: "0", text: "自定义", children: [] },
+      ],
+
+      isYou: true,
+      params: {
+        cycleType: 1,
+        startDate: '',
+        endDate: '',
+        deptIds: '',
+        year: 2025
+      }
+    };
+  },
+
+
+  components: { VanSkeleton },
+
+  watch: {
+    detailInfo(v) {
+      console.log("-------------结果分析,初始化数据-------------")
+      this.$nextTick(() => {
+        this.initData();
+      })
+    }
+  },
+
+
+  methods: {
+
+    openDetail(item){
+      this.$router.push({ path: '/me', query: { reviewId: item.reviewId, employeeId: item.employeeId } });
+    },
+
+    async initData() {
+      // this.activeName = '1'
+      this.deptName = '全部部门'
+      this.deptIds = [];
+      this.department_list = [];
+      this.users = [];
+      this.filterUsers = [];
+      this.tableData1 = [];
+      this.tableData2 = [];
+      this.filterTableData1 = [];
+      this.filterTableData2 = [];
+      let { indicators, startTime, endTime, distribution: { items }, users } = this.detailInfo
+      console.log(this.detailInfo)
+      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 => {
+          this.users.forEach(user => {
+              if (user.employeeId == item.employeeId) {
+                item.departments = user.departments
+              }
+          })
+          if (item.target && item.result) {
+              item.difference = item.result - item.target
+          } else {
+              item.difference = '--'
+          }
+      })
+      this.filterTableData1 = this.tableData1;
+      if(this.tableData1 && this.tableData1.length > 0) {
+        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: '',
+              departments: [],
+              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; // 单位
+              group.departments = indicator.departments; // 单位
+              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;
+            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);
+            this.filterTableData2 = this.tableData2;
+            console.log("this.tableData2")
+            console.log(this.tableData2)
+          })
+      }
+
+
+      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)
+      })
+
+      if (this.users && this.users.length > 0) {
+          this.users.forEach(user => {
+              this.userTotal++;
+              this.userComplete += user.status === 1 ? 1 : 0;
+              user.level = this.findGrade(user.score, this.gradeLevels);
+              // this.rankList.push(user.level || '未评分')
+              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 => {
+            item.dept_list = this.$getEmployeeMapItem(item.employeeId).employee_detail.dept_list
+            if(item.dept_list && item.dept_list.length > 0) {
+              item.dept_list.forEach(dept => {
+                dept.id = dept.dept_id
+                item.select = false
+                this.department_list.push(dept)
+              })
+            }
+            scoreResult.forEach(result => {
+                if (result.scores.includes(item.score)) {
+                    item.scoreResult = result.level
+                }
+            })
+          })
+
+          // 按分数排序
+          this.users = this.users.slice().sort((a, b) => b.score - a.score);
+
+          // this.filterUsers = cloneDeep(this.users)
+          this.filterUsers = this.users
+          // this.getResult();
+          let pieData = []
+
+          if(this.users && this.users.length > 0) {
+            pieData = this.gradeLevels.map(item => ({
+              name: item.name + '   ' + this.users.filter(user => user.level === item.name).length + '人',
+              value: this.users.filter(user => user.level === item.name).length
+            }))
+
+            this.statmentAnalysesPie(pieData)
+          }
+      }
+    },
+
+    statmentAnalysesPie(data) {
+      let colors = ['rgb(38, 162, 255)', '#f36f2a', '#fecb09', '#00b6bd', '#e85d53', '#fecb09'];
+      let legendDataLeng = data.length;
+      if (legendDataLeng > colors.length) {
+        let colorsLeng = colors.length;
+        for (let i = 0; i <= legendDataLeng - colorsLeng; i++) {
+          colors.push('rgb(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ')');
+        }
+      }
+
+      //
+
+      const chart = this.$refs.statmentAnalysePie;
+      if (chart) {
+        const myChart = this.$echarts.init(chart);
+        const option = {
+          legend: [
+            {
+              type: 'scroll',
+              orient: 'vertical',
+              icon: 'square',
+              left: '55%',
+              align: 'left',
+              top: 'center',
+              itemGap: 20,
+              itemWidth: 5, // 图形宽度。
+              itemHeight: 5, // 图形高度。
+              // bottom:'50%',
+              textStyle: {
+                fontSize: 14,
+                color: 'rgb(48, 49, 51)'
+              }
+              // data: Name
+            }
+          ],
+          color: colors,
+          emphasis: {
+            scale: true,
+            scaleSize: 10,
+            label: {
+              formatter: '总人数',
+              show: true,
+              fontSize: '20'
+            }
+          },
+          series: [
+            {
+              type: 'pie',
+              radius: ['43%', '53%'],
+              center: ['30%', '50%'],
+              avoidLabelOverlap: false,
+              itemStyle: {
+                borderRadius: 10,
+                borderColor: '#fff',
+                borderWidth: 2
+              },
+              label: {
+                show: false,
+                position: 'center'
+              },
+              labelLine: {
+                show: false
+              },
+              data
+            }
+          ]
+        };
+        myChart.setOption(option);
+        setTimeout(() => {
+          myChart.resize();
+        }, 200);
+      }
+    },
+
+
+
+    // 查找分数对应的等级
+    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
+            };
+        });
+    },
+
+
+
+    openPanel(){
+      this.pullonThePanel = true;
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+
+    // 考核包搜索
+    onConfirm (data, list) { // 确认
+      console.log(data)
+      console.log(list)
+      let cycle = this.cycleOptions[list[0]].value
+      let time = this.cycleOptions[list[0]].children[list[1]].value
+      this.getResultAnalyze(cycle, time)
+      this.pullonThePanel = false
+    },
+
+    // 获取全局等级设置
+    async getAllLevelSet() {
+      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;//最大值
+      let colorList = ['#5F7294', '#08EEA1', '#f56c6c', '#0887EE', '#92EE08', '#f56c6c']
+      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 };//当不是第一个等级时,最小值为上一个的最大值
+              }
+              obj.color = colorList[index]
+              max = item.value;
+              gradeLevels.push(obj);
+          })
+          this.gradeLevels = gradeLevels
+          console.log("this.gradeLevels")
+          console.log(this.gradeLevels)
+        }
+    },
+
+    // 获取结果分析数据
+    getResultAnalyze(cycle, time) {
+      let url = `/performance/statistics/cycle/${this.$userInfo().site_id}/${cycle}`
+      this.$axiosUser("get", url, { value: `${time}` }).then(res => {
+        console.log("获取结果分析数据")
+        this.detailInfo = res.data.data
+        this.skeletonLoad = false
+        console.log(this.isYou)
+      })
+    },
+
+
+
+    getData() {
+      let url = `/performance/statistics/reviews/${this.userInfo.site_id}`;
+      let params = {
+        cycleType: 4,
+        startDate: '',
+        endDate: '',
+        deptIds: '',
+        cycleValue: 7,
+        year: 2025
+      }
+
+      this.$axiosUser("get", url, params).then(res => {
+        if (res.data.code == 1) {
+          let recordList = res.data.data.list;
+          if(recordList.length == 0) {
+            this.isYou = false
+            return false
+          } else {
+            this.isYou = true
+            let theOf = this.theProgressOf;
+            theOf.complete = recordList.filter(item => item.status == 1).length || 0 // 已完成人数
+            theOf.theTotalNum = res.data.data.total; // 总人数
+            let rate = (theOf.complete / theOf.theTotalNum) * 100; // 进度条百分比
+            if(!isNaN(rate)){
+              this.rate = rate; // 进度条百分比
+            }
+            recordList.forEach(item => {
+              item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+              item.dept_list = this.$getEmployeeMapItem(item.employeeId).employee_detail.dept_list
+            })
+
+          }
+          console.log("---------------------------------")
+          console.log(recordList)
+          this.recordList = recordList
+          this.skeletonLoad = false
+        }
+
+
+
+      })
+
+    },
+
+
+
+    theEchoVanPicker() {
+      // 回显
+      this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+    },
+
+    onCancel() {
+      // 取消
+      this.pullonThePanel = false;
+    },
+
+
+
+    statementTabs(key, tit) {
+    },
+
+
+
+    statementTIme() {
+      this.pullonThePanel = true;
+      this.$nextTick(() => {
+        this.theEchoVanPicker();
+      });
+    },
+
+
+    keyVal: _debounce(function() {
+      if(!this.keyword) this.filterUsers = this.recordList
+      // let filterUsers = []
+      if(this.recordList && this.recordList.length > 0) {
+        this.filterUsers = this.recordList.filter(item => item.employeeName.includes(this.keyword.trim()))
+      }
+    }),
+
+    handleConfirm() {
+      this.deptIds = this.department_list.filter(item => item.select).map(item => item.dept_id)
+      if(this.deptIds && this.deptIds.length > 0) {
+        this.deptName = ''
+        this.department_list.filter(item => item.select).forEach(dept => {
+          this.deptName += dept.dept_name + ","
+        })
+        this.deptName = this.deptName.substring(0, this.deptName.length - 1)
+        this.filterUsers = this.users.filter((item) => {
+          const departmentMatch = this.deptIds.length === 0 || this.deptIds.some((depId) => item.departments.some(dep => dep.id == depId));
+          return departmentMatch;
+        });
+      }else {
+        this.deptName = '全部部门'
+      }
+      this.showDept = false;
+    },
+
+    handleCancel() {
+      this.showDept = false;
+    },
+
+    getColumnsInfo(cycle) {
+      if (cycle < 0) {
+        cycle = 0
+        return
+      }
+      // this.loading = true
+      // 周期种类 0-自定义 1-年度 2-半年度 3-季度 4-月度
+      let url = `/performance/statistics/cycle/info/${this.$userInfo().site_id}/${cycle}`
+      this.$axiosUser("get", url, {}).then(res => {
+        console.log("获取周期数据")
+        console.log(res)
+          // this.loading = false;
+          let { data: { data: { items, cycleType } } } = res
+          let index = parseInt(4 - cycle)
+          this.cycleOptions[index].children = items
+          if (items && items.length > 0) {
+              items.forEach(item => {
+                  item.name = item.remark
+                  item.text = item.remark
+                  item.id = item.value
+              })
+
+              let cycle = this.cycleOptions[index].value
+              let time = this.cycleOptions[index].children[[0]].value
+              // if(!(this.detailInfo && this.detailInfo.users && this.detailInfo.users.length > 0)) {
+              //   if(time) {
+              //     this.getResultAnalyze(cycle, time)
+              //   }
+              // }
+
+              // this.getColumnsInfo(parseInt(cycle) - 1) // 递归周期类型,获取考核数据,优先按月,季,半年度,年度来调用
+          } else {
+            this.cycleOptions[index].children = [
+              {name: '', text: '', value: '', id: ''}
+            ]
+          }
+      })
+    },
+
+  },
+
+  mounted() {
+    this.$nextTick(async () => {
+      // 获取全局等级
+      await this.getAllLevelSet();
+
+      // 获取周期列表数据
+      await this.getColumnsInfo(4);
+      await this.getColumnsInfo(3);
+      await this.getColumnsInfo(2);
+      await this.getColumnsInfo(1);
+      await this.getColumnsInfo(0);
+
+      for(let i = 4; i >=0; i--) {
+        console.log(i)
+      }
+      this.getResultAnalyze(4, '2025:5')
+    })
+  },
+
+  created() {
+
+  }
+};
+</script>
+
+<style scoped lang="less">
+
+  .color-red {
+    padding: 0.05rem 0.2rem;
+    box-sizing: border-box;
+    background-color: #fef0f0;
+    border: 0.02rem solid #fde2e2;
+    color: #f56c6c !important;
+  }
+
+  .color-green {
+    padding: 0.05rem 0.2rem;
+    box-sizing: border-box;
+    background-color: #f0f9eb;
+    border: 0.02rem solid #e1f3d8;
+    color: #67c23a !important;
+  }
+
+  .color-gray {
+    padding: 0.05rem 0.2rem;
+    box-sizing: border-box;
+    background-color: #f4f4f5;
+    border: 0.02rem solid #e9e9eb;
+    color: #909399 !important;
+  }
+
+  .dept-list {
+    padding: 0.2rem;
+    box-sizing: border-box;
+    .dept-item {
+      box-sizing: border-box;
+      padding-left: 0.3rem;
+      margin-bottom: 0.2rem;
+      &-name {
+        font-size: 0.28rem;
+        color: #89919F;
+      }
+    }
+  }
+
+  .statementHnum {
+    padding: 0.2rem;
+    padding-bottom: 0rem;
+    .Hnumvfor {
+      width: 22.8%;
+      position: relative;
+      background-color: #ECF5FF;
+      border-radius: 3px;
+      text-align: center;
+      padding: 0.1rem 0.2rem;
+      box-sizing: border-box;
+      margin-bottom: 0.2rem;
+      .smHnLnum {
+        font-size: 0.42rem;
+        color: #00a1ff;
+      }
+      .smHnLtit {
+        font-size: 0.26rem;
+        color: #8a8a8a;
+      }
+    }
+  }
+
+.selectItem {
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  border-top: 0.02rem solid #f1f1f1;
+  text-align: center;
+  font-size: 0.28rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+header {
+  .selector {
+    z-index: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 0.8rem;
+    line-height: 0.8rem;
+    background-color: #fff;
+    text-align: center;
+    font-size: 0.28rem;
+    i {
+      margin: 0 0 0 0.1rem;
+      color: #c3c3c3;
+    }
+    span {
+      max-width: 3.5rem;
+      overflow: hidden;
+    }
+  }
+}
+
+.all {
+  height: calc(100% - 1.92rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+  .statementHead {
+    width: 100%;
+    text-align: center;
+    // padding-top: 0.35rem;
+    background-color: #fff;
+    .statementpropnum {
+      background-color: #f5f7fa;
+      padding: 0.3rem 0 0.1rem;
+      .propnumrel1 {
+        /deep/ .van-progress__pivot {
+          margin-left: -0.11rem;
+        }
+      }
+      .propnumrel {
+        position: relative;
+        padding: 0 0.15rem;
+        /deep/ .van-progress {
+          border-radius: 0.5rem;
+          .van-progress__portion {
+            border-radius: 0.14rem;
+            .van-progress__pivot {
+              border-radius: 50%;
+              min-width: 0.33rem !important;
+              height: 0.33rem;
+              right: 0;
+              // margin-left: -.11rem;
+            }
+          }
+        }
+        .propnumcol {
+          position: absolute;
+          top: 0;
+          right: 0.4rem;
+          font-size: 0.25rem;
+          color: #fff;
+        }
+        .numelzi {
+          font-size: 0.26rem;
+          margin: 0.25rem 0;
+          .numelzh {
+            color: #000000;
+          }
+          .numelzl {
+            color: #0597ff;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            i {
+              margin: 0.06rem 0 0 0.02rem;
+            }
+          }
+        }
+      }
+    }
+    .circle {
+      margin-top: 0.7rem;
+      .circletit {
+        font-size: 0.24rem;
+        color: #6f6f6f;
+      }
+      .circleclic {
+        color: #4ba0f1;
+        .circleclics1 {
+          font-size: 0.42rem;
+          display: inline-block;
+          margin: 0.1rem 0;
+        }
+        .circleclics2 {
+          font-size: 0.25rem;
+          display: flex;
+          justify-content: center;
+          i {
+            margin: 0.06rem 0 0 0.02rem;
+          }
+        }
+      }
+    }
+
+    .statementHnum {
+      padding: 0.2rem;
+      padding-bottom: 0rem;
+      .Hnumvfor {
+        width: 22.8%;
+        position: relative;
+        background-color: #ECF5FF;
+        border-radius: 3px;
+        text-align: center;
+        padding: 0.1rem 0.2rem;
+        box-sizing: border-box;
+        margin-bottom: 0.2rem;
+        .smHnLnum {
+          font-size: 0.42rem;
+          color: #00a1ff;
+        }
+        .smHnLtit {
+          font-size: 0.26rem;
+          color: #8a8a8a;
+        }
+      }
+    }
+  }
+  .statementFoot {
+    background-color: #fff;
+    margin-top: 0.2rem;
+    .statmentperson {
+      padding: 0.25rem 0.2rem;
+      font-size: 0.32rem;
+      box-sizing: border-box;
+      .score-result {
+        width: 0.4rem;
+        height: 0.4rem;
+        border: 0.02rem solid #409EFF;
+        color: #409EFF;
+        border-radius: 50%;
+        font-size: 0.26rem;
+        text-align: center;
+        line-height: 0.4rem;
+        margin-right: 0.1rem;
+      }
+    }
+  }
+}
+
+.takI {
+  font-size: 0.27rem;
+  color: #f7b461;
+  i {
+    margin: 0.1rem 0.05rem 0 0;
+  }
+}
+
+.statmentAnalysePie {
+  position: relative;
+  .PiePropNum {
+    width: 1.5rem;
+    text-align: center;
+    position: absolute;
+    left: 20%;
+    top: 42%;
+    font-size: 0.3rem;
+  }
+}
+
+.review-status {
+  // padding: 0.01rem 0.1rem;
+  width: 1.2rem;
+  height: 0.4rem;
+  text-align: center;
+  line-height: 0.4rem;
+  color: #fff;
+  border-radius: 2px;
+  font-size: 0.26rem;
+  background-color: #67c23a;
+  margin-right: 0.14rem;
+  margin-bottom: 0.1rem;
+}
+
+.indicator-list-title {
+  padding: 0.2rem 0.2rem 0 0.2rem;
+  box-sizing: border-box;
+  font-size: 0.28rem;
+}
+
+.indicator-list {
+  padding: 0.2rem;
+  box-sizing: border-box;
+  .indicator-item {
+    background-color: white;
+    margin-bottom: 0.2rem;
+    padding: 0.2rem;
+    box-sizing: border-box;
+    border-radius: 8px;
+    .indicator-item-info {
+      display: flex;
+      align-items: center;
+      font-size: 0.28rem;
+      margin-bottom: 0.2rem;
+      .indicator-info-label {
+        width: 2rem;
+        color: black;
+      }
+      .indicator-info-value {
+        // flex: 1;
+        color: #89919F;
+      }
+
+    }
+  }
+}
+</style>

+ 961 - 0
src/performance-07-19/view/navhome/statement - 副本.vue

@@ -0,0 +1,961 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="绩效报表" left-text="返回" left-arrow @click-left="$route_back" />
+    <VanSkeleton :skeLoad="skeletonLoad" v-if="isYou">
+      <template>
+        <header>
+          <div class="selector performanceList" @click="statementTIme">
+            <span>{{ selectPftiText }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+        </header>
+        <scroller ref="me_scroller" class="all">
+          <div style="padding-bottom:1.5rem;">
+            <div class="statementHead">
+              <div class="statementpropnum">
+                <div class="propnumrel" :class="{ propnumrel1: theProgressOf.complete != 0 }">
+                  <van-progress
+                    :percentage="rate"
+                    stroke-width="16"
+                    pivot-text="''"
+                    :show-pivot="theProgressOf.complete != theProgressOf.theTotalNum"
+                    pivot-color="#FFF"
+                    track-color="#26a2ff"
+                    color="rgb(255, 173, 103)"
+                  />
+                  <div class="propnumcol"></div>
+                  <div class="flex-box flex-d-center numelzi">
+                    <span class="numelzh">
+                      考核进度:
+                      <span style="color: rgb(255, 173, 103);">{{ theProgressOf.complete }}人</span>
+                      /
+                      <span style="color: #26a2ff;">{{ theProgressOf.theTotalNum }}人</span>
+                    </span>
+                    <span class="numelzl" @click.stop="personnel_detailsPath(0)">
+                      查看人员明细
+                      <van-icon name="arrow" />
+                    </span>
+                  </div>
+                </div>
+              </div>
+              <div class="statementHnum flex-box-ce flex-d-wrap flex-d-center">
+                <div v-for="(item, index) in statementHnList" class="Hnumvfor" :key="index" @click="personnel_detailsPath(item.key)">
+                  <span class="smHnLtit">{{ item.tit }}</span>
+                  <br />
+                  <span class="smHnLnum">{{ item.num }}</span>
+                </div>
+              </div>
+            </div>
+            <div class="statementFoot">
+              <van-tabs v-model="active" @change="statementTabs">
+                <van-tab v-for="(item, index) in statementVanTabs" :key="index" :title="item.name"></van-tab>
+              </van-tabs>
+              <div class="statmentAnalysePie" v-show="active == 0 && allStatementResult.length > 0">
+                <div style="width: 7.5rem;height: 5rem;" id="statmentAnalysePie" ref="statmentAnalysePie"></div>
+                <div class="PiePropNum">
+                  <div>总人数</div>
+                  <div>{{ PieProps }}人</div>
+                </div>
+              </div>
+              <div v-show="active == 1 && deptMentList.length > 0">
+                <div class="statmentAnalysebar" style="width: 7.5rem;height: 5rem;" id="statmentAnalysebar" ref="statmentAnalysebar"></div>
+              </div>
+              <van-empty description="暂无部门分析" v-if="active == 1 && deptMentList.length == 0" />
+              <van-empty description="暂无结果分析" v-if="active == 0 && allStatementResult.length == 0" />
+              <div v-if="statementtabshow">
+                <div v-if="statementperson.length > 0">
+                  <span style="font-size: .31rem;margin: .45rem 0 .15rem .32rem;display: inline-block;">参与考核部门人数</span>
+                  <van-cell is-link center v-for="(item, index) in statementperson" :key="index" @click="cellDept(item)">
+                    <template #title>
+                      <div style="font-size: .30rem;">
+                        <div>{{ item.name }}</div>
+                        <div class="takI flex-box" style="">
+                          <van-icon name="friends-o" />
+                          {{ item.tak }}人
+                        </div>
+                      </div>
+                    </template>
+                  </van-cell>
+                </div>
+              </div>
+              <div v-else>
+                <div>
+                  <div class="flex-box-ce">
+                    <span class="flex-1" style="font-size: .31rem;margin: .45rem 0 .15rem .2rem;display: inline-block;">绩效排名</span>
+                    <div class="selectItem flex-2 font-flex-word" @click="showDept = true">
+                      <span>{{ deptName }}</span>
+                      <van-icon name="arrow-down" />
+                    </div>
+                    <div class="selectItem flex-1 font-flex-word" @click="showLevel = true">
+                      <span>{{ levelsText }}</span>
+                      <van-icon name="arrow-down" />
+                    </div>
+                  </div>
+                  <ol v-if="statementResult.length > 0">
+                    <li @click="openDetail(item)" v-for="(item, index) in isShow" :key="index" class="flex-box flex-d-center statmentperson" :style="index != 0 ? 'border-top: 0.02rem solid #e6e6e6;' : ''">
+                      <span style="font-size:.31rem;" class="flex-box">
+                        <span style="font-size:.28rem;line-height:.75rem">{{ index + 1 }}&nbsp;&nbsp;</span>
+                        <userImage :id="item.id" :user_name="item.name" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-top:.08rem;"></userImage>
+                        <div style="padding-left:.2rem;">
+                          <span style="font-size:.3rem;">{{ item.name }}</span>
+                          <br />
+                          <span class="font-flex-word" style="width: 3.8rem;display:inline-block;" v-if="item.departments.length > 0">
+                            <span style="font-size:.25rem;" v-for="(arr, att) in item.departments" :key="att">
+                              {{ arr.dep_name }}
+                              <span v-if="item.departments.length - att > 1">,</span>
+                            </span>
+                          </span>
+                        </div>
+                      </span>
+
+                      <span style="font-size:.26rem;line-height: .8rem;text-align:center;" v-if="item.publicity">
+                        <span>{{ item.point == 0 ? '-' : item.point }}</span>/
+                        <span v-if="item.level != ''" style="color:#ffad67;">{{ item.level == 'empty' ? '无等级' : item.level }}</span>
+                        <span v-else>无等级</span>
+                      </span>
+                    </li>
+                  </ol>
+                  <noData content="无考核记录" v-if="isShow.length == 0"></noData>
+                </div>
+              </div>
+            </div>
+          </div>
+        </scroller>
+      </template>
+    </VanSkeleton>
+    <noData content="无考核记录" v-else></noData>
+
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="onCancel" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+        </div>
+    </van-action-sheet>
+
+    <!-- 部门搜索 -->
+    <van-dialog v-model="showDept" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="deptId">
+        <div v-for="(item, index) in department_list" :key="index">
+          <van-radio :name="item.value" @click="clickGlConfirm(item, 1)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.text }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+    <!-- 等级搜索 -->
+    <van-dialog v-model="showLevel" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="level">
+        <div v-for="(item, index) in levels_list" :key="index">
+          <van-radio :name="item.value" @click="clickGlConfirm(item, 2)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.text }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import { Picker, ActionSheet, Circle, Tab, Tabs, Skeleton, DropdownMenu, DropdownItem, Progress } from 'vant';
+Vue.use(Picker)
+  .use(ActionSheet)
+  .use(Circle)
+  .use(Tab)
+  .use(Tabs)
+  .use(Skeleton)
+  .use(DropdownMenu)
+  .use(DropdownItem)
+  .use(Progress);
+export default {
+  data() {
+    return {
+      skeletonLoad: true, //
+      statementtabshow: false,
+      statementperson: [],
+      statementResult: [],
+      allStatementResult: [],
+      statementVanTabs: [{ name: '结果分析' }, { name: '考核人数分析' }],
+      active: 0,
+      statementHnList: [
+        { tit: '参与人数', num: 0, key: 0},
+        {tit:'目标制定',num: 0, key: 1},
+        {tit:'目标确认',num: 0, key: 2},
+        { tit: '执行中', num: 0, key: 3},
+        { tit: '结果值录入', num: 0, key: 4},
+        { tit: '评分', num: 0, key: 5},
+        { tit: '审批', num: 0, key: 9},
+        { tit: '考核结束', num: 0, key: 11}
+      ],
+      theProgressOf: {
+        complete: 0,
+        theTotalNum: 0
+      },
+      currentRate: 0,
+      rate: 0,
+      gradientColor: {
+        '0%': '#3fecff',
+        '100%': '#6149f6'
+      },
+
+      selectPftiText: '', // 展示名字
+      selectPftiTheEcho: [0, 0], // 选项回显
+      pullonThePanel: false, // 选项面板
+      selectPftiData: {}, // 当前选中项
+      columns: [], // 顶部选项
+
+
+      assPeopleFx: {}, // 考核人数分析echarts数据
+      theResultsOfFx: {}, // 结果分析echarts数据
+
+      employList: {}, // 部门人员列表
+      deptMentList: [],
+
+      deptName: '全部部门',
+      department_list: [],
+      showDept: false,
+      deptId: 0,
+      levelsText: '全部等级',
+      showLevel: false,
+      levels_list: [],
+      level: '-',
+      PieProps: 0,
+
+      isYou:true,
+    };
+  },
+  components: {VanSkeleton },
+  computed: {
+    isShow() {
+      let arr = [];
+      this.allStatementResult.map(item => {
+        if (this.isQualified(item)) {
+          arr.push(item);
+        }
+      });
+      return arr;
+    }
+  },
+  methods: {
+    openDetail(item){
+       this.$router.push({ name: 'performanceDetails', query: { assId: this.selectPftiData.id, staffId: item.id, Tit: this.selectPftiText } });
+    },
+    isQualified(item) {
+      if (this.deptId == 0 && this.level == '-') {
+        return true;
+      }
+      let isDept = false,
+        isLevel = false;
+      if (this.deptId != 0) {
+        item.departments.some(e => {
+          if (e.id == this.deptId) {
+            isDept = true;
+            return true;
+          }
+        });
+      }
+      if (item.level == this.level || this.level == '-') {
+        isLevel = true;
+      }
+      if (this.deptId == 0) {
+        isDept = true;
+      }
+      return isDept && isLevel;
+    },
+    clickGlConfirm(item, index) {
+      if (index == 1) {
+        this.deptName = item.text;
+        this.showDept = false;
+      } else {
+        this.levelsText = item.text;
+        this.showLevel = false;
+      }
+    },
+    personnel_detailsPath(index) {
+      // 查看人员明细跳转
+      let data={
+        paths: 'personnelDetail',
+        asslist: JSON.stringify(this.selectPftiData),
+        index:index,
+      }
+      this.$setCache('statement_details',data)
+      this.$router.push({ name: 'statement_details'});
+    },
+    columnList() {
+      // 绩效包树
+      this.$axiosUser('get', '/api/pro/per/package/list', { page: 0, is_manage_scope: 1 }).then(res => {
+        if (res.data.code == 1) {
+          let obj = res.data.data.list;
+          if(obj.length==0){
+            this.isYou=false
+            return false
+          }else{
+             this.isYou=true
+          }
+
+          let arr = [
+            { name: '月度', id: 2, list: [] },
+            { name: '日', id: 1, list: [] },
+            { name: '季度', id: 3, list: [] },
+            { name: '半年度', id: 4, list: [] },
+            { name: '年度', id: 5, list: [] },
+            { name: '自定义', id: 6, list: [] }
+          ];
+          obj.forEach(item => {
+            arr.forEach(item2 => {
+              if (item2.id == item.cycle_type) {
+                item2.list.push(item);
+              }
+            });
+          });
+          let data = arr;
+          let list = [];
+          data.forEach(item => {
+            if (item.list.length > 0) {
+              list.push(item);
+              item.children = item.list;
+            }
+          });
+          let monthXz = false;
+          list.forEach((item, index) => {
+            if (item.name == '月度') {
+              // 有月,月的第一个
+              monthXz = true;
+              this.selectPftiData = item.children[0];
+              this.selectPftiText = item.children[0].name;
+              this.selectPftiTheEcho = [index, 0]; // 回显
+            }
+          });
+          if (!monthXz) {
+            // 没有月,默认选项第一个
+            if (list.length > 0) {
+              this.selectPftiData = list[0].children[0];
+              this.selectPftiText = list[0].children[0].name;
+              this.selectPftiTheEcho = [0, 0];
+            }
+          }
+          if (list.length > 0) {
+            this.statisticalPeople();
+            // console.log(list)
+            this.columns = list;
+          } else {
+            this.skeletonLoad = false;
+          }
+        }
+      });
+    },
+    theEchoVanPicker() {
+      // 回显
+      this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+    },
+    onConfirm(data, list) {
+      // 确认
+      this.deptId = 0;
+      this.level = '-';
+      this.deptName = '全部部门';
+      this.levelsText = '全部等级';
+      this.selectPftiTheEcho = list; // 回显
+      this.selectPftiData = this.columns[list[0]].children[list[1]]; // 当前选中项
+      this.selectPftiText = data[data.length - 1]; // 选中的name
+      this.statisticalPeople();
+      this.pullonThePanel = false;
+    },
+    onCancel() {
+      // 取消
+      this.pullonThePanel = false;
+    },
+    statementTabs(key, tit) {
+      // 点击标签切换时
+      let data = {};
+      if (key == 0) {
+        this.statementtabshow = false;
+        data = this.theResultsOfFx;
+        this.statmentAnalysesPie(data);
+      } else if (key == 1) {
+        this.statementtabshow = true;
+        data = this.assPeopleFx;
+        this.statmentAnalysesBar(data);
+      }
+    },
+
+    statisticalPeople() {
+      let params = {
+        package_id: this.selectPftiData.id,
+      };
+      this.$axiosUser('get', '/api/pro/per/package/info_v3_aid', params).then(res => {
+        if (res.data.code == 1) {
+          this.skeletonLoad = false;
+          let data = res.data.data.statistics;
+          let list = this.statementHnList;
+          let theOf = this.theProgressOf;
+          let all = 0
+          for(let i in data){
+            all += data[i]
+          }
+          list[0].num = all; // 参与人数
+          list[1].num = data[1]; // 目标制定
+          list[2].num = data[2]; // 目标确认
+          list[3].num = data[3]; // 执行中
+          list[4].num = data[4]; // 结果值录入
+          list[5].num = data[5]; // 评分
+          list[6].num = data[9]; // 审批
+          list[7].num = data[11]; // 结束
+          theOf.complete = data[11]; // 已完成人数
+          theOf.theTotalNum = all; // 总人数
+          let rate=(theOf.complete / theOf.theTotalNum) * 100; // 进度条百分比
+          if(!isNaN(rate)){
+            this.rate = rate; // 进度条百分比
+          }
+
+          let other = res.data.data.other
+          //部门筛选
+          let department_list = other.department_list;
+          department_list.forEach(item => {
+            item.text = item.dep_name;
+            item.value = item.id;
+          });
+          department_list.unshift({ text: '全部部门', value: 0 });
+          this.department_list = department_list;
+          //等级筛选
+          let levels = other.levels;
+          if(levels.indexOf('无等级') == -1){
+            levels.push('无等级')
+          }
+          levels = levels.map(item => {
+            return { text: item, value: item };
+          });
+          levels.unshift({ text: '全部等级', value: '-' });
+          this.levels_list = levels;
+
+          let departMent = other.department;
+          this.deptMentList = departMent;
+
+
+          // 考核人数分析
+          let deptList = [];
+          let deptEchartsName = [];
+          let deptEchartsNum = [];
+          let employList = {};//暂没用
+          departMent.forEach(item => {
+            // echarts数据
+            deptEchartsName.push(item[0].dep_name);
+            deptEchartsNum.push(item.length);
+            // 列表
+            let arr = {};
+            arr.name = item[0].dep_name;
+            arr.tak = item.length;
+            arr.id = [item[0].id]
+
+            let employ = [];
+            item.forEach(arr => {
+              employ.push(arr.employee_id);
+            });
+            employList[item[0].dep_name] = employ;
+            deptList.push(arr);
+          });
+          this.statementperson = deptList;
+          this.employList = employList;
+          this.assPeopleFx = {
+            name: deptEchartsName, // Echarts部门分类
+            num: deptEchartsNum, // Echarts部门人数
+            key: 0 // 控制Echarts能否点击
+          };
+
+          let statistics = other.statistics;
+          // 结果分析
+          let theResultsOfName = [];
+          let theResultsOfNum = [];
+          let add = [];
+          let PieProps = 0;
+          for (let i in statistics) {
+            theResultsOfName.push(i == 'empty' ? '无等级' : i);
+            theResultsOfNum.push(statistics[i].length);
+            let empName = i == 'empty' ? '无等级' : i;
+            add.push({
+              name: empName + '   ' + statistics[i].length + '人',
+              value: statistics[i].length
+            });
+            PieProps += statistics[i].length;
+          }
+          this.PieProps = PieProps;
+          this.theResultsOfFx = {
+            name: theResultsOfName, // Echarts结果分析
+            num: theResultsOfNum, // Echarts结果分析人数
+            add: add,
+            key: 1 // 控制Echarts能否点击
+          };
+          let theResultsOfList = [];
+          res.data.data.employees.forEach(item =>{
+            let data = {
+                id: item.id,
+                name: item.name,
+                level: item.final_level == '' ? '无等级' : item.final_level,
+                point: item.final_point,
+                publicity:item.publicity,
+                departments: []
+            }
+            res.data.data.other.department.forEach(x =>{
+              let arr = x.filter(y => item.id == y.employee_id)
+              if(arr[0]){
+                data.departments.push(arr[0])
+              }
+            })
+            theResultsOfList.push(data)
+          })
+          theResultsOfList.sort(function(a, b) {
+            if (Number(a.point) < Number(b.point)) {
+              return 1;
+            } else {
+              return -1;
+            }
+          });
+          this.statementResult = theResultsOfList;
+          this.allStatementResult = theResultsOfList;
+          console.log(this.theResultsOfFx)
+          this.$nextTick(() => {
+            if (this.active == 0) {
+              this.statmentAnalysesPie(this.theResultsOfFx);
+            } else {
+              this.statmentAnalysesBar(this.assPeopleFx);
+            }
+          });
+
+        }
+      })
+    },
+
+    statmentAnalysesPie(item) {
+      let colors = ['rgb(38, 162, 255)', '#f36f2a', '#fecb09', '#00b6bd', '#e85d53', '#fecb09'];
+      let legendDataLeng = item.add.length;
+      if (legendDataLeng > colors.length) {
+        let colorsLeng = colors.length;
+        for (let i = 0; i <= legendDataLeng - colorsLeng; i++) {
+          colors.push('rgb(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ')');
+        }
+      }
+      const chart = this.$refs.statmentAnalysePie;
+      if (chart) {
+        const myChart = this.$echarts.init(chart);
+        const option = {
+          legend: [
+            {
+              type: 'scroll',
+              orient: 'vertical',
+              icon: 'square',
+              left: '55%',
+              align: 'left',
+              top: 'center',
+              itemGap: 20,
+              itemWidth: 5, // 图形宽度。
+              itemHeight: 5, // 图形高度。
+              // bottom:'50%',
+              textStyle: {
+                fontSize: 14,
+                color: 'rgb(48, 49, 51)'
+              }
+              // data: Name
+            }
+          ],
+          color: colors,
+          emphasis: {
+            scale: true,
+            scaleSize: 10,
+            label: {
+              formatter: '总人数',
+              show: true,
+              fontSize: '20'
+            }
+          },
+          series: [
+            {
+              type: 'pie',
+              radius: ['43%', '53%'],
+              center: ['30%', '50%'],
+              avoidLabelOverlap: false,
+              itemStyle: {
+                borderRadius: 10,
+                borderColor: '#fff',
+                borderWidth: 2
+              },
+              label: {
+                show: false,
+                position: 'center'
+              },
+              labelLine: {
+                show: false
+              },
+              data: item.add
+            }
+          ]
+        };
+        myChart.setOption(option);
+        setTimeout(() => {
+          myChart.resize();
+        }, 200);
+      }
+    },
+    statmentAnalysesBar(item) {
+      let Name = [];
+      let Num = [];
+      item.name.forEach((arr, att) => {
+        if (att < 100) {
+          Name.push(arr);
+        }
+      });
+      item.num.forEach((arr, att) => {
+        if (att < 100) {
+          Num.push(arr);
+        }
+      });
+      // 根据数据的多少控制滚动条的初始长度
+      let scrollBarWid = 100; // 滚动条宽度
+      let dataZoomshow = false; // 是否显示滚动条
+      let gridBottom = '10%'; // 柱状图整体偏移量
+      let scrollBar = Math.round(Name.length / 4);
+      if (scrollBar > 0) {
+        scrollBarWid = scrollBarWid / scrollBar;
+      }
+      dataZoomshow = scrollBar > 1;
+      gridBottom = dataZoomshow ? '20%' : '10%';
+      if (scrollBarWid <= 5) {
+        scrollBarWid = 5;
+      }
+
+      const chart = this.$refs.statmentAnalysebar;
+      if (chart) {
+        const myChart = this.$echarts.init(chart);
+        myChart.off('click'); // 取消点击,避免多次点击
+        const option = {
+          tooltip: {
+            trigger: 'axis',
+            formatter: params => {
+              var htmlStr = '<div>';
+              for (let i in params) {
+                htmlStr += '<span>' + params[i].name + ':</span>';
+                htmlStr += '<span style="margin:0 5px 0 3px;">' + params[i].value + '人</span><br>';
+              }
+              htmlStr += '</div>';
+              return htmlStr;
+            }
+          },
+          grid: {
+            top: '10%',
+            // "left": "0%",
+            bottom: gridBottom
+            // "right": "0%",
+            // "containLabel": true
+          },
+          color: ['#26A2FF'],
+          xAxis: {
+            type: 'category',
+            data: Name, // x轴数据
+            axisPointer: {
+              type: 'shadow'
+            },
+            axisLabel: {
+              // interval: 'auto', // 横轴信息全部显示
+              interval: 0, // 横轴信息全部显示
+              // rotate:-30,//-30度角倾斜显示
+
+              formatter: function(value) {
+                var res = value;
+                if (res.length > 5) {
+                  res = res.substring(0, 4) + '..';
+                }
+                return res;
+              }
+            },
+            axisLine: {
+              // 去掉X轴线
+              show: true
+            },
+            axisTick: {
+              // 去掉X轴刻度
+              show: false
+            },
+            axisLine: {
+              // 这是x轴文字颜色
+              lineStyle: {
+                color: '#adadad'
+              }
+            }
+          },
+          yAxis: {
+            minInterval: 1,
+            type: 'value',
+            axisLabel: {
+              formatter: '{value}'
+            },
+            axisLine: {
+              // 去掉Y轴线
+              show: false
+            },
+            axisTick: {
+              // 去掉Y轴刻度
+              show: false
+            },
+            splitLine: {
+              // 网格线
+              lineStyle: {
+                type: 'dashed', // 设置网格线类型 dotted:虚线   solid:实线
+                color: ['#dcdcdc'] // 颜色
+              },
+              show: true // 隐藏或显示
+            }
+          },
+          dataZoom: [
+            {
+              show: dataZoomshow, // 是否展示滚动条
+              start: scrollBarWid, // 滚动条宽度
+              end: 0, // 滚动条起始位置
+              top: '90%', // 滚动条位置
+              height: 20, // 滚动条高度
+              zoomLock: true // 固定滚动条
+            }
+          ],
+          series: [
+            {
+              data: Num, // y轴数据
+              type: 'bar',
+              barWidth: 25, // 柱图宽度
+              barGap: '0%', // 柱图间距
+              itemStyle: {
+                color: new this.$echarts.graphic.LinearGradient(
+                  0,
+                  0,
+                  0,
+                  1, // 4个参数用于配置渐变色的起止位置, 这4个参数依次对应右/下/左/上四个方位. 而0 0 0 1则代表渐变色从正上方开始
+                  [{ offset: 0, color: '#4ECFFF' }, { offset: 1, color: '#26A2FF' }] // 数组, 用于配置颜色的渐变过程. 每一项为一个对象, 包含offset和color两个参数. offset的范围是0 ~ 1, 用于表示位置
+                )
+              }
+            }
+          ]
+        };
+        myChart.setOption(option);
+        if (item.key == 0) {
+          myChart.on('click', params => {
+            // 点击事件
+            let deptarr = []
+            this.department_list.forEach(item =>{
+              if(item.dep_name == params.name){
+                deptarr.push(item.id)
+              }
+            })
+            let data = {
+              paths: 'statdeEcharts',
+              dept_o: {
+                name: params.name,
+                tak: params.value,
+                id: deptarr
+              },
+              asslist: JSON.stringify(this.selectPftiData),
+              index: 0,
+            }
+            this.$setCache('statement_details',data)
+            this.$router.push({name: 'statement_details'});
+          });
+        }
+        setTimeout(() => {
+          myChart.resize();
+        }, 200);
+      }
+    },
+    statementTIme() {
+      this.pullonThePanel = true;
+      this.$nextTick(() => {
+        this.theEchoVanPicker();
+      });
+    },
+    cellDept(item) {
+      let data = {
+        paths: 'statdeEcharts',
+        dept_o: item,
+        asslist: JSON.stringify(this.selectPftiData),
+        index: 0,
+      }
+      this.$setCache('statement_details',data)
+      this.$router.push({
+        name: 'statement_details'
+      });
+    },
+    wordhelp() {
+      // 帮助
+      console.log('帮助');
+    }
+  },
+  created() {
+    this.columnList();
+  }
+};
+</script>
+
+<style scoped lang="less">
+.selectItem {
+  margin-top: 0.2rem;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.32rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+header {
+  .selector {
+    z-index: 1;
+    display: flex;
+    justify-content: center;
+    width: 100%;
+    height: 0.8rem;
+    line-height: 0.8rem;
+    background-color: #fff;
+    text-align: center;
+    font-size: 0.28rem;
+    i {
+      margin: 0.23rem 0 0 0.1rem;
+      color: #c3c3c3;
+    }
+    span {
+      max-width: 3.5rem;
+      overflow: hidden;
+    }
+  }
+}
+.all {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+  .statementHead {
+    width: 100%;
+    text-align: center;
+    // padding-top: 0.35rem;
+    background-color: #fff;
+    .statementpropnum {
+      background-color: #f5f7fa;
+      padding: 0.3rem 0 0.1rem;
+      .propnumrel1 {
+        /deep/ .van-progress__pivot {
+          margin-left: -0.11rem;
+        }
+      }
+      .propnumrel {
+        position: relative;
+        padding: 0 0.15rem;
+        /deep/ .van-progress {
+          border-radius: 0.5rem;
+          .van-progress__portion {
+            border-radius: 0.14rem;
+            .van-progress__pivot {
+              border-radius: 50%;
+              min-width: 0.33rem !important;
+              height: 0.33rem;
+              right: 0;
+              // margin-left: -.11rem;
+            }
+          }
+        }
+        .propnumcol {
+          position: absolute;
+          top: 0;
+          right: 0.4rem;
+          font-size: 0.25rem;
+          color: #fff;
+        }
+        .numelzi {
+          font-size: 0.26rem;
+          margin: 0.25rem 0;
+          .numelzh {
+            color: #000000;
+          }
+          .numelzl {
+            color: #0597ff;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            i {
+              margin: 0.06rem 0 0 0.02rem;
+            }
+          }
+        }
+      }
+    }
+    .circle {
+      margin-top: 0.7rem;
+      .circletit {
+        font-size: 0.24rem;
+        color: #6f6f6f;
+      }
+      .circleclic {
+        color: #4ba0f1;
+        .circleclics1 {
+          font-size: 0.42rem;
+          display: inline-block;
+          margin: 0.1rem 0;
+        }
+        .circleclics2 {
+          font-size: 0.25rem;
+          display: flex;
+          justify-content: center;
+          i {
+            margin: 0.06rem 0 0 0.02rem;
+          }
+        }
+      }
+    }
+
+    .statementHnum {
+      padding: 0.2rem;
+      padding-bottom: 0rem;
+      .Hnumvfor {
+        width: 22.8%;
+        position: relative;
+        background-color: #ECF5FF;
+        border-radius: 3px;
+        text-align: left;
+        padding: 0.1rem 0.2rem;
+        padding-right: 0rem;
+        box-sizing: border-box;
+        margin-bottom: 0.2rem;
+        .smHnLnum {
+          font-size: 0.42rem;
+          color: #00a1ff;
+        }
+        .smHnLtit {
+          font-size: 0.26rem;
+          color: #8a8a8a;
+        }
+      }
+    }
+  }
+  .statementFoot {
+    background-color: #fff;
+    margin-top: 0.2rem;
+    .statmentperson {
+      padding: 0.25rem 0.25rem 0.25rem 0;
+      margin: 0 0 0 0.3rem;
+      font-size: 0.32rem;
+    }
+  }
+}
+.takI {
+  font-size: 0.27rem;
+  color: #f7b461;
+  i {
+    margin: 0.1rem 0.05rem 0 0;
+  }
+}
+.statmentAnalysePie {
+  position: relative;
+  .PiePropNum {
+    width: 1.5rem;
+    text-align: center;
+    position: absolute;
+    left: 20%;
+    top: 42%;
+    font-size: 0.3rem;
+  }
+}
+</style>

+ 816 - 0
src/performance-07-19/view/navhome/statement.vue

@@ -0,0 +1,816 @@
+<template>
+  <div style="height: 100%;" :class="{ bg_fff: skeletonLoad }">
+    <van-nav-bar title="过程跟踪" left-text="返回" left-arrow @click-left="$route_back">
+      <div slot="right" @click="isShowPopup = true" style="color: #fff;">筛选<van-icon name="list-switch" /></div>
+    </van-nav-bar>
+
+    <VanSkeleton :skeLoad="skeletonLoad" v-if="isYou">
+      <template>
+        <header>
+          <div style="border-bottom: 1px solid #f1f1f1;" class="selector flex-box-ce flex-center-center fontColorC">
+            <icon name="YMPicker_item_icon" style="margin-right: 6px; width: 0.3rem; height: 0.3rem;" class="fontColorC"></icon>
+            <div v-show='cycleId == "4"' style="margin-right: 6px;">月度</div>
+            <div v-show='cycleId == "3"' style="margin-right: 6px;">季度</div>
+            <div v-show='cycleId == "2"' style="margin-right: 6px;">半年度</div>
+            <div v-show='cycleId == "1"' style="margin-right: 6px;">年度</div>
+            <div v-show='cycleId !== "0"'>{{ yearId }}年</div>
+            <div v-show='cycleId == "4"' style="margin: 0 6px;">{{ monthId }}月</div>
+            <div v-show='cycleId == "3"' style="margin: 0 6px;">第{{ quarterId }}季度</div>
+            <div v-show='cycleId == "2"' style="margin: 0 6px;">
+              {{ halfYearId == 1 ? "上半年" : "下半年" }}
+            </div>
+            <div v-show='cycleId == "0"' style="margin: 0 6px;">
+              {{ timeStr }}
+            </div>
+          </div>
+        </header>
+
+        <scroller ref="me_scroller" class="all">
+          <div style="padding-bottom: 1.5rem;">
+            <div class="statementHead">
+              <div class="statementpropnum">
+                <div class="propnumrel" :class="{ propnumrel1: theProgressOf.complete != 0 }">
+                  <van-progress
+                    :percentage="rate"
+                    stroke-width="16"
+                    pivot-text="''"
+                    :show-pivot="theProgressOf.complete != theProgressOf.theTotalNum"
+                    pivot-color="#FFF"
+                    track-color="#26a2ff"
+                    color="rgb(255, 173, 103)"
+                  />
+                  <div class="propnumcol"></div>
+                  <div class="flex-box flex-d-center numelzi">
+                    <span class="numelzh">
+                      考核进度:
+                      <span style="color: rgb(255, 173, 103);">{{ theProgressOf.complete }}人</span>
+                      /
+                      <span style="color: #26a2ff;">{{ theProgressOf.theTotalNum }}人</span>
+                    </span>
+                  </div>
+                </div>
+              </div>
+              <div class="statementHnum flex-box-ce flex-d-wrap flex-d-center">
+
+                <!-- <div v-for="(item, index) in generalizeList" class="Hnumvfor" :key="index">
+                  <span class="smHnLtit">{{ item.name }}</span>
+                  <br />
+                  <span class="smHnLtit"></span>
+                  <br />
+                  <span class="smHnLnum">{{ item.val }}</span>
+                </div> -->
+
+                <div v-for="(item, index) in gradeLevels" class="Hnumvfor" :key="index">
+                  <span class="smHnLtit">{{ item.name }}</span>
+                  <br />
+                  <span class="smHnLtit">({{ item.min }} ~ {{ item.max }})</span>
+                  <br />
+                  <span class="smHnLnum">{{ recordList.filter(user => user.levelName === item.name).length }}</span>
+                </div>
+              </div>
+            </div>
+            <div class="statementFoot">
+
+              <div>
+                <div>
+                  <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+                  <div class="flex-box-ce">
+                    <div class="selectItem flex-2 font-flex-word" @click="showDept = true">
+                      <span>{{ deptName }}</span>
+                      <van-icon name="arrow-down" />
+                    </div>
+                  </div>
+                  <ol v-if="filterUsers && filterUsers.length > 0">
+                    <li @click="openDetail(item)" v-for="(item, index) in filterUsers" :key="index" class="flex-ce-box flex-d-center statmentperson" :style="index != 0 ? 'border-top: 0.02rem solid #e6e6e6;' : ''">
+
+                      <div class="flex-1 flex-box" style="align-items: center; justify-content: space-between;">
+
+                        <div class="flex-box-ce flex-1">
+                          <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" fontSize="0.15" width="0.63rem" height="0.63rem" style="margin-top:.08rem;"></userImage>
+                          <div style="padding-left:.2rem;">
+                            <span style="font-size:.3rem;">{{ item.userInfo.name }}</span>
+                            <br />
+                            <span class="font-flex-word" style="width: 3.8rem;display:inline-block;" v-if="item.dept_list && item.dept_list.length > 0">
+                              <span style="font-size:.25rem;" v-for="(arr, att) in item.dept_list" :key="att">
+                                {{ arr.dept_name }}
+                                <span v-if="item.dept_list.length - att > 1">,</span>
+                              </span>
+                            </span>
+                          </div>
+                        </div>
+                        <div style="display: flex; align-items: center; flex-direction: column;">
+                          <div v-if="item.status == 0" class="review-status">进行中</div>
+                          <div v-if="item.status == 1" class="review-status" style="background-color: #FF9600;">已结束</div>
+                          <div style="display: flex; align-items: center; white-wrap: no-wrap; font-size:.26rem; text-align:center; overflow: hidden;">
+
+                            <span>{{ item.score == undefined || item.score == null || item.score == ''  ? '-' : item.score }}</span>
+                            /
+                            <span style="color:#ffad67;">{{ item.levelName ? item.levelName : '--'}}</span>
+                          </div>
+                        </div>
+                      </div>
+
+                    </li>
+                  </ol>
+                  <noData v-else content="无考核记录"></noData>
+                </div>
+              </div>
+            </div>
+          </div>
+        </scroller>
+      </template>
+    </VanSkeleton>
+    <noData content="无考核记录" v-else></noData>
+
+
+
+    <!-- 部门搜索 -->
+    <van-dialog v-model="showDept"width="300" confirm-button-text="确定" @confirm="handleConfirm" @cancel="handleCancel" :show-confirm-button="true" closeOnClickOverlay>
+       <div style="height: 8rem;overflow: auto; " class="scroll-bar">
+         <div class="dept-list">
+           <div class="dept-item flex-box-ce" v-for="(item, index) in department_list" :key="index">
+             <van-checkbox shape="square" v-model="item.select" style="margin-right: 0.16rem;"></van-checkbox>
+             <div class="dept-item-name">{{ item.dept_name }}</div>
+           </div>
+         </div>
+       </div>
+    </van-dialog>
+
+
+
+    <van-popup v-model="isShowPopup" position="right" style="height: 100%; left: 15%;">
+      <div style="position: relative;height: 100%;">
+        <div style="border-bottom: 1px solid #f1f1f1;font-size: 16px;font-weight: 700;height: 0.92rem;line-height: 0.92rem;padding: 0 0.2rem;">高级筛选</div>
+
+        <div style="padding: 0.1rem;">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">周期类型</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in cycleOptions" :key="index" :class="cycleId == item.id ? 'searchActive' : ''" @click="cycleId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId !== '0'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">年度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in yearOptions" :key="index" :class="yearId == item.id ? 'searchActive' : ''" @click="yearId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '2'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">半年度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in halfYearOptions" :key="index" :class="halfYearId == item.id ? 'searchActive' : ''" @click="halfYearId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '3'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">季度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in quarterOptions" :key="index" :class="quarterId == item.id ? 'searchActive' : ''" @click="quarterId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '4'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">月度</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" v-for="(item, index) in monthOptions" :key="index" :class="monthId == item.id ? 'searchActive' : ''" @click="monthId = item.id">
+                {{ item.name }}
+              </div>
+            </div>
+        </div>
+
+        <div style="padding: 0.1rem;" v-show="cycleId == '0'">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">自定义时间</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <span @click="calendarOpen()">{{ timeStr }}</span>
+            </div>
+        </div>
+
+        <div style="position: fixed;bottom: 0.2rem;left: 0.2rem;right: 0.2rem;">
+          <div class="search-btn" @click="doSearch()">确认</div>
+        </div>
+      </div>
+    </van-popup>
+
+
+
+
+    <!-- 日期选择框 -->
+    <van-calendar
+      v-model="showCalendar"
+      type="range"
+      :allow-same-day="true"
+      :min-date="minDate"
+      :max-date="maxDate"
+      :default-date="timeScope"
+      :show-confirm="false"
+      color="#26A2FF"
+      @close="calendarClose"
+      @confirm="calendarConfirm"
+    >
+      <template v-slot:title>
+        <van-row>
+          <van-col span="20">
+            <van-row type="flex" justify="space-between" style="height: 1rem;">
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeThisWeek">本周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="success" size="medium" @click="timeScopeLastWeek">上周</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeThisMoth">本月</van-tag>
+              </van-col>
+              <van-col span="6" style="text-align: center; align-self: center;">
+                <van-tag type="primary" size="medium" @click="timeScopeLastMonth">上月</van-tag>
+              </van-col>
+            </van-row>
+          </van-col>
+        </van-row>
+      </template>
+    </van-calendar>
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import VanSkeleton from '@/performance/components/public/VanSkeleton';
+import { Picker, ActionSheet, Circle, Tab, Tabs, Skeleton, DropdownMenu, DropdownItem, Progress, Calendar } from 'vant';
+import moment from "moment/moment";
+import { _debounce } from '@/utils/auth';
+
+Vue.use(Picker)
+  .use(ActionSheet)
+  .use(Circle)
+  .use(Tab)
+  .use(Tabs)
+  .use(Skeleton)
+  .use(DropdownMenu)
+  .use(DropdownItem)
+  .use(Progress)
+  .use(Calendar);
+export default {
+  data() {
+
+    let startDate = new Date();
+    startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * 7);
+    startDate = moment(startDate).format('YYYY-MM-DD');
+    let endDate = moment().format('YYYY-MM-DD');
+
+    let today = new Date();
+    let minDate = new Date();
+    minDate.setTime(today.getTime() - 3600 * 1000 * 24 * 30 * 6);
+    let maxDate = new Date(today.getFullYear(), today.getMonth(), 1);
+    maxDate.setMonth(maxDate.getMonth() + 1);
+    maxDate.setDate(0);
+
+
+    return {
+      skeletonLoad: true, //
+      isShowPopup: false,
+      timeStr: "请选择时间",
+      showCalendar: false,
+
+      generalizeList: [
+        { name: '考核人数', val: 0, color: '#FF9600' },
+        { name: '已结束', val: 0, color: '#409EFF' },
+        { name: '进行中', val: 0, color: '#67c23a' },
+      ],
+
+      minDate: minDate,
+      maxDate: maxDate,
+      timeScope: [new Date(startDate), new Date(endDate)],
+
+      cycleId: '4',
+      cycleOptions: [
+        { name: "月度", text: "月度", value: '4', id: '4' },
+        { name: "季度", text: "季度", value: '3', id: '3' },
+        { name: "半年度", text: "半年度", value: '2', id: '2' },
+        { name: "年度", text: "年度", value: '1', id: '1' },
+        { name: "自定义", text: "自定义", value: '0', id: '0' }
+      ],
+
+      yearId: '2025',
+      yearOptions: [
+        { name: "2020", text: "2020", value: '2020', id: '2020' },
+        { name: "2021", text: "2021", value: '2021', id: '2021' },
+        { name: "2022", text: "2022", value: '2022', id: '2022' },
+        { name: "2023", text: "2023", value: '2023', id: '2023' },
+        { name: "2024", text: "2024", value: '2024', id: '2024' },
+        { name: "2025", text: "2025", value: '2025', id: '2025' },
+        { name: "2026", text: "2026", value: '2026', id: '2026' },
+        { name: "2027", text: "2027", value: '2027', id: '2027' },
+        { name: "2028", text: "2028", value: '2028', id: '2028' },
+        { name: "2029", text: "2029", value: '2029', id: '2029' },
+        { name: "2030", text: "2030", value: '2030', id: '2030' }
+      ],
+
+      halfYearId: '1',
+      halfYearOptions: [
+        { name: "上半年", text: "上半年", id: '1' },
+        { name: "下半年", text: "上半年", id: '2' }
+      ],
+
+      quarterId: '1',
+      quarterOptions: [
+        {name: "第一季度", text: "第一季度", id: '1'},
+        {name: "第二季度", text: "第二季度", id: '2'},
+        {name: "第三季度", text: "第三季度", id: '3'},
+        {name: "第四季度", text: "第四季度", id: '4'},
+      ],
+
+      monthId: '1',
+      monthOptions: [
+        {name: "一月", text: "一月", id: '1'},
+        {name: "二月", text: "二月", id: '2'},
+        {name: "三月", text: "三月", id: '3'},
+        {name: "四月", text: "四月", id: '4'},
+        {name: "五月", text: "五月", id: '5'},
+        {name: "六月", text: "六月", id: '6'},
+        {name: "七月", text: "七月", id: '7'},
+        {name: "八月", text: "八月", id: '8'},
+        {name: "九月", text: "九月", id: '9'},
+        {name: "十月", text: "十月", id: '10'},
+        {name: "十一月", text: "十一月", id: '11'},
+        {name: "十二月", text: "十二月", id: '12'}
+      ],
+
+      dateParameter: {
+        year: this.$moment().format('YYYY'),
+        cycle_type: 0,
+        dateId: 1,
+        name: '全部周期'
+      },
+
+      theProgressOf: {
+        complete: 0,
+        theTotalNum: 0
+      },
+      currentRate: 0,
+      rate: 0,
+      keyword: '',
+      deptName: '全部部门',
+      department_list: [],
+      showDept: false,
+      deptId: '',
+      recordList: [],
+      filterUsers: [],
+      userInfo: this.$userInfo(),
+      gradeLevels: [], // 全局等级配置
+      isYou: true,
+      params: {
+        cycleType: 1,
+        startDate: '',
+        endDate: '',
+        deptIds: '',
+        year: 2025
+      },
+
+    };
+  },
+  components: { VanSkeleton },
+
+
+
+  watch: {
+    timeStr() {
+      return moment(this.timeScope[0], 'YYYY-MM-DD') + "-" + moment(this.timeScope[1], 'YYYY-MM-DD')
+    }
+  },
+
+  methods: {
+
+    // 本周
+    timeScopeThisWeek(){
+      this.timeScope = [new Date(moment().startOf('week').format('YYYY-MM-DD')),new Date(moment().endOf('week').format('YYYY-MM-DD'))]
+      this.showCalendar= false
+    },
+    // 上周
+    timeScopeLastWeek(){
+      this.timeScope = [new Date(moment().subtract(1,'week').startOf('week').format('YYYY-MM-DD')),new Date(moment().subtract(1,'week').endOf('week').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+    // 本月
+    timeScopeThisMoth(){
+      this.timeScope = [new Date(moment().startOf('month').format('YYYY-MM-DD')),new Date(moment().endOf('month').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+    // 上周
+    timeScopeLastMonth(){
+      this.timeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
+      this.showCalendar = false
+    },
+
+
+    calendarOpen(){
+      this.showCalendar = true;
+    },
+
+    calendarClose(){
+      this.showCalendar = false;
+    },
+
+    calendarConfirm(event){
+      const [start,end] = event;
+      this.timeScope = [start, end];
+      this.showCalendar = false;
+    },
+
+
+    openDetail(item){
+      this.$router.push({ path: '/me', query: { reviewId: item.reviewId, employeeId: item.employeeId } });
+    },
+
+    // 搜索 - 关注的人
+    keyVal: _debounce(function() {
+      if(!this.keyword) this.filterUsers = this.recordList
+      // let filterUsers = []
+      if(this.recordList && this.recordList.length > 0) {
+        this.filterUsers = this.recordList.filter(item => item.employeeName.includes(this.keyword.trim()))
+      }
+    }),
+
+    handleConfirm() {
+      this.deptId = this.department_list.filter(item => item.select).map(item => item.dept_id).toString()
+      if(this.deptId && this.deptId.length > 0) {
+        this.deptName = ''
+        this.department_list.filter(item => item.select).forEach(dept => {
+          this.deptName += dept.dept_name + ","
+        })
+        this.deptName = this.deptName.substring(0, this.deptName.length - 1)
+      }else {
+        this.deptName = '全部部门'
+      }
+      this.showDept = false;
+      this.getData(true)
+      console.log(this.deptId)
+    },
+
+    handleCancel() {
+      this.showDept = false;
+    },
+
+
+
+    // 获取全局等级设置
+    async getAllLevelSet() {
+      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;//最大值
+      let colorList = ['#5F7294', '#08EEA1', '#f56c6c', '#0887EE', '#92EE08', '#f56c6c']
+      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 };//当不是第一个等级时,最小值为上一个的最大值
+              }
+              obj.color = colorList[index]
+              max = item.value;
+              gradeLevels.push(obj);
+          })
+          this.gradeLevels = gradeLevels
+          console.log("this.gradeLevels")
+          console.log(this.gradeLevels)
+        }
+    },
+
+    getData(byDept = false) {
+      let url = `/performance/statistics/reviews/${this.userInfo.site_id}`;
+      let params = {
+        cycleType: this.cycleId,
+        startDate: '',
+        endDate: '',
+        deptIds: this.deptId,
+        cycleValue: 7,
+        year: this.yearId
+      }
+
+      // 月度
+      if(this.cycleId == '4') params.cycleValue = this.monthId
+      // 季度
+      if(this.cycleId == '3') params.cycleValue = this.quarterId
+      // 半年度
+      if(this.cycleId == '2') params.cycleValue = this.halfYearId
+      // 年度,自定义
+      if(this.cycleId == '1' || this.cycleId == '0') {
+        delete params.cycleValue
+      }
+
+      this.$axiosUser("get", url, params).then(res => {
+        if (res.data.code == 1) {
+          let recordList = res.data.data.list;
+          if(recordList.length == 0) {
+            this.isYou = false
+            return false
+          } else {
+            this.isYou = true
+            let theOf = this.theProgressOf;
+            theOf.complete = recordList.filter(item => item.status == 1).length || 0 // 已完成人数
+            theOf.theTotalNum = res.data.data.total; // 总人数
+            let rate = (theOf.complete / theOf.theTotalNum) * 100; // 进度条百分比
+            if(!isNaN(rate)){
+              this.rate = rate; // 进度条百分比
+            }
+            this.deptName = '全部部门'
+            if(!byDept) this.department_list = []
+            recordList.forEach(item => {
+              item.userInfo = this.$getEmployeeMapItem(item.employeeId);
+              item.dept_list = this.$getEmployeeMapItem(item.employeeId).employee_detail.dept_list;
+              if(!byDept && item.dept_list && item.dept_list.length > 0) {
+                item.dept_list.forEach(dept => {
+                  // dept.text = dept.dept_name
+                  // dept.value = dept.id
+                  item.select = false
+                  this.department_list.push(dept)
+                })
+              }
+            })
+
+            this.generalizeList[0].val = recordList.length // 总人数
+            this.generalizeList[1].val = recordList.filter(item => item.status == 1).length // 已结束人数
+            this.generalizeList[2].val = recordList.filter(item => item.status == 0).length // 进行中人数
+
+          }
+          console.log("---------------------------------")
+          console.log(recordList)
+          console.log(this.department_list)
+          this.recordList = recordList
+          this.filterUsers = recordList
+          this.skeletonLoad = false
+        }
+      })
+
+    },
+
+
+
+    doSearch() {
+      console.log("选择周期");
+      this.isShowPopup = false;
+      this.getData()
+    },
+
+  },
+
+
+
+  async created() {
+    this.monthId = new Date().getMonth() + 1; // 默认当月
+    await this.getAllLevelSet();
+    await this.getData();
+  }
+};
+</script>
+
+<style scoped lang="less">
+
+/deep/ .van-calendar__header-subtitle {
+  width: 100%;
+  font-size: 0.28rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+
+.selectItem {
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.3rem;
+  color: #c3c3c3;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+header {
+  .selector {
+    z-index: 1;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 0.8rem;
+    line-height: 0.8rem;
+    background-color: #fff;
+    text-align: center;
+    font-size: 0.28rem;
+    i {
+      margin: 0 0 0 0.1rem;
+      color: #c3c3c3;
+    }
+    span {
+      max-width: 3.5rem;
+      overflow: hidden;
+    }
+  }
+}
+
+.all {
+  height: calc(100% - 1.92rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+  .statementHead {
+    width: 100%;
+    text-align: center;
+    // padding-top: 0.35rem;
+    background-color: #fff;
+    .statementpropnum {
+      background-color: #f5f7fa;
+      padding: 0.3rem 0 0.1rem;
+      .propnumrel1 {
+        /deep/ .van-progress__pivot {
+          margin-left: -0.11rem;
+        }
+      }
+      .propnumrel {
+        position: relative;
+        padding: 0 0.15rem;
+        /deep/ .van-progress {
+          border-radius: 0.5rem;
+          .van-progress__portion {
+            border-radius: 0.14rem;
+            .van-progress__pivot {
+              border-radius: 50%;
+              min-width: 0.33rem !important;
+              height: 0.33rem;
+              right: 0;
+              // margin-left: -.11rem;
+            }
+          }
+        }
+        .propnumcol {
+          position: absolute;
+          top: 0;
+          right: 0.4rem;
+          font-size: 0.25rem;
+          color: #fff;
+        }
+        .numelzi {
+          font-size: 0.26rem;
+          margin: 0.25rem 0;
+          .numelzh {
+            color: #000000;
+          }
+          .numelzl {
+            color: #0597ff;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            i {
+              margin: 0.06rem 0 0 0.02rem;
+            }
+          }
+        }
+      }
+    }
+    .circle {
+      margin-top: 0.7rem;
+      .circletit {
+        font-size: 0.24rem;
+        color: #6f6f6f;
+      }
+      .circleclic {
+        color: #4ba0f1;
+        .circleclics1 {
+          font-size: 0.42rem;
+          display: inline-block;
+          margin: 0.1rem 0;
+        }
+        .circleclics2 {
+          font-size: 0.25rem;
+          display: flex;
+          justify-content: center;
+          i {
+            margin: 0.06rem 0 0 0.02rem;
+          }
+        }
+      }
+    }
+
+    .statementHnum {
+      padding: 0.2rem;
+      padding-bottom: 0rem;
+      .Hnumvfor {
+        width: 22.8%;
+        position: relative;
+        background-color: #ECF5FF;
+        border-radius: 3px;
+        text-align: center;
+        padding: 0.1rem 0.2rem;
+        box-sizing: border-box;
+        margin-bottom: 0.2rem;
+        .smHnLnum {
+          font-size: 0.42rem;
+          color: #00a1ff;
+        }
+        .smHnLtit {
+          font-size: 0.26rem;
+          color: #8a8a8a;
+        }
+      }
+    }
+  }
+  .statementFoot {
+    background-color: #fff;
+    margin-top: 0.2rem;
+    .statmentperson {
+      padding: 0.25rem 0.2rem;
+      font-size: 0.32rem;
+      box-sizing: border-box;
+    }
+  }
+}
+
+.takI {
+  font-size: 0.27rem;
+  color: #f7b461;
+  i {
+    margin: 0.1rem 0.05rem 0 0;
+  }
+}
+
+.statmentAnalysePie {
+  position: relative;
+  .PiePropNum {
+    width: 1.5rem;
+    text-align: center;
+    position: absolute;
+    left: 20%;
+    top: 42%;
+    font-size: 0.3rem;
+  }
+}
+
+.review-status {
+  // padding: 0.01rem 0.1rem;
+  width: 1.2rem;
+  height: 0.4rem;
+  text-align: center;
+  line-height: 0.4rem;
+  color: #fff;
+  border-radius: 2px;
+  font-size: 0.26rem;
+  background-color: #67c23a;
+  margin-right: 0.14rem;
+  margin-bottom: 0.1rem;
+}
+
+
+.search-item {
+  padding: 0.06rem 0.1rem;
+  background-color: #F7F8FA;
+  color: #89919F;
+  width: 1.2rem;
+  text-align: center;
+  margin-right: 0.1rem;
+  margin-bottom: 0.2rem;
+  border-radius: 3px;
+  font-size: 0.3rem;
+}
+
+
+.searchActive{
+  color: #26A2FF;
+  background-color: #E9F0FD;
+}
+.search-btn{
+  background-color: #26A2FF;
+  color: #fff;
+  text-align: center;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  border-radius: 25px;
+}
+
+.dept-list {
+  padding: 0.2rem;
+  box-sizing: border-box;
+  .dept-item {
+    box-sizing: border-box;
+    padding-left: 0.3rem;
+    margin-bottom: 0.2rem;
+    &-name {
+      font-size: 0.28rem;
+      color: #89919F;
+    }
+  }
+}
+</style>

+ 782 - 0
src/performance-07-19/view/navhome/workbench.vue

@@ -0,0 +1,782 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar :title="$getRole(3) || $getRole(4) ? '我的' : '工作台'" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all" style="position: relative;">
+      <header class="workHeader">
+        <van-row>
+          <van-col span="12" @click="backlog" class="headcol">
+            <span class="headicon">
+              <van-icon name="certificate" size=".4rem" />
+              <span>待办事项</span>
+            </span>
+            <em v-if="informNum.commission > 0" class="cunt" :class="{ cunts: informNum.commission > 99 }">
+              <i v-if="informNum.commission < 100">{{ informNum.commission }}</i>
+              <i v-else>99+</i>
+            </em>
+          </van-col>
+          <van-col span="12" @click="notification" class="headcol">
+            <span class="headicon">
+              <van-icon name="chat-o" size=".4rem" />
+              <span>消息通知</span>
+            </span>
+            <em v-if="informNum.information > 0" class="cunt" :class="{ cunts: informNum.information > 99 }">
+              <i v-if="informNum.information < 100">{{ informNum.information }}</i>
+              <i v-else>99+</i>
+            </em>
+          </van-col>
+        </van-row>
+      </header>
+      <van-tabs v-model="typeIndex">
+        <van-tab :title="item.title" :name="item.value" v-for="(item, index) in titles" :key="index"></van-tab>
+      </van-tabs>
+      <template v-if="typeIndex=='1'||typeIndex=='2'">
+          <div class="flex-box-ce">
+            <div class="selectItem " @click="statementTIme" style="width: 4.8rem;">
+              <template v-if="selectGlKgpText">
+                <span>{{ selectGlKgpText }}</span>
+                <van-icon name="arrow-down" />
+              </template>
+            </div>
+            <div class="selectItem" style="width: 3.2rem;" @click="selectGl=true">
+              <span>{{ selectGlText }}</span>
+              <van-icon name="arrow-down" />
+            </div>
+          </div>
+          <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+          <div class="event-list__content">
+            <scroller ref="perScroller" :on-refresh="refresh_two" :on-infinite="infinite_two" noDataText="我也是有底线的" :list="glDataList">
+              <van-cell-group>
+                  <div class="flex-box-ce list-item flex-d-wrap"  v-for="(item, index) in glDataList" :key="index"  @click="openDetail(item)">
+                    <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" :img_url="item.userInfo.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                    <div class="flex-1" style="margin-left: 0.24rem;">
+                       <div style="margin-bottom: 0.1rem;">{{item.userInfo.name}}</div>
+                       <div class="fontColorC font-flex-word" style="font-size: 0.28rem;width: 3.5rem;" v-if="item.dept_list.length>0">
+                           <span v-for="item2 in item.dept_list" :key="item2.dept_id">{{ item2.dept_name }}</span>
+                       </div>
+                    </div>
+                    <div>
+                      <div  style="font-size: 0.28rem;margin-bottom: 0.1rem;" class="flex-box-end">
+                        <template v-if="typeIndex==1">
+                          <span  class="green" v-if="item.count_record">{{item.count_record}}条管理记录</span>
+                          <span  class="fontColorC" v-else>无管理记录</span>
+                        </template>
+                        <template v-else>
+                          <span v-if="item.status==0" class="orange">未到评分节点</span>
+                          <span v-if="item.status==1" class="blue">待我评分</span>
+                          <span v-if="item.status==2" class="green">我已评分</span>
+                          <span v-if="item.status==3" class="green">已被其他管理评分</span>
+                        </template>
+                      </div>
+                      <div class="flex-box-end">
+                        <template v-if="typeIndex==1">
+                           <van-button plain type="info" size="small" v-if="!item.has_finish" @click.stop="complete(item)">填写管理记录</van-button>
+                           <span v-else class="yellow">已归档</span>
+                        </template>
+                        <van-button plain type="info" size="small" v-else>查看详情</van-button>
+                      </div>
+                    </div>
+                    <div style="width: 100%;" v-if="typeIndex=='1'">
+                      <template v-if="item.action_update">
+                         <div v-if="returnStr(item.action_update).indexOf('今天')>=0" class="orange" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else-if="returnStr(item.action_update).indexOf('昨天')>=0" class="green" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else-if="returnStr(item.action_update).indexOf('前天')>=0" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                      </template>
+
+
+                    </div>
+                  </div>
+              </van-cell-group>
+              <van-empty description="暂无内容" v-if="glDataList.length == 0" />
+            </scroller>
+          </div>
+      </template>
+
+      <template v-else>
+        <span v-if="$getRole(1) || $getRole(2)">
+          <div class="selector" @click="selectPfTIme">
+            <span>{{ selectPftiText.label }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+          <div class="event-list__content2">
+            <scroller ref="perScroller" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="performanceList">
+              <van-cell-group>
+                <div
+                  v-for="(item, index) in performanceList"
+                  :key="index"
+                  class="performanceList workbench_list"
+                  :style="'z-index:' + (performanceList.length - index)"
+                  @click="$router.push({ name: 'workList_details', query: { bagId: item.id, bagName: item.name } })"
+                >
+                  <div>{{ item.name }}</div>
+                  <span class="iconColor">
+                    <van-icon name="underway-o" />
+                    {{ item.date }}
+                  </span>
+                  <span>
+                    <van-icon name="friends-o" />
+                    {{ item.employee_num }}人参与
+                  </span>
+                </div>
+              </van-cell-group>
+              <van-empty :description="'暂无' + (selectPftiText.value == 0 ? '' : selectPftiText.label) + '绩效考核数据'" v-if="performanceList.length == 0" />
+            </scroller>
+          </div>
+        </span>
+        <div :class="[$getRole(3) || $getRole(4) ? 'meAll' : '']" v-else>
+          <scroller ref="me_scroller" class="all" :on-refresh="refresh1">
+            <footer style="padding-bottom:1rem;">
+              <div style="height:.2rem;background-color:#f5f7fa;"></div>
+              <van-empty description="暂无绩效考核数据" v-if="meList.length == 0" />
+              <div
+                v-else
+                class="me_list performanceList"
+                v-for="(item, index) in meList"
+                :key="index"
+                :style="'z-index:' + (meList.length - index)"
+                @click="$router.push({ name: 'performanceDetails', query: { id: item.id, Tit: item.package_name } })"
+              >
+                <div class="me_list_img">
+                  <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                </div>
+                <div class="me_list_content">
+                  <div class="me_list_tit">{{ item.package_name }}</div>
+                  <span v-if="item.current_node == 'result' || !item.current_node" class="me_list_result">
+                    <span v-if="item.result">
+                      <span class="me_list_col">绩效结果:</span>
+                      {{ item.result }}
+                      <br />
+                    </span>
+                    <span v-if="item.grade">
+                      <span class="me_list_col">绩效等级:</span>
+                      {{ item.grade }}
+                      <br />
+                    </span>
+                    <span class="me_list_resultTit">考核结束</span>
+                  </span>
+                  <div v-else class="me_list_course">
+                    {{
+                      item.current_node == 'target'
+                        ? '目标制定'
+                        : item.current_node == 'confirm'
+                        ? '目标确定'
+                        : item.current_node == 'execution'
+                        ? '执行中'
+                        : item.current_node == 'result_value'
+                        ? '结果值录入'
+                        : item.current_node == 'score' || item.current_node == 'special_scorer'
+                        ? '评分'
+                        : item.current_node == 'review'
+                        ? '审批'
+                        : ''
+                    }}
+                  </div>
+                </div>
+              </div>
+            </footer>
+          </scroller>
+        </div>
+      </template>
+    </div>
+
+    <van-dialog v-model="selectpfdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectpradio">
+          <van-radio v-for="(item, index) in selectpfList" :key="index" :name="item.value" @click="clickpfTime(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.label }}</span>
+          </van-radio>
+      </van-radio-group>
+    </van-dialog>
+    <!-- 管理记录筛选 -->
+    <van-dialog v-model="selectGl" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectGlVal">
+        <div v-for="(item, index) in selectGlType" :key="index">
+          <van-radio :name="item.value" @click="clickGlConfirm(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.label }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="onCancel" value-key="name" @confirm="onConfirm" confirm-button-text="确定" />
+      </div>
+    </van-action-sheet>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import {Tab, Tabs,Search} from 'vant'
+import moment from 'moment';
+import { _debounce, _throttle } from '@/utils/auth';
+Vue.use(Tabs).use(Tab).use(Search);
+export default {
+  data() {
+    return {
+      informNum: { commission: 0, information: 0 }, // 待办事项消息数
+      selectpfdlg: false, // 选择时间弹窗开关
+      selectpfList: [
+        // 选择时间选项
+        { value: 0, label: '全部' },
+        { value: 2, label: '月度' },
+        { value: 3, label: '季度' },
+        { value: 4, label: '半年度' },
+        { value: 5, label: '年度' },
+        { value: 1, label: '天' },
+        { value: 6, label: '自定义' }
+      ],
+      titles:[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}],
+      // 列表
+      performanceList: [], // 绩效列表
+      assessData: {
+        cycle_type: 0, // 周期类型
+        keywords: '', // 搜索字
+        page: 1, // 当期页
+        page_size: 10, // 一页多少数据
+        is_manage_scope: 1
+      },
+      selectpradio: 0, // 选中的时间选项
+      selectPftiText: { value: 0, label: '全部' }, // 默认值
+      meList: [],
+
+      typeIndex:'1',
+      selectGl:false,
+      selectGlVal:0,
+      selectGlText:'全部',
+      selectGlType: [
+        // 选择时间选项
+        { value: 0, label: '全部' },
+        { value: 1, label: '我的下级' },
+        { value: 2, label: '我协助管理的' },
+      ],
+      pullonThePanel:false,
+      selectGlData: {}, // 当前选中项
+      selectGlKgpText:'',
+      columns: [], // 顶部选项
+      selectGlTheEcho:[],
+      keyword:'',
+      page:1,
+
+      //我评分的
+      glDataList:[{userInfo:{},dept_list:[]}],
+      isColumns:false,//是否请求完考核包列表
+
+      apList:[],
+      day: moment().format('YYYY-MM-DD')
+    };
+  },
+  created() {
+    if(this.$getRole(3)){
+      this.titles=[{title:'我的考核',value:'3'},{title:'我评分的',value:'2'},{title:'我管理的',value:'1'}];
+      this.typeIndex="3";
+    }else{
+      this.titles=[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}];
+    }
+  	this.doSthForSb(); // 代办
+  	this.cc(); // 抄送
+  },
+  mounted() {
+    this.assessData.page = 1;
+    this.assessData.cycle_type = 0;
+    // this.perScrollerFun();//请求 列表数据
+  },
+  activated() {
+  	this.doSthForSb(); // 代办
+  	this.cc(); // 抄送
+    this.perScrollerFun();//请求 列表数据
+  },
+  watch:{
+    typeIndex(val){
+      this.page=1;
+      this.selectGlVal=0;
+      this.selectGlText='全部';
+      this.keyword='';
+      if(this.columns.length>0){
+        this.selectGlData = this.columns[0].children[0]
+        this.selectGlKgpText = this.columns[0].children[0].name
+        this.selectGlTheEcho = [0, 0]
+      }
+      if(val=='1'){
+          this.selectGlType=[
+          { value: 0, label: '全部' },
+          { value: 1, label: '我的下级' },
+          { value: 2, label: '我协助管理的' },
+        ]
+        this.$nextTick(()=>{
+          this.getManagement();
+        })
+      }else if(val=='2'){
+        this.selectGlType=[
+          { value: 0, label: '全部' },
+          { value: 1, label: '我的下级' },
+          { value: 2, label: '我协助评分的' },
+        ]
+        this.$nextTick(()=>{
+          this.getScorerRecord();
+        })
+      }
+    }
+  },
+  methods: {
+    returnStr(time){
+      let date=`${time}000`
+      let res = moment(Number(date)).format('YYYY/MM/DD HH:mm');
+      return this.fnTime(res);
+    },
+    fnTime( time ){
+        let staer=time.slice(0,11);
+        let ptime = new Date(time).getTime()
+        const twentyFourHours = 24 * 60 * 60 * 1000;
+        const fortyEightHours = 24 * 60 * 60 * 1000 * 2;
+        const today = moment().format('YYYY/MM/DD');
+        const todayTime = new Date(today).getTime();
+        const yesterdayTime = new Date(todayTime - twentyFourHours).getTime();
+        const lastYesterdayTime = new Date(todayTime - fortyEightHours).getTime();
+
+        if( ptime >= todayTime ){
+            return '今天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < todayTime && yesterdayTime <= ptime ){
+            return '昨天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < yesterdayTime && lastYesterdayTime <= ptime ){
+            return '前天 '+time.split(' ')[1]+' 更新了执行计划';
+        }else if(this.dateSum(this.day,staer)>30){
+            return '近30天无计划更新';
+        } else{
+            return time+' 更新了执行计划';
+        }
+    },
+    dateSum(sDate1, sDate2){   //sDate1和sDate2是2008-12-13格式
+        var aDate, oDate1, oDate2, iDays
+        aDate = sDate1.split("-")
+        oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])   //转换为12-13-2008格式
+        aDate = sDate2.split("-")
+        oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
+        iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 /24)   //把相差的毫秒数转换为天数
+        return iDays
+    },
+    complete(item) {
+      this.employeeDet(item.record_id, (recordMemberIds) => {
+        let data={
+            know: 'admnin',
+            apList: this.apList,
+            packId: item.record_id,
+            assessID: item.employee_id,
+            recordMemberIds:recordMemberIds||[]
+        }
+        this.$setCache('actionplanList',data);
+        this.$router.push({
+          name: 'actionplanList'
+          // query: {
+          //   know: 'admnin',
+          //   apList: this.apList,
+          //   packId: item.record_id,
+          //   assessID: item.employee_id,
+          //   recordMemberIds:recordMemberIds||[],
+          // }
+        })
+        this.isTrack = true;
+      });
+    },
+    employeeDet(id,callBack) {
+      this.staffLoad = true;
+      this.$axiosUser('get', '/api/pro/per/package/employee/info', { id: id })
+        .then(res => {
+          let data = res.data.data;
+          this.apList = JSON.stringify(data.dimension);
+          callBack && callBack(data.record_member_ids);
+        })
+        .finally(() => {
+          this.staffLoad = false;
+        });
+    },
+    openDetail(item){
+      let data={
+        id: item.record_id,
+        Tit: item.package_name
+      }
+      this.$router.push({name:'performanceDetails', query:data});
+    },
+    // 下拉刷新
+    refresh_two(done) {
+      this.page = 1;
+      if(this.isColumns){
+         this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+      }else{
+        this.columnList(()=>{
+          this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+        });
+      }
+    },
+    // 上拉加载
+    infinite_two(done) {
+      this.page++;
+      this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+    },
+    //管理记录列表
+    getManagement(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/management_record', { package_id: this.selectGlData.id, range:this.selectGlVal, name: this.keyword, page: this.page, page_size: 10 }).then(res => {
+          let list = res.data.data.list;
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list=this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          if (this.page === 1) {
+            this.glDataList = list;
+          } else {
+            this.glDataList = this.glDataList.concat(list);
+          }
+          hasMore = list.length !== 10;
+        })
+        .finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    //我评分的
+    getScorerRecord(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/score_record', { package_id: this.selectGlData.id, range:this.selectGlVal, name: this.keyword, page: this.page, page_size: 10 }).then(res => {
+          let list = res.data.data.list;
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list=this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          if (this.page === 1) {
+            this.glDataList = list;
+          } else {
+            this.glDataList = this.glDataList.concat(list);
+          }
+          hasMore = list.length !== 10;
+        })
+        .finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    onCancel () { // 取消
+      this.pullonThePanel = false
+    },
+    statementTIme () {
+      if(!this.selectGlKgpText){
+        return false
+      }
+      this.pullonThePanel = true
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+    theEchoVanPicker () { // 回显
+      this.$refs.van_picker.setIndexes(this.selectGlTheEcho)
+    },
+    // 考核包搜索
+    onConfirm (data, list) { // 确认
+      this.selectGlTheEcho = list// 回显
+      this.selectGlData = this.columns[list[0]].children[list[1]]// 当前选中项
+      this.selectGlKgpText = data[data.length - 1]// 选中的name
+      this.pullDown();
+      this.pullonThePanel = false
+    },
+    // 搜索
+    keyVal: _debounce(function() {
+      this.pullDown();
+    }),
+    // 管理记录筛选确定
+    clickGlConfirm(item){
+      this.selectGlText=item.label;
+      this.pullDown();
+      this.selectGl=false;
+    },
+    pullDown(){
+      this.page=1;
+      setTimeout(() => {
+        this.$refs.perScroller.triggerPullToRefresh();
+      }, 50);
+    },
+    columnList (callback) { // 绩效包树
+      this.$axiosUser('get', '/api/pro/per/package/tree').then((res) => {
+        if (res.data.code == 1) {
+          let data = res.data.data
+          let list = []
+          data.forEach((item) => {
+            if (item.list.length > 0) {
+              list.push(item)
+              item.children = item.list
+            }
+          })
+          if (list.length > 0) {
+            this.selectGlData = list[0].children[0]
+            this.selectGlKgpText = list[0].children[0].name
+            this.selectGlTheEcho = [0, 0]
+            this.columns = list
+          }
+        }
+      }).finally(()=>{
+        this.isColumns=true;
+        callback && callback()
+      })
+    },
+    // 上拉刷新
+    refresh(done) {
+      this.assessData.page = 1;
+      this.assessBagList(done);
+    },
+    // 下拉加载
+    infinite(done) {
+      this.assessData.page++;
+      this.assessBagList(done);
+    },
+    // 点击选择时间选项
+    clickpfTime(val) {
+      this.selectPftiText = val;
+      this.assessData.page = 1;
+      this.assessData.cycle_type = val.value;
+      this.selectpfdlg = false;
+      this.perScrollerFun();
+    },
+    assessBagList(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/list', this.assessData)
+        .then(res => {
+          if (res.data.code == 1) {
+            const { list } = res.data.data;
+            if (this.assessData.page === 1) {
+              this.performanceList = list;
+            } else {
+              this.performanceList = this.performanceList.concat(list);
+            }
+            hasMore = list.length !== 10;
+          }
+        }).finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    selectPfTIme() {
+      this.selectpfdlg = true;
+    },
+    backlog() {
+      this.$router.push({ name: 'backlog' });
+      // 待办事项
+    },
+    notification() {
+      this.$router.push({ name: 'messageInform' });
+    },
+    perScrollerFun() {
+      setTimeout(() => {
+        this.$refs.perScroller.triggerPullToRefresh();
+      }, 50);
+    },
+    doSthForSb() {
+      // 代办数量
+      let params = {status: 0,page: 0};
+      let axios= this.$axiosUser('get', '/api/pro/per/package/msg/agency', params,'v2')
+      let axios2= this.$axiosUser('get', '/api/pro/per/package/plc/list', {page:1,page_size:1,status:0})
+      Promise.all([axios,axios2]).then(res => {
+          let total=res[0].data.data.total;
+          let total2=res[1].data.data.total;
+          this.informNum.commission = total+total2
+      })
+    },
+    cc() {
+      // 抄送
+      let params = {
+        type: '1,2',
+        status: 0, // 未处理
+        page: 0
+      };
+      this.$axiosUser('get', '/api/pro/per/package/msg/cc', params).then(res => {
+        if (res.data.code == 1) {
+          this.informNum.information = res.data.data.total;
+        }
+      });
+    },
+    refresh1(done) {
+      if (this.$getRole(3) || this.$getRole(4)) {
+        // 员工权限
+        this.myPerformanceList(done); // 请求我的绩效接口
+      }
+    },
+    myPerformanceList(callback) {
+      let params = {
+        employee_id: this.$userInfo().id
+      };
+      this.$axiosUser('get', '/api/pro/per/package/employee/list', params)
+        .then(res => {
+          if (res.data.code == 1) {
+            let data = res.data.data.list;
+            this.meList = data;
+          }
+        })
+        .finally(() => {
+          callback && callback();
+        });
+    }
+  },
+};
+</script>
+
+<style scoped lang="less">
+.list-item{
+  padding: 0.24rem 0.32rem;
+  font-size: 0.32rem;
+  border-bottom: 1px solid #f1f1f1;
+}
+
+.selectItem{
+  margin-top: 0.2rem;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.32rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+
+.workHeader {
+  background-color: #fff;
+  height: 1.1rem;
+  font-size: 0.31rem;
+  line-height: 1.2rem;
+  margin-bottom: 0.2rem;
+  .headcol {
+    position: relative;
+    .headicon {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+      i {
+        margin: 0.4rem 0.1rem 0 0;
+      }
+    }
+  }
+}
+
+.selector {
+  display: flex;
+  justify-content: center;
+  margin-top: 0.2rem;
+  width: 100%;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.32rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+.cunt {
+  background-color: #f15532;
+  text-align: center;
+  line-height: 0.39rem;
+  width: 0.4rem;
+  height: 0.4rem;
+  border-radius: 50%;
+  position: absolute;
+  top: 0.4rem;
+  left: 2.9rem;
+  color: #fff;
+  font-size: 0.26rem;
+  font-style: normal;
+}
+.cunt i {
+  font-style: normal;
+}
+.cunts {
+  // padding: 0 0.04rem !important;
+  // max-width: 0.8rem;
+  // overflow: hidden;
+  // text-overflow: ellipsis;
+  // white-space: nowrap;
+  width: auto !important;
+  padding: 0 .04rem 0 .08rem !important;
+  border-radius: .8rem !important;
+}
+
+.all {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+  // background-color: #f5f7fa;
+  // padding-bottom: .5rem;
+  // height: 100%;
+  & .event-list__content {
+    position: relative;
+    height: calc(100% - 4.3rem);
+    & .van-hairline--top-bottom:after,
+    .body_com .van-hairline-unset--top-bottom:after {
+      border: none;
+    }
+  }
+  & .event-list__content2 {
+    position: relative;
+    height: calc(100% - 3.2rem);
+    & .van-hairline--top-bottom:after,
+    .body_com .van-hairline-unset--top-bottom:after {
+      border: none;
+    }
+  }
+}
+
+.workbench_list {
+  padding: 0.3rem 0.6rem;
+  div {
+    font-size: 0.33rem;
+  }
+  span {
+    padding-top: 0.1rem;
+    color: #737373;
+    font-size: 0.25rem;
+    display: flex;
+    i {
+      margin: 0.06rem 0.05rem 0 0;
+      color: #f7b461;
+    }
+  }
+}
+
+.meAll {
+  height: calc(100% - 1rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+.me_list {
+  background-color: #fff;
+  display: flex;
+  padding: 12px 16px;
+  .me_list_content {
+    padding-left: 0.3rem;
+    .me_list_tit {
+      font-size: 0.33rem;
+    }
+    .me_list_result {
+      font-size: 0.3rem;
+      .me_list_col {
+        color: #adadad;
+      }
+      .me_list_resultTit {
+        display: inline-block;
+        padding-bottom: 0.18rem;
+        color: #3bdf9a;
+      }
+    }
+    .me_list_course {
+      display: inline-block;
+      padding-bottom: 0.18rem;
+      font-size: 0.28rem;
+      color: #ff9439;
+    }
+  }
+}
+</style>

+ 173 - 0
src/performance-07-19/view/navigation.vue

@@ -0,0 +1,173 @@
+<template>
+  <div>
+    <div class="user_index_scroller_com" :class="isIos? 'isIos':''"  v-show="!appNavJx">
+      <div class="height100p" v-if="active_index == 0" :class="{ hidden_right: active_index != 0 }"><Workbench/></div>
+      <div class="height100p" v-if="active_index == 1" :class="{ hidden_right: active_index != 1 }"><Statement></Statement></div>
+      <div class="height100p" v-if="active_index == 2" :class="{ hidden_right: active_index != 2 }"><Me></Me></div>
+      <!-- 导航 -->
+      <van-tabbar v-model="active_index" :class="isIos? 'padding-m':''" :fixed="false">
+        <van-tabbar-item>
+          <icon name="footer_nav_work" v-if="tabs != 0" class="footer_nav_work"></icon>
+          <icon name="footer_nav_work_press" v-if="tabs == 0" class="footer_nav_work_press active"></icon>
+          <span v-if="$getRole(3)||$getRole(4)">我的</span>
+          <span v-else>工作台</span>
+        </van-tabbar-item>
+        <van-tabbar-item v-show="statementif">
+          <icon name="statistics" v-if="tabs != 1" class="footer_nav_review"></icon>
+          <icon name="statistics_checked" v-if="tabs == 1" class="footer_nav_review active"></icon>
+          <span>报表</span>
+        </van-tabbar-item>
+        <van-tabbar-item v-show="$getRole(1)||$getRole(2)">
+          <icon name="footer_nav_me" v-if="tabs != 2" class="footer_nav_me"></icon>
+          <icon name="footer_nav_me_press" v-if="tabs == 2" class="footer_nav_me_press active"></icon>
+          <span>我的</span>
+        </van-tabbar-item>
+      </van-tabbar>
+    </div>
+    <div v-show="appNavJx" class="jxNav">
+      <img :src="'static/images/' + navList[navNew].image + '.png'" />
+      <van-button @click="navNew++" v-if="navNew < 1" type="primary" color="rgb(125 171 255)" block>下一步</van-button>
+      <van-button @click="appNavJx=false" v-else type="primary" color="rgb(125 171 255)" block>进入</van-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import Workbench from '@/performance/view/navhome/workbench'
+import Statement from '@/performance/view/navhome/statement'
+import Me from '@/performance/view/navhome/me'
+
+import Vue from 'vue'
+import { Overlay, Image as VanImage } from 'vant'
+Vue.use(Overlay).use(VanImage)
+export default {
+  data () {
+    return {
+      active_index: 0,
+      tabs: 0,
+      isIos: this.$getCache('iPhone'),
+      statementif: false,
+      appNavJx:false,
+      newNav: this.plusStoGet('newNav'),
+      navList: [{ image: 'newNav1' }, { image: 'newNav2' }],
+      navNew: 0
+    }
+  },
+  components: { Workbench, Statement, Me},
+  watch: {
+    active_index (val, old) {
+      this.tabs = val
+    },
+    appNavJx(val){
+      if(!val){
+         this.plusStoSet('newNav', 'true')
+      }
+    }
+  },
+  methods:{
+    plusStoGet(key) {
+      if (window.plus) {
+        return plus.storage.getItem(key);
+      } else {
+        return localStorage.getItem(key);
+      }
+    },
+    plusStoSet(key, val, fun = function() {}) {
+      if (window.plus) {
+        plus.storage.setItem(key, val);
+      } else {
+        localStorage.setItem(key, val);
+      }
+      fun();
+    },
+    setMent(){
+      // 报表显示隐藏
+      if (this.$userInfo().employee_detail.manage_dept_ids.length>0|| (this.$getRole(1) && this.$getPermis(16))) {
+        this.statementif = true
+      } else {
+        this.statementif = false
+      }
+      if (this.$getRole(3) || this.$getRole(2) || this.$getRole(1) && !this.$getPermis(16)) {
+        this.active_index = 0
+        this.tabs = 0
+      }
+      this.$nextTick(()=>{
+        if(this.$route.query.index){
+          this.active_index=this.$route.query.index
+        }
+      })
+    }
+  },
+  created () {
+    document.documentElement.style.backgroundColor = '#26A2FF';
+    if (window.plus) { // 下边横杠兼容
+      plus.navigator.setStatusBarStyle('light')
+    }
+    if (!this.newNav) {
+      this.appNavJx = true;
+    }
+    this.setMent();
+  },
+}
+</script>
+
+<style scoped lang="less">
+.jxNav {
+  width: 100%;
+  height: 100%;
+  img {
+    width: 100%;
+    margin-top: 50px;
+  }
+  button {
+    width: 90%;
+    margin: auto;
+    border-radius: 0.1rem;
+    position: fixed;
+    bottom: 0.2rem;
+    left: 5%;
+    z-index: 999;
+  }
+}
+.user_index_scroller_com {
+  height: calc(100% - 1rem);
+  position: relative;
+}
+/deep/ .isIos{
+  height: calc(100% - 1.4rem);
+}
+.padding-m{
+  padding-bottom: 0.4rem;
+}
+
+.hidden_right {
+  position: absolute;
+  top: -1000000px;
+  left: -100000px;
+}
+
+.height100p {
+  height: 100%;
+}
+
+.user_index_scroller_com /deep/ .van-tabbar-item {
+  text-align: center;
+  position: relative;
+}
+.user_index_scroller_com /deep/ .van-tabbar-item .svg-icon {
+  color: #606266;
+  height: 0.36rem;
+  margin-bottom: 0.08rem;
+}
+.user_index_scroller_com .footer_nav_add_press {
+  height: 0.8rem !important;
+}
+.user_index_scroller_com /deep/ .van-tabbar-item .active {
+  color: #238dfa;
+}
+.user_index_scroller_com /deep/ .van-tabbar-item span {
+  display: block;
+  font-size: 0.2rem;
+  margin-bottom: 0.08rem;
+}
+</style>

+ 363 - 0
src/performance-07-19/view/performanceHome - 副本 (2).vue

@@ -0,0 +1,363 @@
+<template>
+  <div class="all">
+    <header class="workHeader">
+      <van-grid :border="false" style="background-color: #fff;position: relative;" class="border-bottom">
+        <van-grid-item v-if="app.isShow" v-for="(app, index) in topMenuList" :dot="app.dot" :badge="app.badge" :key="app.code" @click="openUrl(app)" :text="app.code">
+          <template slot="icon">
+            <img :src="app.icon" style="-webkit-touch-callout: none;" />
+          </template>
+        </van-grid-item>
+      </van-grid>
+    </header>
+
+    <div class="my-attention-box" >
+      <div class="my-attention">
+        我关注的
+      </div>
+      <div class="flex-box-ce fontColorC" @click="goAttentionPage()">
+       <van-icon name="weapp-nav" style="padding-right: 5px;" />设置
+      </div>
+    </div>
+
+
+    <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+
+
+
+
+
+      <!-- <div class="list-box">
+        <div class="flex-box-ce flex-d-center">
+          <div class="add-task-title">
+            上次绩效
+          </div>
+          <div>
+            <span style="font-size: 0.3rem;color: #89919F;">全部</span>
+            <i class="van-icon van-icon-arrow van-cell__right-icon"></i>
+          </div>
+        </div>
+        <div class="flex-box-ce" style="margin: 0.2rem 0;">
+          <div>
+            <userImage class="about-me__avatar" :id="userInfo.id" :img_url="userInfo.img_url"  :user_name="userInfo.name"  fontSize="0.24"  width="0.8rem"  height="0.8rem"></userImage>
+          </div>
+          <div class="user-info">
+            <div>{{ userInfo.name }}</div>
+            <span v-for="item in dept_list" :key="item.dept_id">{{ item.dept_name }}&nbsp;</span>
+          </div>
+        </div>
+
+        <div>
+          <div>
+            考核等级: 优秀
+          </div>
+          <div>
+            考核评分: 99
+          </div>
+        </div>
+      </div> -->
+      <div class="scroller">
+        <scroller ref="perScroller" >
+          <van-cell-group>
+              <div class="flex-box-ce list-item flex-d-wrap"  v-for="(item, index) in glDataList" :key="index">
+                <userImage :id="item.id" :user_name="item.name" :img_url="item.imgUrl" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                <div class="flex-1" style="margin-left: 0.24rem;">
+                   <div style="margin-bottom: 0.1rem;">{{item.name}}</div>
+                   <div class="fontColorC font-flex-word" style="font-size: 0.28rem; width: 3.5rem;" v-if="item.departments && item.departments.length > 0">
+                       <span v-for="dept in item.departments" :key="dept.id">{{ dept.name }}</span>
+                   </div>
+                </div>
+
+                <div style="font-size: 0.28rem; margin-bottom: 0.1rem;" class="flex-box-end">
+                  <template>
+                    <van-button plain type="info" size="small" @click="goMorePage(item.id)">查看详情</van-button>
+                  </template>
+                </div>
+              </div>
+          </van-cell-group>
+          <van-empty description="暂无内容" v-if="glDataList.length == 0" />
+        </scroller>
+      </div>
+
+
+    <!-- 上次考核 -->
+    <div class="sidebar flex-box-ce">
+      <van-icon name="plus" size=".24rem" />
+      上次考核
+    </div>
+
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import {Tab, Tabs,Search} from 'vant'
+import moment from 'moment';
+import { _debounce, _throttle } from '@/utils/auth';
+Vue.use(Tabs).use(Tab).use(Search);
+export default {
+  data() {
+    return {
+      topMenuList:[
+        {code:"待办", icon:"static/images/daiban.png", url:'backlog', badge:0, isShow: true},
+        // {code:"通知", icon:"static/images/tongzhi.png",url:'messageInform',badge:0, isShow:true},
+        {code:"过程跟踪",icon:"static/images/guochenggenzong.png",url:'statement',isShow:this.$userInfo().employee_detail.manage_dept_ids.length>0||(this.$getRole(1) && this.$getPermis(16))},
+        {code:"我的绩效",icon:"static/images/wodejixiao.png",url:'me',isShow:this.$getRole(1)||this.$getRole(2)},
+        {code:"结果分析",icon:"static/images/jieguofenxi.png",url:'resultAnalysis', isShow:this.$getRole(1)||this.$getRole(2)},
+        {code:"组织考核",icon:"static/images/jixiaoduibi.png",url:'me',isShow:this.$getRole(1)||this.$getRole(2)},
+      ],
+
+      glDataList: [],
+
+      titles: [{ title:'我关注的', value: '1' }],
+      userInfo: this.$userInfo(),
+
+      typeIndex:'1',
+
+      keyword:'',
+      day: moment().format('YYYY-MM-DD'),
+
+    };
+  },
+
+
+  computed: {
+    dept_list() {
+      return this.userInfo && this.userInfo.employee_detail && this.userInfo.employee_detail.dept_list || []
+    }
+  },
+  created() {
+    // if(this.$getRole(3)){
+    //   this.titles=[{title:'我的考核',value:'3'},{title:'我评分的',value:'2'},{title:'我管理的',value:'1'}];
+    //   this.typeIndex="3";
+    // }else{
+    //   this.titles=[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}];
+    // }
+  	this.doSthForSb(); // 获取代办角标数量
+    this.getAttentionList();// 请求列表数据
+  	// this.cc(); // 抄送
+  },
+
+  activated() {
+  	this.doSthForSb(); // 获取代办角标数量
+  	// this.cc(); // 抄送
+    this.getAttentionList();//请求列表数据
+  },
+
+
+  methods: {
+    openUrl(item) {
+      this.$router.push({ name:item.url});
+    },
+
+    goAttentionPage() {
+      this.$router.push({ name: 'perAttentionList' })
+    },
+
+    goMorePage(employeeId) {
+      this.$router.push({ path: '/more', query: { employeeId } })
+    },
+
+
+    // 关注列表
+    getAttentionList(callback) {
+      this.$axiosUser('get', `/performance/follow/employees/${this.$userInfo().site_id}`, ).then(res => {
+        let list = res.data.data.list;
+        if(list && list.length > 0) {
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          console.log("关注用户列表")
+          console.log(list);
+          this.glDataList = list;
+        }
+
+      })
+    },
+
+    // 搜索 - 关注的人
+    keyVal: _debounce(function() {
+      console.log("搜索 - 关注的人")
+      // this.pullDown();
+    }),
+
+
+    doSthForSb() {
+
+      let url = `/performance/review/job/employee/app/${this.$userInfo().site_id}/${this.$userInfo().id}`
+      // 代办数量
+      let params = {
+        siteId: this.$userInfo().site_id,
+        employeeId: this.$userInfo().id,
+        page: 1,
+        pageSize: 1000,
+        type: 0
+      };
+      this.$axiosUser('get', url, params).then(res => {
+        this.topMenuList[0].badge = res.data.data.total || 0
+      })
+    },
+
+    cc() {
+      // 抄送
+      let params = {
+        type: '1,2',
+        status: 0, // 未处理
+        page: 0
+      };
+      this.$axiosUser('get', '/api/pro/per/package/msg/cc', params).then(res => {
+        if (res.data.code == 1) {
+          this.topMenuList[1].badge= res.data.data.total||'';
+        }
+      });
+    },
+
+
+  },
+};
+</script>
+
+<style scoped lang="less">
+
+.all {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  position: relative !important;
+
+  .workHeader /deep/ .van-grid-item {
+    margin-bottom: 0.2rem;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content {
+    padding: 0 !important;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__text {
+    font-size: 0.28rem;
+    color: #606266;
+    line-height: 0.44rem;
+    width: 1.4rem;
+    text-align: center;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  .workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__icon-wrapper img {
+    width: 1rem;
+    height: 1rem;
+    border-radius: 0.42rem;
+  }
+
+  .workHeader {
+    background-color: #fff;
+    font-size: 0.31rem;
+    padding-top: 0.4rem;
+    box-sizing: border-box;
+    .headcol {
+      position: relative;
+      .headicon {
+        width: 100%;
+        display: flex;
+        justify-content: center;
+        i {
+          margin: 0.4rem 0.1rem 0 0;
+        }
+      }
+    }
+  }
+
+
+
+
+
+  .my-attention-box {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 0.2rem;
+    padding: 0.2rem;
+    box-sizing: border-box;
+    background: #fff;
+    border-bottom: 1px solid #f1f1f1;
+    .my-attention {
+      flex: 1;
+      box-sizing: border-box;
+      background-color: #fff;
+      font-size: 0.3rem;
+      font-weight: 600;
+    }
+  }
+}
+
+
+
+
+
+
+
+.list-item {
+  padding: 0.24rem 0.32rem;
+  font-size: 0.32rem;
+  border-bottom: 1px solid #f1f1f1;
+}
+
+
+
+
+
+
+
+
+
+.list-box {
+  width: 96%;
+  padding: 0.24rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  box-sizing: border-box;
+  margin: 0.24rem auto;
+  .add-task-title {
+    font-weight: 600;
+    font-size: 0.32rem;
+  }
+
+  .user-info {
+    font-size: 0.28rem;
+    color: #999;
+    margin: 0 0 0 0.2rem;
+  }
+}
+
+.scroller {
+  height: 20rem !important;
+}
+
+.sidebar {
+  width: 2.2rem;
+  height: 0.5rem;
+  position: fixed;
+  right: 0px;
+  bottom: 2rem;
+  font-size: 0.28rem;
+  padding: 0.1rem 0.25rem;
+  border-top-left-radius: 0.05rem;
+  border-bottom-left-radius: 0.05rem;
+  display: flex;
+  color: #26a2ff;
+  box-sizing: border-box;
+  z-index: 999;
+  background-color: #ecf5ff;
+  i {
+    // margin: 0.05rem 0.15rem 0 0;
+    margin-right: 0.15rem;
+    color: #26a2ff;
+  }
+}
+
+
+</style>

+ 781 - 0
src/performance-07-19/view/performanceHome - 副本.vue

@@ -0,0 +1,781 @@
+<template>
+  <div>
+    <div class="all">
+      <header class="workHeader">
+        <van-grid :border="false" style="background-color: #fff;position: relative;" class="border-bottom">
+          <van-grid-item v-if="app.isShow" v-for="(app, index) in topMenuList" :dot="app.dot" :badge="app.badge" :key="app.code" @click="openUrl(app)" :text="app.code">
+            <template slot="icon">
+              <img :src="app.icon" style="-webkit-touch-callout: none;" />
+            </template>
+          </van-grid-item>
+        </van-grid>
+      </header>
+      <van-tabs v-model="typeIndex">
+        <van-tab :title="item.title" :name="item.value" v-for="(item, index) in titles" :key="index"></van-tab>
+      </van-tabs>
+      <template v-if="typeIndex=='1'||typeIndex=='2'">
+          <div class="flex-box-ce">
+            <div class="selectItem flex-box-ce flex-center-center" @click="statementTIme" style="width: 4.8rem;">
+              <template v-if="selectGlKgpText">
+                <span style="max-width: 4rem;" class="clamp">{{ selectGlKgpText }}</span>
+                <van-icon name="arrow-down" style="margin-top: 0;" />
+              </template>
+            </div>
+            <div class="selectItem" style="width: 3.2rem;" @click="selectGl=true">
+              <span>{{ selectGlText }}</span>
+              <van-icon name="arrow-down"/>
+            </div>
+          </div>
+          <van-search placeholder="请输入姓名" v-model="keyword" @input="keyVal()" />
+          <div class="event-list__content">
+            <scroller ref="perScroller" :on-refresh="refresh_two" :on-infinite="infinite_two" noDataText="我也是有底线的" :list="glDataList">
+              <van-cell-group>
+                  <div class="flex-box-ce list-item flex-d-wrap"  v-for="(item, index) in glDataList" :key="index"  @click="openDetail(item)">
+                    <userImage :id="item.userInfo.id" :user_name="item.userInfo.name" :img_url="item.userInfo.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                    <div class="flex-1" style="margin-left: 0.24rem;">
+                       <div style="margin-bottom: 0.1rem;">{{item.userInfo.name}}</div>
+                       <div class="fontColorC font-flex-word" style="font-size: 0.28rem;width: 3.5rem;" v-if="item.dept_list.length>0">
+                           <span v-for="item2 in item.dept_list" :key="item2.dept_id">{{ item2.dept_name }}</span>
+                       </div>
+                    </div>
+                    <div>
+                      <div  style="font-size: 0.28rem;margin-bottom: 0.1rem;" class="flex-box-end">
+                        <template v-if="typeIndex==1">
+                          <span  class="green" v-if="item.count_record">{{item.count_record}}条管理记录</span>
+                          <span  class="fontColorC" v-else>无管理记录</span>
+                        </template>
+                        <template v-else>
+                          <span v-if="item.status==0" class="orange">未到评分节点</span>
+                          <span v-if="item.status==1" class="blue">待我评分</span>
+                          <span v-if="item.status==2" class="green">我已评分</span>
+                          <span v-if="item.status==3" class="green">已被其他管理评分</span>
+                        </template>
+                      </div>
+                      <div class="flex-box-end">
+                        <template v-if="typeIndex==1">
+                           <van-button plain type="info" size="small" v-if="!item.has_finish" @click.stop="complete(item)">填写管理记录</van-button>
+                           <span v-else class="yellow">已归档</span>
+                        </template>
+                        <van-button plain type="info" size="small" v-else>查看详情</van-button>
+                      </div>
+                    </div>
+                    <div style="width: 100%;" v-if="typeIndex=='1'">
+                      <template v-if="item.action_update">
+                         <div v-if="returnStr(item.action_update).indexOf('今天')>=0" class="orange" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else-if="returnStr(item.action_update).indexOf('昨天')>=0" class="green" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else-if="returnStr(item.action_update).indexOf('前天')>=0" style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                         <div v-else style="font-size: 0.28rem;padding-left:1rem;padding-top: 0.24rem;" >{{returnStr(item.action_update)}}</div>
+                      </template>
+
+
+                    </div>
+                  </div>
+              </van-cell-group>
+              <van-empty description="暂无内容" v-if="glDataList.length == 0" />
+            </scroller>
+          </div>
+      </template>
+
+      <template v-else>
+        <span v-if="$getRole(1) || $getRole(2)">
+          <div class="selector" @click="selectPfTIme">
+            <span>{{ selectPftiText.label }}</span>
+            <van-icon name="arrow-down" />
+          </div>
+          <div class="event-list__content2">
+            <scroller ref="perScroller" :on-refresh="refresh" :on-infinite="infinite" noDataText="我也是有底线的" :list="performanceList">
+              <van-cell-group>
+                <div
+                  v-for="(item, index) in performanceList"
+                  :key="index"
+                  class="performanceList workbench_list"
+                  :style="'z-index:' + (performanceList.length - index)"
+                  @click="$router.push({ name: 'workList_details', query: { bagId: item.id, bagName: item.name } })"
+                >
+                  <div>{{ item.name }}</div>
+                  <span class="iconColor">
+                    <van-icon name="underway-o" />
+                    {{ item.date }}
+                  </span>
+<!--                  <span>
+                    <van-icon name="friends-o" />
+                    {{ item.employee_num }}人参与
+                  </span> -->
+                </div>
+              </van-cell-group>
+              <van-empty :description="'暂无' + (selectPftiText.value == 0 ? '' : selectPftiText.label) + '绩效考核数据'" v-if="performanceList.length == 0" />
+            </scroller>
+          </div>
+        </span>
+        <div :class="[$getRole(3) || $getRole(4) ? 'meAll' : '']" v-else>
+          <scroller ref="me_scroller" class="all" :on-refresh="refresh1">
+            <footer style="padding-bottom:1rem;">
+              <div style="height:.2rem;background-color:#f5f7fa;"></div>
+              <van-empty description="暂无绩效考核数据" v-if="meList.length == 0" />
+              <div
+                v-else
+                class="me_list performanceList"
+                v-for="(item, index) in meList"
+                :key="index"
+                :style="'z-index:' + (meList.length - index)"
+                @click="$router.push({ name: 'performanceDetails', query: { id: item.id, Tit: item.package_name } })"
+              >
+                <div class="me_list_img">
+                  <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                </div>
+                <div class="me_list_content">
+                  <div class="me_list_tit">{{ item.package_name }}</div>
+                  <span v-if="item.current_node == 'result' || !item.current_node" class="me_list_result">
+                    <span v-if="item.result">
+                      <span class="me_list_col">绩效结果:</span>
+                      {{ item.result }}
+                      <br />
+                    </span>
+                    <span v-if="item.grade">
+                      <span class="me_list_col">绩效等级:</span>
+                      {{ item.grade }}
+                      <br />
+                    </span>
+                    <span class="me_list_resultTit">考核结束</span>
+                  </span>
+                  <div v-else class="me_list_course">
+                    {{
+                      item.current_node == 'target'
+                        ? '目标制定'
+                        : item.current_node == 'confirm'
+                        ? '目标确定'
+                        : item.current_node == 'execution'
+                        ? '执行中'
+                        : item.current_node == 'result_value'
+                        ? '结果值录入'
+                        : item.current_node == 'score' || item.current_node == 'special_scorer'
+                        ? '评分'
+                        : item.current_node == 'review'
+                        ? '审批'
+                        : ''
+                    }}
+                  </div>
+                </div>
+              </div>
+            </footer>
+          </scroller>
+        </div>
+      </template>
+    </div>
+
+    <van-dialog v-model="selectpfdlg" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectpradio">
+          <van-radio v-for="(item, index) in selectpfList" :key="index" :name="item.value" @click="clickpfTime(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.label }}</span>
+          </van-radio>
+      </van-radio-group>
+    </van-dialog>
+    <!-- 管理记录筛选 -->
+    <van-dialog v-model="selectGl" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="selectGlVal">
+        <div v-for="(item, index) in selectGlType" :key="index">
+          <van-radio :name="item.value" @click="clickGlConfirm(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.label }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="onCancel" value-key="name" @confirm="onConfirm" confirm-button-text="确定" />
+      </div>
+    </van-action-sheet>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import {Tab, Tabs,Search} from 'vant'
+import moment from 'moment';
+import { _debounce, _throttle } from '@/utils/auth';
+Vue.use(Tabs).use(Tab).use(Search);
+export default {
+  data() {
+    return {
+      selectpfdlg: false, // 选择时间弹窗开关
+      selectpfList: [
+        // 选择时间选项
+        { value: 0, label: '全部' },
+        { value: 2, label: '月度' },
+        { value: 3, label: '季度' },
+        { value: 4, label: '半年度' },
+        { value: 5, label: '年度' },
+        { value: 1, label: '天' },
+        { value: 6, label: '自定义' }
+      ],
+      titles:[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}],
+      // 列表
+      performanceList: [], // 绩效列表
+      assessData: {
+        cycle_type: 0, // 周期类型
+        keywords: '', // 搜索字
+        page: 1, // 当期页
+        page_size: 10, // 一页多少数据
+        is_manage_scope: 1
+      },
+      selectpradio: 0, // 选中的时间选项
+      selectPftiText: { value: 0, label: '全部' }, // 默认值
+      meList: [],
+
+      typeIndex:'1',
+      selectGl:false,
+      selectGlVal:0,
+      selectGlText:'全部',
+      selectGlType: [
+        // 选择时间选项
+        { value: 0, label: '全部' },
+        { value: 1, label: '我的下级' },
+        { value: 2, label: '我协助管理的' },
+      ],
+      pullonThePanel:false,
+      selectGlData: {}, // 当前选中项
+      selectGlKgpText:'',
+      columns: [], // 顶部选项
+      selectGlTheEcho:[],
+      keyword:'',
+      page:1,
+
+      //我评分的
+      glDataList:[{userInfo:{},dept_list:[]}],
+      isColumns:false,//是否请求完考核包列表
+
+      apList:[],
+      day: moment().format('YYYY-MM-DD'),
+      topMenuList:[
+        {code:"待办",icon:"static/images/daiban.png",url:'backlog',badge:0,isShow:true},
+        {code:"通知",icon:"static/images/tongzhi.png",url:'messageInform',badge:0,isShow:true},
+        {code:"考核明细",icon:"static/images/jixiaobaobiao.png",url:'statement',isShow:this.$userInfo().employee_detail.manage_dept_ids.length>0||(this.$getRole(1) && this.$getPermis(16))},
+        {code:"我的绩效",icon:"static/images/wodejixiao.png",url:'me',isShow:this.$getRole(1)||this.$getRole(2)},
+      ],
+    };
+  },
+  created() {
+    if(this.$getRole(3)){
+      this.titles=[{title:'我的考核',value:'3'},{title:'我评分的',value:'2'},{title:'我管理的',value:'1'}];
+      this.typeIndex="3";
+    }else{
+      this.titles=[{title:'我管理的',value:'1'},{title:'我评分的',value:'2'},{title:'全部考核',value:'3'}];
+    }
+  	this.doSthForSb(); // 代办
+  	this.cc(); // 抄送
+  },
+  mounted() {
+    this.assessData.page = 1;
+    this.assessData.cycle_type = 0;
+  },
+  activated() {
+  	this.doSthForSb(); // 代办
+  	this.cc(); // 抄送
+    this.perScrollerFun();//请求 列表数据
+  },
+  watch:{
+    typeIndex(val){
+      this.page=1;
+      this.selectGlVal=0;
+      this.selectGlText='全部';
+      this.keyword='';
+      if(this.columns.length>0){
+        this.selectGlData = this.columns[0].children[0]
+        this.selectGlKgpText = this.columns[0].children[0].name
+        this.selectGlTheEcho = [0, 0]
+      }
+      if(val=='1'){
+          this.selectGlType=[
+          { value: 0, label: '全部' },
+          { value: 1, label: '我的下级' },
+          { value: 2, label: '我协助管理的' },
+        ]
+        this.$nextTick(()=>{
+          this.getManagement();
+        })
+      }else if(val=='2'){
+        this.selectGlType=[
+          { value: 0, label: '全部' },
+          { value: 1, label: '我的下级' },
+          { value: 2, label: '我协助评分的' },
+        ]
+        this.$nextTick(()=>{
+          this.getScorerRecord();
+        })
+      }
+    }
+  },
+  methods: {
+    openUrl(item) {
+      this.$router.push({ name:item.url});
+    },
+    returnStr(time){
+      let date=`${time}000`
+      let res = moment(Number(date)).format('YYYY/MM/DD HH:mm');
+      return this.fnTime(res);
+    },
+    fnTime( time ){
+        let staer=time.slice(0,11);
+        let ptime = new Date(time).getTime()
+        const twentyFourHours = 24 * 60 * 60 * 1000;
+        const fortyEightHours = 24 * 60 * 60 * 1000 * 2;
+        const today = moment().format('YYYY/MM/DD');
+        const todayTime = new Date(today).getTime();
+        const yesterdayTime = new Date(todayTime - twentyFourHours).getTime();
+        const lastYesterdayTime = new Date(todayTime - fortyEightHours).getTime();
+
+        if( ptime >= todayTime ){
+            return '今天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < todayTime && yesterdayTime <= ptime ){
+            return '昨天 '+time.split(' ')[1]+' 更新了执行计划';
+        }
+        else if( ptime < yesterdayTime && lastYesterdayTime <= ptime ){
+            return '前天 '+time.split(' ')[1]+' 更新了执行计划';
+        }else if(this.dateSum(this.day,staer)>30){
+            return '近30天无计划更新';
+        } else{
+            return time+' 更新了执行计划';
+        }
+    },
+    dateSum(sDate1, sDate2){   //sDate1和sDate2是2008-12-13格式
+        var aDate, oDate1, oDate2, iDays
+        aDate = sDate1.split("-")
+        oDate1 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])   //转换为12-13-2008格式
+        aDate = sDate2.split("-")
+        oDate2 = new Date(aDate[1] + '-' + aDate[2] + '-' + aDate[0])
+        iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 /24)   //把相差的毫秒数转换为天数
+        return iDays
+    },
+    complete(item) {
+      this.employeeDet(item.record_id, (recordMemberIds) => {
+        let data={
+            know: 'admnin',
+            apList: this.apList,
+            packId: item.record_id,
+            assessID: item.employee_id,
+            recordMemberIds:recordMemberIds||[]
+        }
+        this.$setCache('actionplanList',data);
+        this.$router.push({
+          name: 'actionplanList'
+          // query: {
+          //   know: 'admnin',
+          //   apList: this.apList,
+          //   packId: item.record_id,
+          //   assessID: item.employee_id,
+          //   recordMemberIds:recordMemberIds||[],
+          // }
+        })
+        this.isTrack = true;
+      });
+    },
+    employeeDet(id,callBack) {
+      this.staffLoad = true;
+      this.$axiosUser('get', '/api/pro/per/package/employee/info', { id: id })
+        .then(res => {
+          let data = res.data.data;
+          this.apList = JSON.stringify(data.dimension);
+          callBack && callBack(data.record_member_ids);
+        })
+        .finally(() => {
+          this.staffLoad = false;
+        });
+    },
+    openDetail(item){
+      let data={
+        id: item.record_id,
+        Tit: item.package_name
+      }
+      this.$router.push({name:'performanceDetails', query:data});
+    },
+
+    // 下拉刷新
+    refresh_two(done) {
+      this.page = 1;
+      if(this.isColumns){
+         this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+      }else{
+        this.columnList(()=>{
+          this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+        });
+      }
+    },
+    // 上拉加载
+    infinite_two(done) {
+      this.page++;
+      this.typeIndex=='1'? this.getManagement(done): this.getScorerRecord(done);
+    },
+    //管理记录列表
+    getManagement(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/management_record', { package_id: this.selectGlData.id, range:this.selectGlVal, name: this.keyword, page: this.page, page_size: 10 }).then(res => {
+          let list = res.data.data.list;
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list=this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          if (this.page === 1) {
+            this.glDataList = list;
+          } else {
+            this.glDataList = this.glDataList.concat(list);
+          }
+          hasMore = list.length !== 10;
+        })
+        .finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    //我评分的
+    getScorerRecord(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/score_record', { package_id: this.selectGlData.id, range:this.selectGlVal, name: this.keyword, page: this.page, page_size: 10 }).then(res => {
+          let list = res.data.data.list;
+          list.forEach(item => {
+            if (item.employee_id) {
+              //当是导入导出时,显示登录者
+              item.userInfo = this.$getEmployeeMapItem(item.employee_id);
+              item.dept_list=this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list
+            }
+          });
+          if (this.page === 1) {
+            this.glDataList = list;
+          } else {
+            this.glDataList = this.glDataList.concat(list);
+          }
+          hasMore = list.length !== 10;
+        })
+        .finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    onCancel () { // 取消
+      this.pullonThePanel = false
+    },
+    statementTIme () {
+      if(!this.selectGlKgpText){
+        return false
+      }
+      this.pullonThePanel = true
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+    theEchoVanPicker () { // 回显
+      this.$refs.van_picker.setIndexes(this.selectGlTheEcho)
+    },
+    // 考核包搜索
+    onConfirm (data, list) { // 确认
+      this.selectGlTheEcho = list// 回显
+      this.selectGlData = this.columns[list[0]].children[list[1]]// 当前选中项
+      this.selectGlKgpText = data[data.length - 1]// 选中的name
+      this.pullDown();
+      this.pullonThePanel = false
+    },
+    // 搜索
+    keyVal: _debounce(function() {
+      this.pullDown();
+    }),
+    // 管理记录筛选确定
+    clickGlConfirm(item){
+      this.selectGlText=item.label;
+      this.pullDown();
+      this.selectGl=false;
+    },
+
+    pullDown(){
+      this.page=1;
+      setTimeout(() => {
+        this.$refs.perScroller.triggerPullToRefresh();
+      }, 50);
+    },
+    columnList (callback) { // 绩效包树
+      this.$axiosUser('get', '/api/pro/per/package/tree').then((res) => {
+        if (res.data.code == 1) {
+          let data = res.data.data
+          let list = []
+          data.forEach((item) => {
+            if (item.list.length > 0) {
+              list.push(item)
+              item.children = item.list
+            }
+          })
+          if (list.length > 0) {
+            this.selectGlData = list[0].children[0]
+            this.selectGlKgpText = list[0].children[0].name
+            this.selectGlTheEcho = [0, 0]
+            this.columns = list
+          }
+        }
+      }).finally(()=>{
+        this.isColumns=true;
+        callback && callback()
+      })
+    },
+    // 上拉刷新
+    refresh(done) {
+      this.assessData.page = 1;
+      this.assessBagList(done);
+    },
+    // 下拉加载
+    infinite(done) {
+      this.assessData.page++;
+      this.assessBagList(done);
+    },
+    // 点击选择时间选项
+    clickpfTime(val) {
+      this.selectPftiText = val;
+      this.assessData.page = 1;
+      this.assessData.cycle_type = val.value;
+      this.selectpfdlg = false;
+      this.perScrollerFun();
+    },
+    assessBagList(callback) {
+      let hasMore = false;
+      this.$axiosUser('get', '/api/pro/per/package/list', this.assessData)
+        .then(res => {
+          if (res.data.code == 1) {
+            const { list } = res.data.data;
+            if (this.assessData.page === 1) {
+              this.performanceList = list;
+            } else {
+              this.performanceList = this.performanceList.concat(list);
+            }
+            hasMore = list.length !== 10;
+          }
+        }).finally(() => {
+          callback && callback(hasMore);
+        });
+    },
+    selectPfTIme() {
+      this.selectpfdlg = true;
+    },
+
+    perScrollerFun() {
+      setTimeout(() => {
+        this.$refs.perScroller.triggerPullToRefresh();
+      }, 50);
+    },
+
+    doSthForSb() {
+      // 代办数量
+      let params = {status: 0,page: 0};
+      let axios= this.$axiosUser('get', '/api/pro/per/package/msg/agency', params,'v2')
+      let axios2= this.$axiosUser('get', '/api/pro/per/package/plc/list', {page:1,page_size:1,status:0})
+      Promise.all([axios,axios2]).then(res => {
+          let total=res[0].data.data.total;
+          let total2=res[1].data.data.total;
+          this.topMenuList[0].badge=total+total2||'';
+      })
+    },
+    cc() {
+      // 抄送
+      let params = {
+        type: '1,2',
+        status: 0, // 未处理
+        page: 0
+      };
+      this.$axiosUser('get', '/api/pro/per/package/msg/cc', params).then(res => {
+        if (res.data.code == 1) {
+          this.topMenuList[1].badge= res.data.data.total||'';
+        }
+      });
+    },
+    refresh1(done) {
+      if (this.$getRole(3) || this.$getRole(4)) {
+        // 员工权限
+        this.myPerformanceList(done); // 请求我的绩效接口
+      }
+    },
+    myPerformanceList(callback) {
+      let params = {
+        employee_id: this.$userInfo().id
+      };
+      this.$axiosUser('get', '/api/pro/per/package/employee/list', params)
+        .then(res => {
+          if (res.data.code == 1) {
+            let data = res.data.data.list;
+            this.meList = data;
+          }
+        })
+        .finally(() => {
+          callback && callback();
+        });
+    }
+  },
+};
+</script>
+
+<style scoped lang="less">
+.workHeader /deep/ .van-grid-item {
+  margin-bottom: 0.2rem;
+}
+.workHeader /deep/ .van-grid-item .van-grid-item__content {
+  padding: 0 !important;
+}
+.workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__text {
+  font-size: 0.28rem;
+  color: #606266;
+  line-height: 0.44rem;
+  width: 1.4rem;
+  text-align: center;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.workHeader /deep/ .van-grid-item .van-grid-item__content .van-grid-item__icon-wrapper img {
+  width: 1rem;
+  height: 1rem;
+  border-radius: 0.42rem;
+}
+.list-item{
+  padding: 0.24rem 0.32rem;
+  font-size: 0.32rem;
+  border-bottom: 1px solid #f1f1f1;
+}
+
+.selectItem{
+  margin-top: 0.2rem;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.32rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+
+.workHeader {
+  background-color: #fff;
+  font-size: 0.31rem;
+  padding-top: 0.4rem;
+  .headcol {
+    position: relative;
+    .headicon {
+      width: 100%;
+      display: flex;
+      justify-content: center;
+      i {
+        margin: 0.4rem 0.1rem 0 0;
+      }
+    }
+  }
+}
+
+.selector {
+  display: flex;
+  justify-content: center;
+  margin-top: 0.2rem;
+  width: 100%;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.32rem;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+}
+
+.cunt {
+  background-color: #f15532;
+  text-align: center;
+  line-height: 0.39rem;
+  width: 0.4rem;
+  height: 0.4rem;
+  border-radius: 50%;
+  position: absolute;
+  top: 0.4rem;
+  left: 2.9rem;
+  color: #fff;
+  font-size: 0.26rem;
+  font-style: normal;
+}
+.cunt i {
+  font-style: normal;
+}
+.cunts {
+  width: auto !important;
+  padding: 0 .04rem 0 .08rem !important;
+  border-radius: .8rem !important;
+}
+
+.all {
+  height: 100%;
+  position: relative !important;
+  & .event-list__content {
+    position: relative;
+    height: calc(100% - 4.3rem);
+    & .van-hairline--top-bottom:after,
+    .body_com .van-hairline-unset--top-bottom:after {
+      border: none;
+    }
+  }
+  & .event-list__content2 {
+    position: relative;
+    height: calc(100% - 3.2rem);
+    & .van-hairline--top-bottom:after,
+    .body_com .van-hairline-unset--top-bottom:after {
+      border: none;
+    }
+  }
+}
+
+.workbench_list {
+  padding: 0.3rem 0.6rem;
+  div {
+    font-size: 0.33rem;
+  }
+  span {
+    padding-top: 0.1rem;
+    color: #737373;
+    font-size: 0.25rem;
+    display: flex;
+    i {
+      margin: 0.06rem 0.05rem 0 0;
+      color: #f7b461;
+    }
+  }
+}
+
+.meAll {
+  height: calc(100% - 1rem) !important;
+  position: relative !important;
+  background-color: #f5f7fa;
+}
+.me_list {
+  background-color: #fff;
+  display: flex;
+  padding: 12px 16px;
+  .me_list_content {
+    padding-left: 0.3rem;
+    .me_list_tit {
+      font-size: 0.33rem;
+    }
+    .me_list_result {
+      font-size: 0.3rem;
+      .me_list_col {
+        color: #adadad;
+      }
+      .me_list_resultTit {
+        display: inline-block;
+        padding-bottom: 0.18rem;
+        color: #3bdf9a;
+      }
+    }
+    .me_list_course {
+      display: inline-block;
+      padding-bottom: 0.18rem;
+      font-size: 0.28rem;
+      color: #ff9439;
+    }
+  }
+}
+</style>

+ 1 - 0
src/performance-07-19/view/performanceHome.vue

@@ -0,0 +1 @@
+        </van-grid>

+ 1 - 1
src/performance/components/actionplan/actionplanDetails.vue

@@ -34,7 +34,7 @@
           <span>保存</span>
         </button>
       </div>
-      <div class="planText" v-if="isShowAdd&&!has_finish">
+      <div class="planText" v-if="isShowAdd && !has_finish">
         <van-cell-group style="margin-top: 0rem;">
           <van-field :label="detailsTIt" v-model="titValue" rows="3" type="textarea" autosize maxlength="200" :placeholder="'请输入' + detailsTIt" show-word-limit />
           <div></div>

+ 150 - 41
src/performance/components/actionplan/resultValueEntry.vue

@@ -1,27 +1,44 @@
 <template>
-  <div :class="[{ bg_fff: skeletonLoad }]">
+  <div :class="[{ bg_fff: skeletonLoad }]" style="width: 100%; height: 100%; ">
     <van-nav-bar title="结果值数据录入" left-text="" left-arrow @click-left="routerBak" />
+
     <VanSkeleton :skeLoad="skeletonLoad">
-      <header v-if="$route.query.resultStr=='录入结果值'">
-        <van-tabs v-model="active" swipeable><van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'" :key="index"></van-tab></van-tabs>
-      </header>
-      <scroller :isNeed="isNeed" :style="{height:$route.query.resultStr=='录入结果值'? 'calc(100% - 3.2rem)':'calc(100% - 2.3rem)'}"  ref="work_bench_scroller" class="all" :class="{ isIos: isIos }">
+      <div style="width: 100%; height: calc(100% - 0.92rem); display: flex; flex-direction: column;">
+        <header v-if="$route.query.resultStr=='录入结果值'">
+          <van-tabs v-model="active" swipeable>
+            <van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'" :key="index"></van-tab>
+          </van-tabs>
+        </header>
+
+        <div class="batch-operate" style="width: 100%; font-size: 0.28rem;  color: rgb(146, 146, 146);  display: flex; align-items: center; padding: 0.24rem; box-sizing: border-box;background-color: #fff;">
+          <van-checkbox v-model="isAllChecked" shape="square" icon-size="18px" @change="toggleAllCheck" style="margin-right: 0.24rem;"></van-checkbox>
+          <button class="footcolButno" @click="openBatchOperation(1)" style="width: 2rem; height: 0.5rem; margin-right: 0.24rem;" :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">结果值</button>
+          <button class="footcolButno" @click="openBatchOperation(2)" style="width: 2rem; height: 0.5rem; margin-right: 0.24rem;" :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">图片</button>
+        </div>
+
+      <scroller :isNeed="isNeed" ref="work_bench_scroller" class="all">
         <div style="padding-bottom:2.65rem;" v-if="rvenotList.length > 0">
           <div v-for="(item, index) in rvenotList" :key="index" style="margin:.2rem 0;padding:0.24rem;background-color:#fff;">
-            <div style="display:flex;border-bottom: 1px dashed #f3f3f3;padding-bottom: .25rem;">
-              <userImage class="about-me__avatar" :id="item.userId" :user_name="item.userName" fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
-              <span style="font-size:.3rem;padding: 0.09rem 0px 0px 0.18rem;">{{ item.userName }}</span>
-              <span class="font-flex-word" style="width: 4rem;display:inline-block;color:#a7a7a7;">
-                <span v-for="(depts, keys) in item.dept_list" :key="keys" style="font-size:.25rem;padding: 0.14rem 0px 0px 0.15rem;display: inline-block;">
-                  {{ depts.dept_name }}
-                  <span v-if="item.dept_list.length - keys > 1">,</span>
+            <div style="display:flex; border-bottom: 1px dashed #f3f3f3;padding-bottom: .25rem;">
+              <div style="width: 100%; display:flex; align-items: center;">
+                <van-checkbox v-model="item.isChecked" shape="square" style="margin-right: 0.24rem;" icon-size="18px" @change="updateAllCheckStatus"></van-checkbox>
+                <userImage class="about-me__avatar" :id="item.userId" :user_name="item.userName" fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
+                <span style="font-size:.3rem;padding: 0.09rem 0px 0px 0.18rem;">{{ item.userName }}</span>
+              </div>
+              <div style="width: 100%; display:flex; align-items: center;">
+                <span class="font-flex-word" style="width: 100%; display:inline-block;color:#a7a7a7;">
+                  <span v-for="(depts, keys) in item.dept_list" :key="keys" style="font-size:.25rem;padding: 0.14rem 0px 0px 0.15rem;display: inline-block;">
+                    {{ depts.dept_name }}
+                    <span v-if="item.dept_list.length - keys > 1">,</span>
+                  </span>
                 </span>
-              </span>
+              </div>
+
             </div>
             <div>
               <div style="font-size:.32rem;margin: 0.2rem 0;">{{ item.name }}</div>
               <div  class="flex-box" style="margin-bottom: 0.14rem;" v-for="(arr, att) in item.dil" :key="att" v-if="arr.prop">
-                <div style="color:#929292;font-size:.27rem;width: 1.4rem;">{{ arr.lab }}:</div>
+                <div style="color:#929292;font-size:.27rem;width: 1.6rem;">{{ arr.lab }}:</div>
                 <div class="flex-1" style="font-size:.28rem;">{{ arr.prop }}</div>
               </div>
               <!-- v-if="active == 0" -->
@@ -44,7 +61,7 @@
         </div>
         <van-empty description="暂无结果值录入" v-else />
       </scroller>
-      <footer v-if="active == 0 && rvenotList.length > 0">
+      <footer v-if="active == 0 && rvenotList.length > 0 && selectList && selectList.length > 0">
         <van-row class="footfoot">
           <van-col span="14" class="footcol" @click="save(1)">
             <div style="width:1rem;margin: auto;" v-if="$route.query.resultStr=='录入结果值'">
@@ -58,7 +75,7 @@
           </van-col>
         </van-row>
       </footer>
-      <footer v-if="active == 1 && rvenotList.length > 0">
+      <footer v-if="active == 1 && rvenotList.length > 0 && selectList && selectList.length > 0">
         <van-row class="footfoot">
           <van-col span="14" class="footcol">
           </van-col>
@@ -68,7 +85,34 @@
           </van-col>
         </van-row>
       </footer>
+    </div>
     </VanSkeleton>
+
+    <van-popup v-model:show="isBatchOperation" round>
+      <div style="width: 7rem; padding: 0.24rem; box-sizing: border-box;">
+        <div>
+        <div style="font-weight: 600; text-align: center;">
+          批量录入数据
+        </div>
+        <div style="color: #FF9600; padding: 0.24rem 0.32rem; box-sizing: border-box;">选择的数据将会录入同一结果值和图片</div>
+        <div class="flex-box-ce" v-if="showType == 1">
+          <van-field label="结果值" v-model="batch_result_cache" placeholder="请输入结果值" border/>
+        </div>
+
+        <div style="padding: 0.24rem 0.32rem; box-sizing: border-box;" v-if="showType == 2">
+          <div style="color: #646566; margin-bottom: 0.24rem;">请上传图片</div>
+          <Uploader v-model="batch_result_imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept"/>
+          </div>
+        </div>
+
+        <span slot="footer">
+          <div class="flex-box-end" style="margin-top: 12px;" >
+            <button class="footcolButno" @click="cancelBatchOperation()" style="height: 0.6rem;">取消</button>
+            <button class="footcolButok" @click="confirmBatchOperation()" style="height: 0.6rem;">确定</button>
+          </div>
+        </span>
+      </div>
+    </van-popup>
   </div>
 </template>
 
@@ -83,7 +127,12 @@ Vue.use(Tab)
 export default {
   data() {
     return {
+      showType: 1,
       isNeed:!this.$getCache('isAndroid'),
+      isAllChecked: false,
+      batch_result_cache: "",
+      batch_result_imgs: [],
+      isBatchOperation: false,
       skeletonLoad: true, // 骨架屏
       rvenotList: [],
       minFormactive: [{ name: '未录入', age: 0 }, { name: '已录入', age: 0 }],
@@ -109,9 +158,52 @@ export default {
       } else if (val == 1) {
         this.rvenotList = this.statusList;
       }
+      this.isAllChecked = false
+      this.rvenotList.forEach(item => item.isChecked = false)
     }
   },
+
+  computed: {
+    selectList() {
+      return this.rvenotList.filter(item => item.isChecked)
+    }
+  },
+
   methods: {
+    toggleAllCheck() {
+      this.rvenotList.forEach(item => {
+        item.isChecked = this.isAllChecked;
+      });
+    },
+    updateAllCheckStatus() {
+      this.isAllChecked = this.rvenotList.every(item => item.isChecked);
+    },
+    cancelBatchOperation() {
+      this.isBatchOperation = false
+    },
+    confirmBatchOperation() {
+      if(this.batch_result_imgs && this.batch_result_imgs.length > 0) {
+        this.rvenotList.forEach(item => {
+          if(item.isChecked) {
+            item.result_file.imgs = this.batch_result_imgs
+          }
+        })
+      }
+      if(this.batch_result_cache !== '' && this.batch_result_cache !== null) {
+        this.rvenotList.forEach(item => {
+          if(item.isChecked) {
+            if(item.index_type == 1) item.result_cache = this.batch_result_cache
+          }
+        })
+      }
+      this.isBatchOperation = false
+    },
+    openBatchOperation(type) {
+      if(this.selectList && this.selectList.length > 0) {
+        this.showType = type
+        this.isBatchOperation = true
+      }
+    },
     downWgt(url, name) {
       let self = this;
       if (!window.plus) {
@@ -172,7 +264,7 @@ export default {
       let result_info = [];
       let isPost=true;
       let str='';
-      this.rvenotList.some(e => {
+      this.selectList.some(e => {
         let images = [];
         if (e.result_file.imgs) {
           e.result_file.imgs.forEach(imgItem => {
@@ -298,6 +390,7 @@ export default {
                 item2.userName = relevance_employee.name;
                 item2.userId = relevance_employee.id;
                 item2.dept_list = relevance_employee.employee_detail.dept_list;
+                item2.isChecked = false;
                 item2.dil = [
                   {lab: '考核标准',prop: item2.per_remark ? item2.per_remark : null},
                   { lab: '权重%', prop: item2.weight ? item2.weight : null },
@@ -329,6 +422,7 @@ export default {
               });
               item.result_file.imgs = imgs;
             }
+
             if (item.status == 2) {
               dimension[item.dimension_key].index[item.index_key].message = item;
               let result_file=dimension[item.dimension_key].index[item.index_key].result_file;
@@ -369,8 +463,8 @@ export default {
     }
   },
   created() {
-    if (this.$route.query.resultStr=='调整结果值') {
-       this.active = 1;
+    if (this.$route.query.resultStr == '调整结果值') {
+      this.active = 1;
     }
     if (this.$route.query.id) {
       this.id = this.$route.query.id;
@@ -384,8 +478,7 @@ export default {
 
 <style scoped lang="less">
 .all {
-  height: calc(100% - 3.2rem);
-  // height: calc(100% - 2.3rem);
+  flex: 1;
   position: relative ;
   background-color: #f5f7fa;
   padding-bottom: 0.3rem;
@@ -399,7 +492,37 @@ header {
 .isIos {
   height: calc(100% - 3.6rem) !important;
 }
+.batch-operate {
+  width: 100%;
+  font-size: 0.28rem;
+  color: rgb(146, 146, 146);
+  display: flex;
+  align-items: center;
+  padding: 0.24rem;
+  box-sizing: border-box;
+  background-color: #fff;
+}
 
+.footcolButno {
+  border: 1px solid #42a8ff;
+  width: 1.4rem;
+  height: 0.8rem;
+  font-size: 0.28rem;
+  color: #2f9eff;
+  background-color: #ffffff;
+  border-top-left-radius: 3px;
+  border-bottom-left-radius: 3px;
+}
+.footcolButok {
+  border: 0;
+  width: 1.4rem;
+  height: 0.8rem;
+  font-size: 0.28rem;
+  color: #fff;
+  background-color: #42a8ff;
+  border-top-right-radius: 3px;
+  border-bottom-right-radius: 3px;
+}
 footer {
   // position: fixed;
   // left: 0px;
@@ -418,26 +541,12 @@ footer {
     .footBut {
       display: flex;
     }
-    .footcolButno {
-      border: 1px solid #42a8ff;
-      width: 1.4rem;
-      height: 0.8rem;
-      font-size: 0.28rem;
-      color: #2f9eff;
-      background-color: #ffffff;
-      border-top-left-radius: 3px;
-      border-bottom-left-radius: 3px;
-    }
-    .footcolButok {
-      border: 0;
-      width: 1.4rem;
-      height: 0.8rem;
-      font-size: 0.28rem;
-      color: #fff;
-      background-color: #42a8ff;
-      border-top-right-radius: 3px;
-      border-bottom-right-radius: 3px;
-    }
+
   }
 }
+
+.disabled {
+  color: #bbb;
+  border-color: #bbb;
+}
 </style>

+ 1100 - 526
src/performance/components/actionplan/resultValueEntryMb.vue

@@ -1,601 +1,1175 @@
 <template>
-  <div style="height:calc(100% - 1.92rem)">
-    <div style="height: 100%;">
-      <div style="height: 0.9rem;background-color: #fff;font-size: 0.32rem;" class="flex-box-ce flex-center-center" @click="selectUser=true">
-        <span style="max-width: 4rem;" class="font-flex-word">{{userName}} </span>
-        <van-icon name="arrow-down"/>
-      </div>
+  <div style="height:calc(100% - 1.92rem);">
+    <div style="width:100%; height: 100%;">
       <header>
-        <van-tabs v-model="active" swipeable><van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'" :key="index"></van-tab></van-tabs>
+        <van-tabs v-model="active" swipeable>
+          <van-tab v-for="(item, index) in minFormactive" :title="item.name + '(' + item.age + ')'"
+            :key="index"></van-tab>
+        </van-tabs>
       </header>
-      <div v-if="active===0" class="flex-box-ce flex-d-center" style="padding: 0.2rem 0.32rem;background-color: #fff;border-top: 1px solid #f1f1f1;">
-          <span @click.stop="openText2()">排序<van-icon name="question" class="fontColorC"/></span></span>
-          <van-checkbox v-model="paiXu" icon-size="18px" shape="square">按指标名称排序</van-checkbox>
+
+      <div class="batch-operate">
+        <van-checkbox v-model="isAllChecked" shape="square" icon-size="18px" @change="toggleAllCheck"
+          style="margin: 0 0.24rem;"></van-checkbox>
+        <button class="footcolButno" @click="openBatchOperation(1)"
+          style="width: 2rem; height: 0.5rem; font-size: 0.28rem; margin-right: 0.24rem;"
+          :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">结果值</button>
+        <button class="footcolButno" @click="openBatchOperation(2)"
+          style="width: 2rem; height: 0.5rem;  font-size: 0.28rem; margin-right: 0.24rem;"
+          :class="!(selectList && selectList.length) > 0 ? 'disabled' : ''">图片</button>
+        <!-- <div style="color: #FF9600;">支持批量录入结果值和图片</div> -->
+        <span @click.stop="openText2()"><van-icon name="question" class="fontColorC" /></span>
       </div>
-      <scroller :isNeed="isNeed" ref="work_bench_scroller" class="all" :class="{ isIos: isIos }">
-        <div style="padding-bottom:2.65rem;" v-if="rvenotList.length > 0">
-          <div v-for="(item, index) in rvenotList" :key="index" style="margin:.2rem 0;padding:0.24rem;background-color:#fff;">
-            <div class="flex-box-ce" style="border-bottom: 1px dashed #f3f3f3;padding-bottom: .25rem;">
-              <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name" fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
-              <div style="font-size:.3rem;padding: 0rem 0px 0px 0.18rem;">{{ item.employee_name }}</div>
-              <div class="font-flex-word fontColorC flex-1" style="padding-right: 0.2rem;">
-                <span v-for="(depts, keys) in item.dept_list" :key="keys" style="font-size:.25rem;padding: 0rem 0px 0px 0.15rem;display: inline-block;">
-                  {{ depts.dept_name }}
-                  <span v-if="item.dept_list.length - keys > 1">,</span>
-                </span>
-              </div>
-              <template v-if="active == 1">
-                <div style="font-size:.3rem" class="fontColorC" v-if="!item.isUpdate" @click="openText(item)"><van-icon name="info-o" />不可调整</div>
-              </template>
-            </div>
-            <div>
-              <div style="font-size:.32rem;margin: 0.2rem 0;">{{ item.index_name }}</div>
-              <div  class="flex-box" style="margin-bottom: 0.14rem;" v-for="(arr, att) in item.dil" :key="att" v-if="arr.prop">
-                <div style="color:#929292;font-size:.27rem;width: 1.4rem;">{{ arr.lab }}:</div>
-                <div class="flex-1" style="font-size:.28rem;">{{ arr.prop }}</div>
-              </div>
 
-              <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="active == 0">
-                <div class="flex-box-ce" v-if="item.index_type==1">
-                  <van-field v-model="item.result_cache" placeholder="请输入结果值"/>
-                  <div style="padding-right: 0.32rem;" class="fontColorC">{{item.unit}}</div>
+      <div style="width:100%; height:calc(100% - 1.8rem);display: flex; flex-direction: column;">
+        <scroller :isNeed="isNeed" ref="work_bench_scroller" class="all">
+          <div style="padding-bottom:2.65rem;" v-if="rvenotList.length > 0">
+            <div v-for="(item, index) in rvenotList" :key="index"
+              style="margin:.2rem 0;padding:0.24rem;background-color:#fff;">
+              <div class="flex-box-ce" style="border-bottom: 1px dashed #f3f3f3; padding-bottom: .25rem;">
+                <van-checkbox v-model="item.isChecked" shape="square" style="margin-right: 0.24rem;" icon-size="18px"
+                  @change="updateAllCheckStatus"></van-checkbox>
+                <userImage class="about-me__avatar" :id="item.employee_id" :user_name="item.employee_name"
+                  fontSize=".28" width="0.6rem" height="0.6rem"></userImage>
+                <div style="font-size:.3rem; padding: 0rem 0px 0px 0.18rem; box-sizing: border-box;">
+                  {{ item.employee_name }}
                 </div>
-                <van-cell><Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept"/></van-cell>
-                <van-cell v-if="item.result_file.append.length>0">
-                  <template >
-                    <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
-                    <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">{{e.name}}</div>
-                  </template>
-                </van-cell>
+                <div class="font-flex-word fontColorC flex-1" style="padding-right: 0.2rem;">
+                  <span v-for="(depts, keys) in item.dept_list" :key="keys"
+                    style="font-size:.25rem;padding: 0rem 0px 0px 0.15rem;display: inline-block;">
+                    {{ depts.dept_name }}
+                    <span v-if="item.dept_list.length - keys > 1">,</span>
+                  </span>
+                </div>
+                <template v-if="active == 1">
+                  <div style="font-size:.3rem" class="fontColorC" v-if="!item.isUpdate" @click="openText(item)">
+                    <van-icon name="info-o" />不可调整
+                  </div>
+                </template>
               </div>
-              <template v-else>
-                <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="item.isUpdate">
-                  <div class="flex-box-ce" v-if="item.index_type==1">
-                    <van-field v-model="item.result_cache" placeholder="请输入结果值" />
-                    <div style="padding-right: 0.32rem;" class="fontColorC">{{item.unit}}</div>
+              <div>
+                <div style="font-size:.32rem;margin: 0.2rem 0;">{{ item.index_name }}</div>
+                <div class="flex-box" style="margin-bottom: 0.14rem;" v-for="(arr, att) in item.dil" :key="att"
+                  v-if="arr.prop">
+                  <div style="color:#929292;font-size:.27rem; width: 1.6rem;">{{ arr.lab }}:</div>
+                  <div class="flex-1" style="font-size:.28rem;">{{ arr.prop }}</div>
+                </div>
+
+                <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="active == 0">
+                  <div class="flex-box-ce"
+                    style="justify-content: space-between; padding: 0 0.32rem 0 0; box-sizing: border-box;"
+                    v-if="item.index_type==1">
+                    <van-field v-model="item.result_cache" placeholder="请输入结果值" style="width: 5rem;" />
+                    <div class="fontColorC">{{item.unit}}</div>
                   </div>
-                  <van-cell><Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept"/></van-cell>
+                  <van-cell>
+                    <Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead"
+                      :accept="accept" />
+                  </van-cell>
                   <van-cell v-if="item.result_file.append.length>0">
-                    <template >
+                    <template>
                       <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
-                      <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">{{e.name}}</div>
+                      <div class="blue" style="padding-top: 5px;font-size: 0.28rem;"
+                        v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">
+                        {{e.name}}
+                      </div>
                     </template>
                   </van-cell>
                 </div>
-                <div v-else>
-                  <span style="color:#929292;font-size:.27rem;width: 1.4rem;display: inline-block;">结果值:</span>
-                  <span style="font-size:.28rem;position: relative;left: -4px;" class="orange" v-if="item.index_type==1">{{ item.result_cache }} {{ item.unit }}</span>
-                  <template v-if="item.result_file.images">
-                    <div class="flex-box-ce" style="margin: 10px 0;" v-if="item.result_file.images.length>0">
-                      <van-image @click="openImg(item.result_file.images,index2)" v-for="(e,index2) in item.result_file.images" :key="index2" style="border-radius: 3px;margin-right: 10px;" width="100" height="100" :src="e.url"/>
+                <template v-else>
+                  <div style="border:1px solid #e4e4e4;margin: .2rem 0 0 0;" v-if="item.isUpdate">
+                    <div class="flex-box-ce"
+                      style="justify-content: space-between; padding: 0 0.32rem 0 0; box-sizing: border-box;"
+                      v-if="item.index_type==1">
+                      <van-field v-model="item.result_cache" placeholder="请输入结果值" style="width: 5rem;" />
+                      <div class="fontColorC">{{item.unit}}</div>
                     </div>
-                  </template>
-                  <template v-if="item.result_file.append.length>0">
-                    <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
-                    <div class="blue" style="padding-top: 5px;font-size: 0.28rem;" v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">{{e.name}}</div>
-                  </template>
-                </div>
-              </template>
-            </div>
+                    <van-cell>
+                      <Uploader v-model="item.result_file.imgs" :max-count="3" :beforeRead="beforeRead"
+                        :accept="accept" />
+                    </van-cell>
+                    <van-cell v-if="item.result_file.append.length>0">
+                      <template>
+                        <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                        <div class="blue" style="padding-top: 5px;font-size: 0.28rem;"
+                          v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">
+                          {{e.name}}
+                        </div>
+                      </template>
+                    </van-cell>
+                  </div>
+                  <div v-else>
+                    <span style="color:#929292;font-size:.27rem;width: 1.4rem;display: inline-block;">结果值:</span>
+                    <span style="font-size:.28rem;position: relative;left: -4px;" class="orange"
+                      v-if="item.index_type==1">{{ item.result_cache }} {{ item.unit }}</span>
+                    <template v-if="item.result_file.images">
+                      <div class="flex-box-ce" style="margin: 10px 0;" v-if="item.result_file.images.length>0">
+                        <van-image @click="openImg(item.result_file.images,index2)"
+                          v-for="(e,index2) in item.result_file.images" :key="index2"
+                          style="border-radius: 3px;margin-right: 10px;" width="100" height="100" :src="e.url" />
+                      </div>
+                    </template>
+                    <template v-if="item.result_file.append.length>0">
+                      <div style="font-size: 0.24rem;" class="orange">文件仅支持在PC上‘上传’、‘删除’</div>
+                      <div class="blue" style="padding-top: 5px;font-size: 0.28rem;"
+                        v-for="(e,index2) in item.result_file.append" :key="index2" @click="downWgt(e.url,e.name)">
+                        {{e.name}}
+                      </div>
+                    </template>
+                  </div>
+                </template>
+              </div>
 
-          </div>
-        </div>
-        <van-empty description="暂无结果值录入" v-else />
-      </scroller>
-      <footer v-if="active == 0 && rvenotList.length > 0" v-isKeyboard>
-        <van-row class="footfoot">
-          <van-col span="14" class="footcol" @click="save(1)">
-            <div style="width:1rem;margin: auto;">
-              <icon name="save" style="width: 0.5rem;height: 0.5rem;"></icon>
-              <div style="font-size: .24rem;color:#8a8a8a;">暂存</div>
             </div>
-          </van-col>
-          <van-col span="10" class="footBut">
-            <button class="footcolButno" @click="rveno">取消</button>
-            <button class="footcolButok" @click="save(0)">提交</button>
-          </van-col>
-        </van-row>
-      </footer>
-      <footer v-if="active == 1 && rvenotList.length > 0&&returnIsShow" v-isKeyboard>
-        <van-row class="footfoot">
-          <van-col span="14" class="footcol"></van-col>
-          <van-col span="10" class="footBut">
-            <button class="footcolButno" @click="rveno">取消</button>
-            <button class="footcolButok" @click="save(3)">提交</button>
-          </van-col>
-        </van-row>
-      </footer>
-
-      <van-popup v-model:show="isResult" round>
-        <div style="width: 7rem;padding: 0.24rem;box-sizing: border-box;">
-          <div style="font-size: 0.28rem;margin-bottom: 0.24rem;">提交结果</div>
-          <van-progress :percentage="percentage" stroke-width="8" />
-          <div style="margin-top: 16px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
-            <div class="flex-box-ce results" style="font-weight: 600;">
-              <div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
-              <div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
-              <div class="flex-2" style="border-right: 1px solid #f1f1f1;">指标名称</div>
-              <div class="flex-2">提交结果</div>
+          </div>
+          <van-empty description="暂无结果值录入" v-else />
+        </scroller>
+        <footer v-if="active == 0 && rvenotList.length > 0 && selectList && selectList.length > 0" v-isKeyboard>
+          <van-row class="footfoot">
+            <van-col span="14" class="footcol" @click="save(1)">
+              <div style="width:1rem;margin: auto;">
+                <icon name="save" style="width: 0.5rem;height: 0.5rem;"></icon>
+                <div style="font-size: .24rem;color:#8a8a8a;">暂存</div>
+              </div>
+            </van-col>
+            <van-col span="10" class="footBut">
+              <button class="footcolButno" @click="rveno">取消</button>
+              <button class="footcolButok" @click="save(0)">提交</button>
+            </van-col>
+          </van-row>
+        </footer>
+        <footer v-if="active == 1 && rvenotList.length > 0 && returnIsShow && selectList && selectList.length > 0"
+          v-isKeyboard>
+          <van-row class="footfoot">
+            <van-col span="14" class="footcol"></van-col>
+            <van-col span="10" class="footBut">
+              <button class="footcolButno" @click="rveno">取消</button>
+              <button class="footcolButok" @click="save(3)">提交</button>
+            </van-col>
+          </van-row>
+        </footer>
+      </div>
+
+    </div>
+
+
+    <van-popup v-model="isFilterShow" position="bottom" :style="popStyle">
+      <div class="popup-title">
+        {{ title }}
+      </div>
+      <div class="filter-options-box">
+        <scroller style="height: 5rem; border-top: 0.01rem solid #f5f7fa;">
+          <div class="dropdown-item-title" style="margin-top: 10px;">选择人员</div>
+          <div class="dropdown-item-content-list">
+            <div class="dropdown-item-content" v-for="(item, index) in user_list" :key="index"
+              @click="chooseOptions(item, 'user_name')" :class="selectOptions.includes(item) ? 'active' : ''">
+              {{ item }}
             </div>
-            <div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
-              <div style="border-right: 1px solid #f1f1f1;width: 40px;">{{ results.length - index }}</div>
-              <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.info.employee_name }}</div>
-              <div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.info.index_name }}</div>
-              <div class="flex-2 red" v-if="item.msg">{{item.msg}}</div>
-              <div class="flex-2 green" v-else>提交成功</div>
+          </div>
+          <div class="dropdown-item-title">指标名称</div>
+          <div class="dropdown-item-content-list">
+            <div class="dropdown-item-content" v-for="(item, index) in index_name_list" :key="index"
+              @click="chooseOptions(item, 'index_name')" :class="selectOptions.includes(item) ? 'active' : ''">
+              {{ item }}
             </div>
           </div>
-          <span slot="footer">
-            <div class="flex-box-end" style="margin-top: 12px;" >
-              <van-button type="primary" @click="isResult = false" size="small">确 定</van-button>
+          <div class="dropdown-item-title">考核标准</div>
+          <div class="dropdown-item-content-list">
+            <div class="dropdown-item-content" v-for="(item, index) in index_standard_list" :key="index"
+              style="flex: 0 0 100%; margin-right: 0;" @click="chooseOptions(item, 'index_standard')"
+              :class="selectOptions.includes(item) ? 'active' : ''" s>
+              {{ item }}
             </div>
-          </span>
+          </div>
+
+          <div class="dropdown-item-title">目标值</div>
+          <div class="dropdown-item-content-list">
+            <template v-if="target_list && target_list.length > 0">
+              <div class="dropdown-item-content" v-for="(item, index) in target_list" :key="index"
+                @click="chooseOptions(item, 'target')" :class="select_target_list.includes(item) ? 'active' : ''">
+                {{ item }}
+              </div>
+            </template>
+          </div>
+
+          <div class="dropdown-item-title">权重%</div>
+          <div class="dropdown-item-content-list">
+            <template v-if="index_weight_list && index_weight_list.length > 0">
+              <div class="dropdown-item-content" v-for="(item, index) in index_weight_list" :key="index"
+                @click="chooseOptions(item, 'weight')" :class="select_index_weight_list.includes(item) ? 'active' : ''">
+                {{ item }}
+              </div>
+            </template>
+          </div>
+
+          <div style="height: 1.2rem;"></div>
+
+        </scroller>
+        <div class="btn-container">
+          <button class="footcolButno" style="width: 96%; height: 0.8rem;" @click="clearFilters()">重置</button>
         </div>
-      </van-popup>
-    </div>
+      </div>
+    </van-popup>
+
+    <van-popup v-model:show="isResult" round>
+      <div style="width: 7rem;padding: 0.24rem;box-sizing: border-box;">
+        <div style="font-size: 0.28rem;margin-bottom: 0.24rem;">提交结果</div>
+        <van-progress :percentage="percentage" stroke-width="8" />
+        <div style="margin-top: 16px;border: 1px solid #f1f1f1;max-height: 500px;overflow-y: auto;" class="scroll-bar">
+          <div class="flex-box-ce results" style="font-weight: 600;">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">序号</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">姓名</div>
+            <div class="flex-2" style="border-right: 1px solid #f1f1f1;">指标名称</div>
+            <div class="flex-2">提交结果</div>
+          </div>
+          <div class="flex-box-ce results" v-for="(item, index) in results" :key="index">
+            <div style="border-right: 1px solid #f1f1f1;width: 40px;">{{ results.length - index }}</div>
+            <div class="flex-1" style="border-right: 1px solid #f1f1f1;">{{ item.info.employee_name }}</div>
+            <div class="flex-2" style="border-right: 1px solid #f1f1f1;">{{ item.info.index_name }}</div>
+            <div class="flex-2 red" v-if="item.msg">{{item.msg}}</div>
+            <div class="flex-2 green" v-else>提交成功</div>
+          </div>
+        </div>
+        <span slot="footer">
+          <div class="flex-box-end" style="margin-top: 12px;">
+            <van-button type="primary" @click="closeIsResult" size="small">确 定</van-button>
+          </div>
+        </span>
+      </div>
+    </van-popup>
+
+    <van-popup v-model:show="isBatchOperation" round>
+      <div style="width: 7rem; padding: 0.24rem; box-sizing: border-box;">
+        <div>
+          <div style="font-weight: 600; text-align: center;">
+            批量录入数据
+          </div>
+          <div style="color: #FF9600; padding: 0.24rem 0.32rem; box-sizing: border-box;">选择的数据将会录入同一结果值和图片</div>
+          <div class="flex-box-ce" v-if="showType == 1">
+            <van-field label="结果值" v-model="batch_result_cache" placeholder="请输入结果值" border />
+            <!-- <div style="padding-right: 0.32rem;" class="fontColorC">{{item.unit}}</div> -->
+          </div>
+
+          <div style="padding: 0.24rem 0.32rem; box-sizing: border-box;" v-if="showType == 2">
+            <div style="color: #646566; margin-bottom: 0.24rem;">请上传图片</div>
+            <Uploader v-model="batch_result_imgs" :max-count="3" :beforeRead="beforeRead" :accept="accept" />
+          </div>
+        </div>
+
+        <span slot="footer">
+          <div class="flex-box-end" style="margin-top: 12px;">
+            <button class="footcolButno" @click="cancelBatchOperation()" style="height: 0.6rem;">取消</button>
+            <button class="footcolButok" @click="confirmBatchOperation()" style="height: 0.6rem;">确定</button>
+          </div>
+        </span>
+      </div>
+    </van-popup>
 
-    <!-- 人员选择 -->
-    <EmployeeSelector
-      title="选择人员"
-      :visible.sync="selectUser"
-      @confirm="confirmCreator"
-      :can_select_dept="false"
-      :selected.sync="selected_data"
-    ></EmployeeSelector>
   </div>
 </template>
 
 <script>
-import Vue from 'vue';
-import VanSkeleton from '@/performance/components/public/VanSkeleton';
-import EmployeeSelector from '@/components/EmployeeSelector';
-import Uploader from '@/components/OssUploader';
-import { Tab, Tabs,ImagePreview,Popup,Progress,DropdownMenu, DropdownItem, Icon   } from 'vant';
-Vue.use(Tab).use(Tabs).use(ImagePreview).use(Popup).use(Progress).use(DropdownMenu).use(DropdownItem).use(Icon);
-export default {
-  props: {
-    peIds: {
-      type: String,
-      default: ''
-    },
-    isUpdate: {
-      type: Boolean,
-      default: false
-    },
-  },
-  data() {
-    return {
-      isNeed:!this.$getCache('isAndroid'),
-      skeletonLoad: true, // 骨架屏
-      rvenotList: [],
-      minFormactive: [{ name: '未录入', age: 0 }, { name: '已录入', age: 0 }],
-      active: 0,
-      noStatusListAll:[],
-      noStatusListDx:[],
-      noStatusList: [], // 未录入指标
-      statusList: [], // 已录入指标
-      bootBool: false, // 防止多次请求
-      isIos: this.$getCache('iPhone'),
-
-      // 上传图标与附件
-      img_fileList: [], // 图片附件
-      images: [],
-      accept:'image/jpeg,image/png,image/jpg',
-
-      // 长连接结果
-      results: [], //提交的返回结果集合
-      isResult: false,
-      percentage: 0,
-      resultList: [], //要发送数据的集合
-      resultIndex: 0,
-
-      userName:'全部人员',
-      selectUser:false,
-      employee_list: [],
-      selected_data: { dept: [], employee: [] } ,//传入已选部门
-
-      paiXu:false,
-    };
-  },
-  components: {VanSkeleton,Uploader,EmployeeSelector },
-  computed:{
-    returnIsShow(){
-      let is=false
-      this.statusList.forEach(item=>{
-        if(item.isUpdate){
-          is=true;
-        }
-      })
-      return is
-    },
-  },
-  watch: {
-    paiXu(val){
-      if(val){
-        this.rvenotList=JSON.parse(JSON.stringify(this.noStatusListDx));
-      }else{
-        this.rvenotList=JSON.parse(JSON.stringify(this.noStatusList));
-      }
-    },
-    isResult(val) {
-      if (!val) {
-        this.results = []; //提交的返回结果集合
-        this.isResult = false;
-        this.percentage = 0;
-        this.resultList = []; //要发送数据的集合
-        this.resultIndex = 0;
-        this.getPackageDtail();
-      }
-    },
-    active(val) {
-      if (val == 0) {
-        this.paiXu=false;
-        this.rvenotList = this.noStatusList;
-      } else if (val == 1) {
-        this.rvenotList = this.statusList;
-      }
+  import Vue from 'vue';
+  import VanSkeleton from '@/performance/components/public/VanSkeleton';
+  import EmployeeSelector from '@/components/EmployeeSelector';
+  import Uploader from '@/components/OssUploader';
+  import DeptSelectorDropdown from '@/components/DeptSelectorDropdown'
+  import {
+    Tab,
+    Tabs,
+    ImagePreview,
+    Popup,
+    Progress,
+    DropdownMenu,
+    DropdownItem,
+    Icon
+  } from 'vant';
+  Vue.use(Tab).use(Tabs).use(ImagePreview).use(Popup).use(Progress).use(DropdownMenu).use(DropdownItem).use(Icon);
+  export default {
+    props: {
+      peIds: {
+        type: String,
+        default: ''
+      },
+      isUpdate: {
+        type: Boolean,
+        default: false
+      },
     },
-    peIds() {
-      this.getPackageDtail();
-    }
-  },
-  methods: {
-    openText2(index){
-      this.$dialog.alert({
-        message:'指标名称排在一起,便于对多人且同个指标的结果值录入(注意:中途修改排序需重新填写结果值)',
-      }).then(() => {});
+    data() {
+      return {
+        popStyle: {
+          width: '100%',
+          height: '9rem',
+          padding: '10px',
+          boxSizing: 'border-box',
+          borderRadius: '10px',
+          position: 'relation'
+        },
+        showType: 1,
+        isFilterShow: false,
+        title: '未录入',
+        isAllChecked: false,
+        batch_result_cache: "",
+        batch_result_imgs: [],
+        isBatchOperation: false,
+        isNeed: !this.$getCache('isAndroid'),
+        skeletonLoad: true, // 骨架屏
+        rvenotList: [],
+        minFormactive: [{
+          name: '未录入',
+          age: 0
+        }, {
+          name: '已录入',
+          age: 0
+        }],
+        active: 0,
+        noStatusListAll: [],
+        noStatusListDx: [],
+        noStatusList: [], // 未录入指标
+        statusList: [], // 已录入指标
+        bootBool: false, // 防止多次请求
+        isIos: this.$getCache('iPhone'),
+        user_list: [],
+        index_name_list: [],
+        index_standard_list: [],
+        target_list: [],
+        index_weight_list: [],
+        select_user_name_list: [],
+        select_index_name_list: [], // 筛选指标名称列表
+        select_index_standard_list: [], // 筛选指标标准列表
+        select_target_list: [], // 筛选指标名称列表
+        select_index_weight_list: [], // 筛选指标名称列表
+        // 上传图标与附件
+        img_fileList: [], // 图片附件
+        images: [],
+        accept: 'image/jpeg,image/png,image/jpg',
+
+        // 长连接结果
+        results: [], //提交的返回结果集合
+        isResult: false,
+        percentage: 0,
+        resultList: [], //要发送数据的集合
+        resultIndex: 0,
+
+        userName: '全部人员',
+        selectUser: false,
+        employee_list: [],
+        selected_data: {
+          dept: [],
+          employee: []
+        }, //传入已选部门
+        paiXu: false,
+        selectOptions: []
+      };
     },
-    openText(item){
-      let message=`${item.employee_name}的考核指标已评分,不可调整结果值;如需调整,请联系绩效管理员`;
-      this.$dialog.alert({
-        message:message,
-      }).then(() => {});
+    components: {
+      VanSkeleton,
+      Uploader,
+      EmployeeSelector
     },
-    confirmCreator(data) {
-      let userName = '';
-      this.userName="全部人员"
-      this.employee_list=[];
-      if (data.employee !== null && data.employee.length != 0) {
-        data.employee.forEach(item=>{
-          this.employee_list.push(item.id);
-          userName+=(item.name+',')
+    computed: {
+      returnIsShow() {
+        let is = false
+        this.statusList.forEach(item => {
+          if (item.isUpdate) {
+            is = true;
+          }
         })
-        this.userName = userName;
+        return is
+      },
+      selectList() {
+        return this.rvenotList.filter(item => item.isChecked)
       }
-      this.selected_data = data;
-      this.selectUser = false;
-      this.getPackageDtail();
     },
-    downWgt (url,name) {
-      let self = this
-      if(!window.plus){
-          window.open(url, '_blank');
-          return false
-      }
-      plus.downloader.createDownload(encodeURI(url),{filename:'_doc/update/'},
-        function (d, status) {
-          if (status == 200) {
-            plus.runtime.openFile(d.filename,{},(err)=>{
-              // console.log(JSON.stringify(err))
-            });
-          } else {
-            self.$toast.clear()
-            Notify({ type: 'danger', message: '下载失败,请稍后重试', duration: 1000 })
-          }
+    watch: {
+
+      paiXu(val) {
+        if (val) {
+          this.rvenotList = JSON.parse(JSON.stringify(this.noStatusListDx));
+        } else {
+          this.rvenotList = JSON.parse(JSON.stringify(this.noStatusList));
         }
-      ).start()
-    },
-    openImg(imgs,index){
-      let imgArr=imgs.map(item=>{
-        return item.url
-      })
-      ImagePreview({
-        images:imgArr,
-        startPosition:index,
-      });
-    },
-    // 返回布尔值
-    beforeRead(file) {
-      const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
-      // const isLt2M = file.size / 1024 / 1024 < 2;
-      if (!isJPG) {
-        this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+      },
+      isResult(val) {
+        if (!val) {
+          this.results = []; //提交的返回结果集合
+          this.isResult = false;
+          this.percentage = 0;
+          this.resultList = []; //要发送数据的集合
+          this.resultIndex = 0;
+          this.getPackageDtail();
+        }
+      },
+      active(val) {
+        if (val == 0) this.title = '未录入'
+        else this.title = '已录入'
+        this.clearFilters();
+        this.initFilterData();
+      },
+      selectOptions(val) {
+        if (this.active == 0) this.rvenotList = this.filterFn(this.noStatusList);
+        else this.rvenotList = this.filterFn(this.statusList);
+      },
+      peIds() {
+        this.getPackageDtail();
       }
-      // if (!isLt2M) {
-      //   this.$toast('上传图片大小不能超过 2MB!');
-      // }
-      return isJPG;
-    },
-    // 返回上一页
-    routerBak() {
-      this.$route_back();
     },
-    rveno() {
-      // 取消
-      this.$route_back();
-    },
-    // 提交
-    save(num) {
-      let isLr = false;
-      let parameterArr = [];
-      let isPost=true;
-      let str='';
-      this.rvenotList.some(item => {
-        let images=[];//图片
-        let result_info = [];
-        if( item.result_file.imgs){
-          item.result_file.imgs.forEach(imgItem=>{
-            let name=imgItem.split('/');
-            let obj={
-              name:name[name.length-1],
-              url:imgItem,
+
+    methods: {
+      openFilterBox(type) {
+        if (type == 1) this.active = 0
+        else this.active = 1
+        this.isFilterShow = true;
+      },
+      clearFilters() {
+        this.selectOptions = [];
+        this.select_user_name_list = [];
+        this.select_index_name_list = [];
+        this.select_index_standard_list = [];
+        this.select_target_list = [];
+        this.select_index_weight_list = [];
+        if (this.active == 0) this.rvenotList = this.noStatusList;
+        else this.rvenotList = this.statusList;
+      },
+
+
+
+      filterFn(data) {
+
+        let result = [];
+        let flag0 = 0
+        let flag1 = 0
+        let flag2 = 0
+        let flag3 = 0
+        let flag4 = 0
+        // 筛选条件对象
+        let filterCriteria = {
+          // employee_name: [],
+          // index_name: [],
+          // index_standard: [],
+          // target: [],
+          // index_weight: []
+        };
+
+
+        // 按照用户名称过滤数据
+        if (this.select_user_name_list && this.select_user_name_list.length > 0) {
+          flag0 = true;
+          filterCriteria.employee_name = this.select_user_name_list
+        }
+
+        // 按照指标名称过滤数据
+        if (this.select_index_name_list && this.select_index_name_list.length > 0) {
+          flag1 = true;
+          filterCriteria.index_name = this.select_index_name_list
+        }
+
+        // 按照指标标准过滤数据
+        if (this.select_index_standard_list && this.select_index_standard_list.length > 0) {
+          flag2 = true;
+          filterCriteria.index_standard = this.select_index_standard_list
+        }
+
+        // 按照目标值过滤数据
+        if (this.select_target_list && this.select_target_list.length > 0) {
+          flag3 = true;
+          filterCriteria.target = this.select_target_list
+        }
+
+        // 按照权重过滤数据
+        if (this.select_index_weight_list && this.select_index_weight_list.length > 0) {
+          flag4 = true;
+          filterCriteria.index_weight = this.select_index_weight_list
+        }
+
+
+        if(!flag0 && !flag1 && !flag2 && !flag3 && !flag4) result = data
+
+
+        // 根据条件对象筛选数组
+        result = data.filter(user => {
+          return Object.keys(filterCriteria).every(key => {
+            if (Array.isArray(filterCriteria[key])) {
+              // 如果条件值是数组,则检查属性值是否包含在数组中
+              return filterCriteria[key] && filterCriteria[key].includes(user[key]);
+            }
+          });
+        });
+        return result
+
+      },
+
+
+      chooseOptions(item, type) {
+        // 所有的过滤条件
+        if (!this.selectOptions.includes(item)) this.selectOptions.push(item);
+        else {
+          let select_option_index = 0
+          this.selectOptions.forEach((select, index) => {
+            if (select == item) {
+              select_option_index = index
             }
-            images.push(obj)
           })
+          this.selectOptions.splice(select_option_index, 1)
         }
-        item.result_file.images=images;
 
-        result_info.push({
-          dimension_key: item.dimension_id, //维度索引
-          index_key: item.index_key, //指标索引
-          index_id: item.index_id, //指标ID
-          result_file: item.result_file
-        });
-        if(item.index_type == 1){
-          result_info[0].result=item.result_cache
+        // 用户名称
+        if (type == 'user_name') {
+          if (!this.select_user_name_list.includes(item)) this.select_user_name_list.push(item);
+          else {
+            let select_index = 0
+            this.select_user_name_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_user_name_list.splice(select_index, 1)
+          }
         }
-        let data = {
-          id: item.pe_id, //个人考核包ID
-          cache: num==1? 1:0, // 是否暂存 1 是 0 否(提交)
-          info: item,
-          result_info: JSON.stringify(result_info),
-          sub: num==3? 0:1
-        };
 
-        if(num==3){
-          if(item.isUpdate){
-            if (item.index_type == 1) {
-              if(!item.result_cache){
-                isPost=false;
-                str=item.index_name+': 请输入结果值'
-                return true
+        // 指标名称
+        if (type == 'index_name') {
+          if (!this.select_index_name_list.includes(item)) this.select_index_name_list.push(item);
+          else {
+            let select_index = 0
+            this.select_index_name_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
               }
-              parameterArr.push(data);
-            }else{
-              if (item.result_file.append.length == 0 && item.result_file.images.length == 0) {
-                isPost=false;
-                str=item.index_name+': 至少添加一份附件'
-                return true
+            })
+            this.select_index_name_list.splice(select_index, 1)
+          }
+        }
+
+        // 考核标准
+        if (type == 'index_standard') {
+          if (!this.select_index_standard_list.includes(item)) this.select_index_standard_list.push(item);
+          else {
+            let select_index = 0
+            this.select_index_standard_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
               }
-              parameterArr.push(data);
-            }
+            })
+            this.select_index_standard_list.splice(select_index, 1)
           }
-        }else{
-          if (item.index_type == 1 && item.result_cache!==null && item.result_cache!=='') {
-            parameterArr.push(data);
+        }
+
+        // 目标值
+        if (type == 'target') {
+          if (!this.select_target_list.includes(item)) this.select_target_list.push(item);
+          else {
+            let select_index = 0
+            this.select_target_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_target_list.splice(select_index, 1)
           }
-          if (item.index_type != 1 && (item.result_file.append.length > 0 || item.result_file.images.length > 0)) {
-            parameterArr.push(data);
+        }
+
+        // 权重
+        if (type == 'weight') {
+          if (!this.select_index_weight_list.includes(item)) this.select_index_weight_list.push(item);
+          else {
+            let select_index = 0
+            this.select_index_weight_list.forEach((select, index) => {
+              if (select == item) {
+                select_index = index
+              }
+            })
+            this.select_index_weight_list.splice(select_index, 1)
           }
         }
-      });
-      if(num==3){
-        if(!isPost){
-          this.$toast(str);
-          return false;
+
+      },
+      toggleAllCheck() {
+        this.rvenotList.forEach(item => {
+          item.isChecked = this.isAllChecked;
+        });
+      },
+      updateAllCheckStatus() {
+        this.isAllChecked = this.rvenotList.every(item => item.isChecked);
+      },
+      cancelBatchOperation() {
+        this.isBatchOperation = false
+      },
+      confirmBatchOperation() {
+        if (this.batch_result_imgs && this.batch_result_imgs.length > 0) {
+          this.rvenotList.forEach(item => {
+            if (item.isChecked) {
+              item.result_file.imgs = this.batch_result_imgs
+            }
+          })
+        }
+        if (this.batch_result_cache !== '' && this.batch_result_cache !== null) {
+          this.rvenotList.forEach(item => {
+            if (item.isChecked) {
+              if (item.index_type == 1) item.result_cache = this.batch_result_cache
+            }
+          })
+        }
+        this.isBatchOperation = false
+      },
+      openBatchOperation(type) {
+        if (this.selectList && this.selectList.length > 0) {
+          this.showType = type
+          this.isBatchOperation = true
         }
-      }else{
-        if (parameterArr.length == 0) {
-          this.$toast.fail('至少输入一项结果值或非量化指标添加一份附件');
-          return false;
+      },
+
+      closeIsResult() {
+        this.isResult = false;
+        this.batch_result_cache = "";
+        this.batch_result_imgs = [];
+        this.selectOptions = [];
+        this.select_user_name_list = [];
+        this.select_index_name_list = [];
+        this.select_index_standard_list = [];
+        this.select_target_list = [];
+        this.select_index_weight_list = [];
+      },
+
+      openText2(index) {
+        this.$dialog.alert({
+          message: '支持多条件筛选,批量录入结果值及图片',
+        }).then(() => {});
+      },
+      openText(item) {
+        let message = `${item.employee_name}的考核指标已评分,不可调整结果值;如需调整,请联系绩效管理员`;
+        this.$dialog.alert({
+          message: message,
+        }).then(() => {});
+      },
+      confirmCreator(data) {
+        let userName = '';
+        this.userName = "全部人员"
+        this.employee_list = [];
+        if (data.employee !== null && data.employee.length != 0) {
+          data.employee.forEach(item => {
+            this.employee_list.push(item.id);
+            userName += (item.name + ',')
+          })
+          this.userName = userName;
         }
-      }
-      this.webSocket(parameterArr);
-    },
-    webSocket(data) {
-      this.resultList = data;
-      this.resultIndex = 0;
-      this.percentage = 0;
-      this.results = [];
-      this.isResult = true;
-      this.opneWebSocket();
-    },
-    opneWebSocket() {
-      let wsData = this.resultList;
-      if (wsData[this.resultIndex]) {
-        this.$axiosUser('post', '/api/pro/per/package/record_result', wsData[this.resultIndex]).then(res => {
-          this.onmessageWS(wsData[this.resultIndex],true);
-        }).catch(e=>{
-          let data=wsData[this.resultIndex];
-          data.msg=e.data.msg;
-          this.onmessageWS(data,false);
+        this.selected_data = data;
+        this.selectUser = false;
+        this.getPackageDtail();
+      },
+      downWgt(url, name) {
+        let self = this
+        if (!window.plus) {
+          window.open(url, '_blank');
+          return false
+        }
+        plus.downloader.createDownload(encodeURI(url), {
+            filename: '_doc/update/'
+          },
+          function(d, status) {
+            if (status == 200) {
+              plus.runtime.openFile(d.filename, {}, (err) => {
+                // console.log(JSON.stringify(err))
+              });
+            } else {
+              self.$toast.clear()
+              Notify({
+                type: 'danger',
+                message: '下载失败,请稍后重试',
+                duration: 1000
+              })
+            }
+          }
+        ).start()
+      },
+      openImg(imgs, index) {
+        let imgArr = imgs.map(item => {
+          return item.url
+        })
+        ImagePreview({
+          images: imgArr,
+          startPosition: index,
         });
+      },
+      // 返回布尔值
+      beforeRead(file) {
+        const isJPG = /^image\/(jpeg|png|jpg)$/.test(file.type);
+        // const isLt2M = file.size / 1024 / 1024 < 2;
+        if (!isJPG) {
+          this.$toast('上传图片只能是 jpeg|png|jpg 格式!');
+        }
+        // if (!isLt2M) {
+        //   this.$toast('上传图片大小不能超过 2MB!');
+        // }
+        return isJPG;
+      },
+      // 返回上一页
+      routerBak() {
+        this.$route_back();
+      },
+      rveno() {
+        // 取消
+        this.$route_back();
+      },
+      // 提交
+      save(num) {
+        let isLr = false;
+        let parameterArr = [];
+        let isPost = true;
+        let str = '';
+        this.selectList.some(item => {
+          let images = []; //图片
+          let result_info = [];
+          if (item.result_file.imgs) {
+            item.result_file.imgs.forEach(imgItem => {
+              let name = imgItem.split('/');
+              let obj = {
+                name: name[name.length - 1],
+                url: imgItem,
+              }
+              images.push(obj)
+            })
+          }
+          item.result_file.images = images;
 
-      }
-    },
-    onmessageWS(data,isJx) {
-      this.results.unshift(data);
-      this.resultIndex++;
-      if(!isJx){
-        return false
-      }
-      this.opneWebSocket();
-      // 进度条
-      let lng = this.resultList.length;
-      this.percentage += Math.floor(100 / lng);
-      if (lng == this.results.length) {
-        this.percentage = 100;
-      }
-    },
-    getPackageDtail() {
-      this.$axiosUser('get', '/api/pro/per/package/result_job_list', { pe_ids: this.peIds, page: 1, page_size: 2000,employee_ids:JSON.stringify(this.employee_list) }).then(res => {
-          let list = res.data.data.list;
-          let pe_flows=res.data.data.pe_flows;
-          let statusList = []; // 已录入指标
-          let noStatusList = []; // 未录入指标
-          list.forEach(item => {
-            let imgs=[];
-            if(item.result_file){
-              item.result_file.images.forEach(img => {
-                imgs.push(img.url);
-              })
-              item.result_file.imgs=imgs;
+          result_info.push({
+            dimension_key: item.dimension_id, //维度索引
+            index_key: item.index_key, //指标索引
+            index_id: item.index_id, //指标ID
+            result_file: item.result_file
+          });
+          if (item.index_type == 1) {
+            result_info[0].result = item.result_cache
+          }
+          let data = {
+            id: item.pe_id, //个人考核包ID
+            cache: num == 1 ? 1 : 0, // 是否暂存 1 是 0 否(提交)
+            info: item,
+            result_info: JSON.stringify(result_info),
+            sub: num == 3 ? 0 : 1
+          };
+
+          if (num == 3) {
+            if (item.isUpdate) {
+              if (item.index_type == 1) {
+                if (!item.result_cache) {
+                  isPost = false;
+                  str = item.index_name + ': 请输入结果值'
+                  return true
+                }
+                parameterArr.push(data);
+              } else {
+                if (item.result_file.append.length == 0 && item.result_file.images.length == 0) {
+                  isPost = false;
+                  str = item.index_name + ': 至少添加一份附件'
+                  return true
+                }
+                parameterArr.push(data);
+              }
             }
-            item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
-            let target=item.target? item.target+' '+item.unit:null;
-            item.dil = [
-              { lab: '考核标准', prop: item.index_standard ? item.index_standard : null},
-              { lab: '权重%', prop: item.index_weight ? item.index_weight : null },
-              { lab: '备注', prop: item.index_remark ? item.index_remark : null },
-              { lab: '目标值', prop: target },
-            ];
-
-            if (item.index_result_status == 1) {
-              noStatusList.push(item);
+          } else {
+            if (item.index_type == 1 && item.result_cache !== null && item.result_cache !== '') {
+              parameterArr.push(data);
             }
-            if (item.index_result_status == 2) {
-              item.isUpdate=true;
-              pe_flows.forEach(e=>{
-                if(e.pe_id==item.pe_id){
-                  item.isUpdate=this.returnIs(e.flow);
-                }
-              })
-              statusList.push(item);
+            if (item.index_type != 1 && (item.result_file.append.length > 0 || item.result_file.images.length >
+                0)) {
+              parameterArr.push(data);
             }
+          }
+        });
+        if (num == 3) {
+          if (!isPost) {
+            this.$toast(str);
+            return false;
+          }
+        } else {
+          if (parameterArr.length == 0) {
+            this.$toast.fail('至少输入一项结果值或非量化指标添加一份附件');
+            return false;
+          }
+        }
+        this.webSocket(parameterArr);
+      },
+      webSocket(data) {
+        this.resultList = data;
+        this.resultIndex = 0;
+        this.percentage = 0;
+        this.results = [];
+        this.isResult = true;
+        this.opneWebSocket();
+      },
+      opneWebSocket() {
+        let wsData = this.resultList;
+        if (wsData[this.resultIndex]) {
+          this.$axiosUser('post', '/api/pro/per/package/record_result', wsData[this.resultIndex]).then(res => {
+            this.onmessageWS(wsData[this.resultIndex], true);
+          }).catch(e => {
+            let data = wsData[this.resultIndex];
+            data.msg = e.data.msg;
+            this.onmessageWS(data, false);
           });
-          this.statusList = statusList;
-          this.noStatusList = noStatusList;
 
-          if (this.active == 0) {
-            this.rvenotList = JSON.parse(JSON.stringify(noStatusList));
-          } else if (this.active == 1) {
-            this.rvenotList = this.statusList;
-          }
-          let obj={},arr=[];
-          noStatusList.forEach(item=>{
-            if(obj[item.index_name]){
-              obj[item.index_name].push(item)
-            }else{
-              obj[item.index_name]=[item]
+        }
+      },
+      onmessageWS(data, isJx) {
+        this.results.unshift(data);
+        this.resultIndex++;
+        if (!isJx) {
+          return false
+        }
+        this.opneWebSocket();
+        // 进度条
+        let lng = this.resultList.length;
+        this.percentage += Math.floor(100 / lng);
+        if (lng == this.results.length) {
+          this.percentage = 100;
+        }
+      },
+      getPackageDtail() {
+        this.$axiosUser('get', '/api/pro/per/package/result_job_list', {
+            pe_ids: this.peIds,
+            page: 1,
+            page_size: 2000,
+            employee_ids: JSON.stringify(this.employee_list)
+          }).then(res => {
+            let list = res.data.data.list;
+            let pe_flows = res.data.data.pe_flows;
+            let statusList = []; // 已录入指标
+            let noStatusList = []; // 未录入指标
+
+            list.forEach(item => {
+              let imgs = [];
+              if (item.result_file) {
+                item.result_file.images.forEach(img => {
+                  imgs.push(img.url);
+                })
+                item.result_file.imgs = imgs;
+              }
+              item.isChecked = false;
+              item.dept_list = this.$getEmployeeMapItem(item.employee_id).employee_detail.dept_list;
+              let target = item.target ? item.target + ' ' + item.unit : null;
+              item.dil = [{
+                  lab: '考核标准',
+                  prop: item.index_standard ? item.index_standard : null
+                },
+                {
+                  lab: '权重%',
+                  prop: item.index_weight ? item.index_weight : null
+                },
+                {
+                  lab: '备注',
+                  prop: item.index_remark ? item.index_remark : null
+                },
+                {
+                  lab: '目标值',
+                  prop: target
+                },
+              ];
+
+              if (item.index_result_status == 1) {
+                noStatusList.push(item);
+              }
+              if (item.index_result_status == 2) {
+                item.isUpdate = true;
+                pe_flows.forEach(e => {
+                  if (e.pe_id == item.pe_id) {
+                    item.isUpdate = this.returnIs(e.flow);
+                  }
+                })
+                statusList.push(item);
+              }
+            });
+
+
+            this.statusList = statusList;
+            this.noStatusList = noStatusList;
+
+            if (this.active == 0) {
+              this.rvenotList = JSON.parse(JSON.stringify(noStatusList));
+            } else if (this.active == 1) {
+              this.rvenotList = this.statusList;
             }
-          })
-          for (let key in obj) {
-            arr.push(obj[key]);
-          }
-          arr.sort(function(a, b){return b.length - a.length});
-          let noStatusListDx=[]
-          arr.forEach(item=>{
-            noStatusListDx.push(...item);
-          })
-          this.noStatusListDx=noStatusListDx
 
 
+            let obj = {},
+              arr = [];
+            noStatusList.forEach(item => {
+              if (obj[item.index_name]) {
+                obj[item.index_name].push(item)
+              } else {
+                obj[item.index_name] = [item]
+              }
+            })
+            for (let key in obj) {
+              arr.push(obj[key]);
+            }
+            arr.sort(function(a, b) {
+              return b.length - a.length
+            });
+            let noStatusListDx = [];
+            arr.forEach(item => {
+              noStatusListDx.push(...item);
+            })
 
+            this.noStatusListDx = noStatusListDx
+            this.title1 = '未录入' + '(' + noStatusList.length + ')'
+            this.title2 = '已录入' + '(' + statusList.length + ')'
+            this.minFormactive[0].age = noStatusList.length; // 未
+            this.minFormactive[1].age = statusList.length; // 已
+            if (this.isUpdate) {
+              this.active = 1
+            }
+            this.initFilterData();
+          })
+          .finally(() => {
+            this.skeletonLoad = false;
+          });
+      },
+      uniqueArray(arr) {
+        return [...new Set(arr.map(item => JSON.stringify(item)))].map(item => JSON.parse(item));
+      },
 
-          this.minFormactive[0].age = noStatusList.length; // 未
-          this.minFormactive[1].age = statusList.length; // 已
-          if(this.isUpdate){
-            this.active=1
+      initFilterData() {
+        if(this.rvenotList && this.rvenotList.length > 0) {
+          this.user_list = [];
+          this.index_name_list = [];
+          this.index_standard_list = [];
+          this.target_list = [];
+          this.index_weight_list = [];
+          this.rvenotList.forEach(item => {
+            this.user_list.push(item.employee_name);
+            this.index_name_list.push(item.index_name);
+            this.index_standard_list.push(item.index_standard);
+            this.target_list.push(item.target);
+            this.index_weight_list.push(item.index_weight);
+          })
+          this.user_list = this.uniqueArray(this.user_list);
+          this.index_name_list = this.uniqueArray(this.index_name_list);
+          this.index_standard_list = this.uniqueArray(this.index_standard_list);
+          this.target_list = this.uniqueArray(this.target_list);
+          this.index_weight_list = this.uniqueArray(this.index_weight_list);
+        }
+      },
+      //判断评分节点是否有人评了分
+      returnIs(list) {
+        let is = true;
+        list.forEach(item => {
+          if (item.code == 'score_supervisor' || item.code == 'special_scorer') {
+            item.target.forEach(e => {
+              if (e.status == 2) {
+                is = false;
+              }
+            })
           }
         })
-        .finally(() => {
-          this.skeletonLoad = false;
-        });
+        return is
+      },
     },
-    //判断评分节点是否有人评了分
-    returnIs(list){
-      let is=true;
-      list.forEach(item=>{
-        if(item.code=='score_supervisor'||item.code=='special_scorer'){
-          item.target.forEach(e=>{
-            if(e.status==2){
-              is=false;
-            }
-          })
-        }
-      })
-      return is
+    created() {
+      if (this.peIds) {
+        this.getPackageDtail();
+      }
+
     },
-  },
-  created() {
-    if (this.peIds) {
-      this.getPackageDtail();
-    }
-  },
-};
+  };
 </script>
 
 <style scoped lang="less">
-.userName{
-  position: absolute;
-  left: 0%;
-  height: 50px;
-  width: 100%;
-  opacity: 0;
-}
-.results {
-  border-bottom: 1px solid #f1f1f1;
-  text-align: center;
-  font-size: 0.24rem;
-}
-.results div {
-  padding: 10px;
-}
-.line-feed {
+  .userName {
+    position: absolute;
+    left: 0%;
+    height: 50px;
+    width: 100%;
+    opacity: 0;
+  }
+
+  .results {
+    border-bottom: 1px solid #f1f1f1;
+    text-align: center;
+    font-size: 0.24rem;
+  }
+
+  .results div {
+    padding: 10px;
+  }
+
+  .line-feed {
     white-space: pre-wrap;
-}
-.all {
-  height: calc(100% - 3.16rem);
-  position: relative !important;
-  background-color: #f5f7fa;
-  padding-bottom: 0.3rem;
-  overflow-y: scroll;
-}
-header {
-  background-color: #fff;
-  font-size: 0.3rem;
-  z-index: 1;
-}
-.isIos {
-  height: calc(100% - 3.6rem);
-}
-
-footer {
-  background-color: #ffffff;
-  z-index: 999;
-  border-top: 1px solid #e2e2e2;
-  padding: 0.1rem;
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  .footfoot {
-    .footcol {
-      text-align: center;
-    }
-    .footBut {
-      display: flex;
+  }
+
+  .all {
+    flex: 1;
+    position: relative !important;
+    background-color: #f5f7fa;
+    padding-bottom: 0.3rem;
+    overflow-y: scroll;
+  }
+
+  header {
+    width: 100%;
+    height: 0.8rem;
+    font-size: 0.3rem;
+    z-index: 1;
+  }
+
+  .isIos {
+    height: calc(100% - 3.6rem);
+  }
+
+  footer {
+    width: 100%;
+    background-color: #fff;
+    border-top: 1px solid #e2e2e2;
+    padding: 0.1rem;
+
+    .footfoot {
+      .footcol {
+        text-align: center;
+      }
+
+      .footBut {
+        display: flex;
+      }
+
     }
-    .footcolButno {
-      border: 1px solid #42a8ff;
-      width: 1.4rem;
+  }
+
+  .footcolButno {
+    border: 1px solid #42a8ff;
+    width: 1.4rem;
+    height: 0.8rem;
+    font-size: 0.28rem;
+    color: #2f9eff;
+    background-color: #ffffff;
+    border-top-left-radius: 3px;
+    border-bottom-left-radius: 3px;
+  }
+
+  .footcolButok {
+    border: 0;
+    width: 1.4rem;
+    height: 0.8rem;
+    font-size: 0.28rem;
+    color: #fff;
+    background-color: #42a8ff;
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+  }
+
+  .tab-box {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-bottom: 0.01rem solid #f5f7fa;
+    font-size: 0.28rem;
+
+    .tab-item {
+      flex: 1;
       height: 0.8rem;
-      font-size: 0.28rem;
-      color: #2f9eff;
-      background-color: #ffffff;
-      border-top-left-radius: 3px;
-      border-bottom-left-radius: 3px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
     }
-    .footcolButok {
-      border: 0;
-      width: 1.4rem;
-      height: 0.8rem;
-      font-size: 0.28rem;
-      color: #fff;
-      background-color: #42a8ff;
-      border-top-right-radius: 3px;
-      border-bottom-right-radius: 3px;
+  }
+
+
+
+  .popup-title {
+    width: 100%;
+    height: 0.6rem;
+    line-height: 0.6rem;
+    font-weight: 600;
+    font-size: 0.28rem;
+    margin-bottom: 10px;
+    text-align: center;
+  }
+
+  .filter-options-box {
+    width: 100%;
+    height: 8rem;
+    background-color: white;
+    position: absolute;
+    top: 1rem;
+    left: 0;
+  }
+
+  .batch-operate {
+    width: 100%;
+    background-color: white;
+    height: 1rem;
+    font-size: 0.28rem;
+    color: rgb(146, 146, 146);
+    display: flex;
+    align-items: center;
+    box-sizing: border-box;
+  }
+
+
+  .dropdown-item-title {
+    margin-bottom: 10px;
+    padding: 0 0 0 10px;
+    color: rgb(146, 146, 146);
+    font-size: 0.27rem;
+  }
+
+  .dropdown-item-content-list {
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    padding: 0 10px;
+    margin-bottom: 10px;
+    box-sizing: border-box;
+
+    .dropdown-item-content {
+      flex: 0 0 calc((100% - 10px)/3);
+      height: 0.48rem;
+      line-height: 0.48rem;
+      background: #F5F7FA;
+      border-radius: 0.28rem;
+      color: rgb(146, 146, 146);
+      font-size: 0.27rem;
+      text-align: center;
+      margin: 0 5px 5px 0;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+      overflow: hidden;
+      transition: 0.3s;
+      padding: 0 0.24rem;
+      box-sizing: border-box;
+
+      &.active {
+        background: #42a8ff;
+        color: white;
+      }
+
+      &:nth-child(3n) {
+        /* 去除第3n个的margin-right */
+        margin-right: 0;
+      }
     }
   }
-}
+
+  .van-dropdown-item {
+    position: relative;
+  }
+
+  .btn-container {
+    width: 100%;
+    background-color: #fff;
+    display: flex;
+    justify-content: space-around;
+    border-top: 0.01rem solid #f5f7fa;
+    padding: 10px 0;
+    box-sizing: border-box;
+    z-index: 10;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+  }
+
+  .disabled {
+    color: #bbb;
+    border-color: #bbb;
+  }
 </style>

+ 35 - 6
src/performance/components/performanceDetails.vue

@@ -1,6 +1,8 @@
 <template>
   <div :class="[{ bg_fff: skeletonLoad }]">
-    <van-nav-bar :title="detailsTIt" left-arrow @click-left="routerBak" />
+    <van-nav-bar :title="detailsTIt" left-arrow @click-left="routerBak">
+      <div v-if="!isDetails" slot="right" @click="handleClick()" style="color: #fff;">筛选<van-icon name="list-switch" /></div>
+    </van-nav-bar>
     <div v-if="isDisabled && !graded" class="upDownList flex-box flex-d-center">
       <div class="uDownBut font-flex-word" style="" v-for="(item, index) in headuDown" :key="index" @click="uDownCli(item)">
         <span v-if="!item.id" style="color: #a2a2a2;">已无待办</span>
@@ -17,7 +19,7 @@
             <scroller :isNeed="isNeed">
               <div :style="isDisabled ? 'padding-bottom: 3rem;' : 'padding-bottom: 2rem;'">
                 <header>
-                  <div class="flex-box-ce">
+                  <div class="flex-box-ce" style="position: relative;">
                     <userImage
                       class="about-me__avatar"
                       :id="Information.id"
@@ -28,10 +30,11 @@
                       height=".75rem"
                       style="margin-top:.1rem;"
                     ></userImage>
-                    <div style="padding:.1rem 0 0 .25rem;">
+                    <div style="padding:.1rem 0 0 .25rem; box-sizing: border-box;">
                       <span style="font-size:.28rem;color:black;">{{ Information.name }}</span>
+                      <span v-if="okrs && okrs.length > 0" class="okr-tips" @click="goMyTarget">查看okr</span>
                       <br />
-                      <span class="font-flex-word" style="width: 4.4rem;display:inline-block;" v-if="Information.employee_detail&&Information.employee_detail.dept_list.length>0">
+                      <span class="font-flex-word" style="width: 4.4rem;display:inline-block;" v-if="Information.employee_detail && Information.employee_detail.dept_list.length>0">
                         <span class="pdHeadDept" v-for="(arr, att) in Information.employee_detail.dept_list" :key="att">
                           {{ arr.dept_name }}
                           <span v-if="Information.employee_detail.dept_list.length - att > 1">,</span>
@@ -132,7 +135,7 @@
                       <span v-if="item.schedule && item.schedule.length > 0" style="font-size: .28rem;padding-right:.2rem;color:#1d96ff;" @click="openPlanPath(item, 'action')">
                         执行计划({{ item.schedule.length }})
                       </span>
-                      <span v-if="item.mamage_record && item.mamage_record.length > 0" style="font-size:.26rem;color:rgb(29, 150, 255);" @click="openPlanPath(item, 'admnin')">
+                      <span v-if="item.mamage_record && item.mamage_record.length > 0" style="font-size:.26rem; color:rgb(29, 150, 255);" @click="openPlanPath(item, 'admnin')">
                         管理记录({{ item.mamage_record.length }})
                       </span>
                     </div>
@@ -290,7 +293,7 @@
           </div>
         </template>
     </template>
-    <resultValueEntryMb v-else :peIds="pe_ids" :isUpdate="isUpdate"></resultValueEntryMb>
+    <resultValueEntryMb v-else ref="result-mb" :peIds="pe_ids" :isUpdate="isUpdate"></resultValueEntryMb>
 
     <van-dialog v-model="isShowE" :show-cancel-button="false">
       <div style="padding: 10px;font-size: 0.28rem;">
@@ -649,6 +652,7 @@ export default {
       logList: [],
       apDetails: {},
       resultStr:'录入结果值',
+      okrs: [], // 已关联的OKR
     };
   },
   computed: {
@@ -678,6 +682,12 @@ export default {
     }
   },
   methods: {
+    handleClick() {
+      this.$refs["result-mb"].isFilterShow = true;
+    },
+    goMyTarget() {
+      this.$router.push({name: 'myTarget', query: {ids: JSON.stringify(this.okrs)}});
+    },
     copyPoin(item){
       if(item.auto_score<0||item.auto_score===0){
         item.resultval='0';
@@ -825,6 +835,7 @@ export default {
       this.$axiosUser('get', '/api/pro/per/package/employee/info', params).then(res => {
         if (res.data.code == 1) {
           let data = res.data.data;
+          this.okrs = data.okrs || [];
           this.has_finish = data.has_finish;
           if (this.pendingList.length > 0) {
             this.setUpD();
@@ -1765,6 +1776,7 @@ export default {
       this.planIndex = index;
       this.openTrackPath('admnin');
     },
+
     // 管理记录||执行计划
     openTrackPath(add) {
       let data = {
@@ -2086,6 +2098,22 @@ export default {
 </script>
 
 <style scoped lang="less">
+  .okr-tips {
+    position: absolute;
+    top: 0;
+    right: 0;
+    height: 0.38rem;
+    font-size: 0.27rem;
+    padding: 0.1rem 0.25rem;
+    border-top-left-radius: 0.05rem;
+    border-bottom-left-radius: 0.05rem;
+    display: -webkit-box;
+    display: -ms-flexbox;
+    display: flex;
+    color: #26a2ff;
+    background-color: #ecf5ff;
+  }
+
 .apdList {
   background-color: #fff;
 }
@@ -2240,6 +2268,7 @@ header {
   padding: 0.3rem 0 0.3rem 0.3rem;
   font-size: 0.3rem;
   z-index: 1;
+  box-sizing: border-box;
   .pdHeadDept {
     color: rgb(117, 117, 117);
     padding-top: 0.03rem;

+ 2 - 1
src/performance/components/workbenchcontent/backlog.vue

@@ -48,7 +48,7 @@
               </div>
             </div>
           </template>
-
+          <div style="height: 0.5rem;"></div>
         </scroller>
         <scroller v-show="type=='entering'" ref="work_bench_scroller2" class="all2" :on-refresh="refresh2" :on-infinite="infinite2" noDataText="我也是有底线的" :list="enteringList">
             <div>
@@ -66,6 +66,7 @@
                 </van-row>
               </div>
               <van-empty description="暂无绩效考核数据" v-if="enteringList.length == 0" />
+              <div v-else style="height: 0.5rem;"></div>
             </div>
         </scroller>
       </template>

+ 1 - 1
src/performance/utils/auth.js

@@ -32,7 +32,7 @@ import {getUserData} from '@/utils/auth'
 export function getRole(type) {
   /* type为判断哪些角色*/
 
-  var role = window.plus ? plus.storage.getItem('role') : localStorage.getItem('role')
+  var role = window.plus ? JSON.parse(plus.storage.getItem('role')) : JSON.parse(localStorage.getItem('role'))
   let is = false;
   switch (type) {
     case 1: // 判断是否是主子管理员

+ 863 - 0
src/performance/view/myTarget/krDetail.vue

@@ -0,0 +1,863 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="KR详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all-box" style="height: calc(100% - 0.92rem);position: relative;">
+      <template >
+        <header class="header">
+          <div class="flex-box">
+            <div class="flex-1" style="font-weight: 600;padding: 0 0.2rem;padding-left: 0.1rem;">{{krDetail.name}}</div>
+          </div>
+          <div class="flex-box-ce fontColorC header-message" style="font-size: 0.26rem;margin-top:0.14rem">
+            <userImage :img_url="krDetail.owner_userInfo.img_url" :user_name="krDetail.owner_userInfo.name" width="0.7rem" height="0.7rem"></userImage>
+            <span>{{ krDetail.owner_userInfo.name }}</span>
+            <van-icon name="star" class="yellow"/>
+            <span>{{krDetail.confident}}分</span>
+            <van-circle layer-color="#E5E9F2" v-model="krDetail.currentRate" :color="krDetail.risk_level==2? '#FF9600':krDetail.risk_level==3? '#f56c6c':' #2879ff'" :rate="krDetail.process" :stroke-width="120" size="20px"/>
+            <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:krDetail.risk_level==2,red:krDetail.risk_level==3}">{{ krDetail.process }}%</span>
+          </div>
+        </header>
+        <div class="scroller">
+          <div class="box" style="border-bottom: 0.2rem solid #f5f7fa;">
+              <div class="title">基本信息</div>
+              <div class="flex-box"><div class="label flex-1">发布人</div><div>{{$getEmployeeMapItem(krDetail.publisher_id).name}}</div></div>
+              <div class="flex-box"><div class="label flex-1">KR权重</div><div>{{krDetail.weight}}%</div></div>
+              <div class="flex-box"><div class="label flex-1">起止时间</div>
+                <div>{{krDetail.start_time}}~{{krDetail.end_time}}</div>
+                <template v-if="krDetail.o_composite_state!=6">
+                  <span v-if="krDetail.day>0" style="padding-left: 0.14rem;">剩余<span class="green">{{krDetail.day}}</span>天</span>
+                  <span v-if="krDetail.day<0" style="padding-left: 0.14rem;">过期<span class="red">{{Math.abs(krDetail.day)}}</span>天</span>
+                </template>
+              </div>
+              <div class="flex-box"><div class="label flex-1">KR评分</div>
+                  <span v-if="krDetail.score===-0.1" class="fontColorC">暂未评分</span>
+                  <span v-else>{{krDetail.score}}分</span>
+              </div>
+              <div class="flex-box">
+                <div class="label flex-1">评分说明</div>
+                <span v-if="krDetail.score_detail" style="max-width: 5.6rem;">{{krDetail.score_detail}}</span>
+                <span v-else class="fontColorC">暂无说明</span>
+              </div>
+              <div class="flex-box">
+                <div class="label">子目标</div>
+                <div class="flex-1" style="text-align: right;">
+                  <span v-if="krOs.length==0" class="fontColorC">暂无子目标</span>
+                  <div v-else class="hoverBlue" style="margin-bottom: 5px;text-align: right;" v-for="(item, index) in krOs" :key="index">
+                    {{item.name}}
+                  </div>
+                </div>
+              </div>
+          </div>
+          <van-tabs v-model="tabActive" class="shadow">
+            <van-tab :title="item.title" :name="item.name" :disabled="item.disabled" v-for="(item, index) in tabs" :key="index"></van-tab>
+            </van-tabs>
+          <div style="margin-top: 0.2rem;">
+            <template v-if="tabActive==1">
+              <div class="list-box" v-for="(item, index) in krsListAll" :key="index">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;border-bottom: 1px solid #f1f1f1;padding-bottom: 0.2rem;">
+                  <span class="flex-1" style="font-size: 0.26rem;" v-if="item.plans.length>0">计划任务<span class="blue">{{returnSum(item.plans)}}</span>/<span>{{item.plans.length}}</span></span>
+                </div>
+                <div style="padding:0 0.1rem;">
+                  <template v-if="item.projects.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index3) in item.projects" :key="task_item.id" @click="openDetail(task_item,3)">
+                        <van-icon name="paid" class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"/>
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD')}} 截止</span>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <template v-if="item.plans.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index2) in item.plans" :key="index2" @click="openDetail(task_item,1)">
+                        <van-icon :name="taskStatus(task_item.composite_state).icon"
+                        class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"
+                        :class="(task_item.day<=0&&$moment(task_item.end_date).format('YYYY-MM-DD')!=$moment().format('YYYY-MM-DD')) ? 'red':''"
+                        />
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD HH:mm')}} 截止</span>
+                            <template v-if="task_item.statistics.plan_total">
+                              <van-icon name="orders-o" />
+                              <span style="font-size: 0.26rem;">
+                                <span class="blue">{{task_item.statistics.plan_finish}}</span>/<span>{{task_item.statistics.plan_total}}</span>
+                              </span>
+                            </template>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <div v-if="item.projects.length==0&&item.plans.length==0" style="text-align: center;margin: 0.2rem 0;font-size: 0.28rem;" class="fontColorC">用“任务”推动目标达成,合理规划安排工作</div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive==2">
+              <Evolve v-if="kr_id" :isOperation="isOperation && !krDetail.process_conf.enable_automatic && krDetail.can_edit" readonly :process="Number(krDetail.process)" :target_id="Number(kr_id)" :target_type="2" style="padding: 0 0.2rem;"></Evolve>
+            </template>
+          </div>
+          <div style="height: 3rem;"></div>
+        </div>
+        <!-- <div class="aite" @click="openCommunication"><van-icon name="more" class="fontColorB" /></div> -->
+        <footer class="footer">
+          <div class="flex-box-ce" v-if="isOperation">
+            <van-icon name="chat-o" @click="openCommunication" style="margin-left: 0.2rem;font-size:0.6rem;" class="fontColorC"/>
+          </div>
+          <div v-else class="fontColorC gt" @click="openCommunication">有事沟通,可@Ta</div>
+        </footer>
+      </template>
+
+    </div>
+    <!-- 关联任务 -->
+    <TaskSearch :visible.sync="isShwoTaskSearch" @confirm="ActiveRelevanceTask"></TaskSearch>
+
+    <!-- 修改KR -->
+    <van-popup v-model:show="isShowUpdateKr" round position="bottom" :style="{ height: '90%',background:'#fff' }" @close="isShowUpdateKr=false">
+       <div>
+         <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+           <div class="blue" @click="isShowUpdateKr=false">取消</div>
+           <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">编辑</div>
+           <div class="blue" @click="confirmUpdateKr">确定</div>
+         </header>
+         <div>
+           <van-field v-model="form.name" rows="3"  type="textarea" maxlength="100"  placeholder="书写建议:KR是可量化的,需要体现行动效果"  show-word-limit/>
+           <van-cell title="开始时间" is-link :value="form.start_date" @click="openTime(1)" />
+           <van-cell title="截止时间" is-link :value="form.end_date" @click="openTime(2)"/>
+           <van-cell title="负责人" is-link @click="openSelectUser(2)"><div>{{form.owner_name}}</div></van-cell>
+           <van-cell title="信心指数" is-link @click="isShowSelectConfidence=true"><div>{{form.confident}}分</div></van-cell>
+         </div>
+       </div>
+    </van-popup>
+    <!-- 信心 -->
+    <van-action-sheet v-model="isShowSelectConfidence">
+      <div>
+        <van-picker show-toolbar :columns="pointArr"  @change="onChange" value-key="name" item-height="50px" @confirm="onConfirmConfidence" @cancel="isShowSelectConfidence = false">
+          <template #columns-top>
+              <div style="font-weight: 600;font-size: 0.34rem;text-align: center;">{{pointName}}</div>
+          </template>
+          <template #option="option">
+              <div class="flex-box-ce">
+                <van-rate v-model="option.value" allow-half :size="22" color="#ffd21e" void-icon="star" void-color="#eee" readonly />
+                <div style="padding-left: 0.2rem;">{{option.name}}</div>
+              </div>
+          </template>
+        </van-picker>
+      </div>
+    </van-action-sheet>
+
+    <!-- 选择时间 -->
+    <van-action-sheet v-model="isShowSelectTime">
+      <van-datetime-picker @cancel="isShowSelectTime=false" @confirm="selectConfirm" v-model="currentDate" type="date" :title="timeIndex==1? '开始时间':'截止时间'" :min-date="minDate" :max-date="maxDate"/>
+    </van-action-sheet>
+    <!-- 权重 -->
+    <van-popup v-model:show="isShowUpdateWeight" round position="bottom" :style="{ height: '90%', background: '#fff' }" @close="isShowUpdateWeight=false">
+      <div>
+        <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+          <div class="blue" @click="isShowUpdateWeight=false">取消</div>
+          <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">编辑权重</div>
+          <div class="blue" @click="confirmWeight">确定</div>
+        </header>
+        <div class="wInput">
+            <van-field v-for="(item, index) in krsList" :key="index" v-model="item.weight" input-align="right" @input="[(item.weight = item.weight.match(/\d+(\.\d{0,2})?/) ? item.weight.match(/\d+(\.\d{0,2})?/)[0] : '')]">
+                <template #label>
+                  <div>
+                    <span class="blue" style="padding-right: 3px;">KR{{index+1}}</span>
+                    <span>{{item.name}}</span>
+                  </div>
+                </template>
+                <template #right-icon> <span>%</span></template>
+            </van-field>
+            <div class="flex-box-ce flex-box-end" style="padding:0.24rem 0.32rem;">
+                <div class="updateprocess" @click="pingJun">平均权重</div>
+                <div class="fontColorC" style="margin-left: 0.2rem;font-size: 0.28rem;">总权重:{{getKrWeight}}%</div>
+            </div>
+        </div>
+      </div>
+    </van-popup>
+
+    <!-- 人员选择 -->
+    <EmployeeSelector  :isRequired="true" title="选择人员" :visible.sync="selectUser" @confirm="confirmUser" :can_select_dept="false" :multi="false" :selected.sync="selected_user"></EmployeeSelector>
+
+    <!-- 进度 -->
+    <Progress :visible.sync="isShwoUpdateProgress" :progressData="progressData" @confirm="update"></Progress>
+
+    <!-- 选择 -->
+    <van-action-sheet v-model="isShowbelong" :actions="scopeArr" @select="activebelong" cancel-text="取消" close-on-click-action/>
+    <!-- 评分 -->
+    <van-popup v-model:show="isShowUpdatePoint" round position="bottom" :style="{ height: '90%', background: '#fff' }" @close="isShowUpdatePoint=false">
+      <div>
+        <header class="flex-box-ce" style="text-align: center;font-size: 0.32rem;padding: 0.2rem;">
+          <div class="blue" @click="isShowUpdatePoint=false">取消</div>
+          <div class="flex-1" style="font-weight: 700;font-size: 0.36rem;">KR评分</div>
+          <div class="blue" @click="confirmPoint">确定</div>
+        </header>
+        <div>
+          <van-field label="评分"  ref="input" input-align="right" placeholder="评分(0~10)" type="digit" v-model.trim="pointData.score"> <template #right-icon><span>分</span></template></van-field>
+          <van-field v-model="pointData.score_detail" rows="3" type="textarea" maxlength="500" placeholder="请输入评分说明" show-word-limit />
+          <van-cell title="@ta查看" is-link @click="openSelectUser(1)">
+              <div v-if="employees.length>0">
+                  <span v-for="(item, index) in employees" :key="index">{{ item.name }}<span v-if="employees.length - index > 1">,</span></span>
+              </div>
+              <span v-else class="input-ccc">请选择</span>
+          </van-cell>
+        </div>
+      </div>
+    </van-popup>
+    <!-- @人员 -->
+    <EmployeeSelector title="人员"  :visible.sync="selectUserAll" @confirm="confirmCreator" :selected.sync="selected_user_all"
+      :can_select_dept="false" :dept_multi="false" :append_body="true" :isShowDepts="false"
+    />
+
+    <!-- 可见范围 -->
+    <van-action-sheet v-model="isShowV" :actions="vArr" @select="activevArr" cancel-text="取消" close-on-click-action/>
+
+    <!-- 关联KR -->
+    <TargetSearch :visible.sync="isShwoKrSearch" :showSelectType="2" @confirm="ActiveRelevanceKr"></TargetSearch>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import {Circle,ActionSheet,Rate,Picker,DatetimePicker,Tab, Tabs, } from 'vant';
+Vue.use(Circle).use(ActionSheet).use(Rate).use(Picker).use(DatetimePicker).use(Tabs).use(Tab);
+
+import Evolve from '@/okr/components/public/Evolve';
+import Progress from '@/okr/components/public/Progress';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import {getOperation,taskStatus} from '@/okr/utils/auth';
+import TaskSearch from '@/okr/components/public/TaskSearch';
+import TargetSearch from '@/okr/components/public/TargetSearch';
+
+export default {
+  components:{Progress,EmployeeSelector,Evolve,TaskSearch,TargetSearch},
+  name: 'krDetail',
+  data() {
+    return {
+      taskStatus:taskStatus,
+      isShowbelong:false,
+      isShwoUpdateProgress:false,
+      isShowSelectConfidence:false,
+      isShowUpdatePoint:false,
+      isShowUpdateKr:false,
+      isShowSelectTime:false,
+      isShowUpdateWeight:false,
+      pointData:{kr_id:'',score:'',score_detail:'',to_employee_id:[]},
+      employees:[],
+      selectUserAll:false,
+      selected_user_all: { dept: [], employee: [] },//参与人员
+      selectUser:false,
+      selected_user: { dept: [], employee: [] },//参与人员
+      userInfo: this.$userInfo(),
+      currentDate:'',
+      timeIndex:1,
+      pointArr:[
+        {name:'1分',value:0.5,code:'1'},
+        {name:'2分',value:1,code:'1'},
+        {name:'3分',value:1.5,code:'2'},
+        {name:'4分',value:2,code:'2'},
+        {name:'5分',value:2.5,code:'3'},
+        {name:'6分',value:3,code:'3'},
+        {name:'7分',value:3.5,code:'4'},
+        {name:'8分',value:4,code:'4'},
+        {name:'9分',value:4.5,code:'5'},
+        {name:'10分',value:5,code:'5'},
+      ],
+      minDate: new Date(2020, 0, 1),
+      maxDate: new Date(2050, 10, 1),
+      columns:[],
+      krsList:[],
+      form:{
+        name:'',
+        owner_id:'',
+        owner_name:'',
+        confident:'',
+        start_date:'',//	是	string	开始日期,格式:2022-01-01
+        end_date:'',//	是	string	结束日期,格式:2022-01-01
+      },
+      scopeArr:[{
+          value: 1,
+          name:'KR 评分',
+          disabled: false
+        },
+        {
+          value: 2,
+          name:'更新完成度',
+          disabled: false
+        },
+        {
+          value: 3,
+          name:'编辑基本信息',
+          disabled: false
+        },
+        {
+          value: 4,
+          name:'编辑权重',
+          disabled: false
+        },
+        {
+          value: 5,
+          name:'删除KR',
+          color: '#f56c6c',
+          disabled: false
+        }
+      ],
+      processList: [],
+      kr_id:0,
+      krDetail:{owner_userInfo:{},process:0,publisher_userInfo:{},visible:1,process_conf:{}},
+      krOs:[],
+      progressData:{},
+      sumWeight:0,
+      isOperation:true,
+      pointNameArr:[
+        {name:'不可能完成',code:'1'},
+        {name:'很难完成,需要帮助',code:'2'},
+        {name:'有挑战,可以尝试',code:'3'},
+        {name:'有信心完成',code:'4'},
+        {name:'轻松完成',code:'5'},
+      ],
+      pointName:'不可能完成',
+      tabActive: 0,
+      tabs: [
+        {title:'计划',name:1,disabled:false},
+        {title:'进展',name:2,disabled:false},
+        {title:'',name:0,disabled:true}
+      ],
+      krsListAll:[],//包括任务
+      isShwoTaskSearch:false,
+
+      // 可见范围
+      isShowV:false,
+      vArr:[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}],
+      addTaskIndex:1,
+      selectKr:{},
+      isShwoKrSearch:false,
+    };
+  },
+  computed:{
+    getKrWeight(){
+      let sumWeight=0;
+      this.krsList.forEach(item=>{
+        sumWeight+=Number(item.weight)
+      })
+      this.sumWeight= Math.round(sumWeight)
+      return this.sumWeight
+    }
+  },
+  watch:{
+    tabActive(val){
+      if(val==1){
+        this.getkrTaskList();
+      }
+    },
+  },
+  mounted() {
+    if(this.$route.query.id){
+      this.kr_id=this.$route.query.id;
+      this.getKrDetail();
+    }
+  },
+  activated() {
+  	this.getkrTaskList();
+  },
+  methods: {
+    openDetail(item,type){
+      if(type==1){
+        this.$router.push({name: 'taskDetail', query: {id: item.id, readonly: 1}})
+      }else if(type==3) {
+        return
+        this.$router.push({name: 'projectDetail', query: {id: item.id}})
+      }
+    },
+    //执行
+    getkrTaskList(){
+      if(!this.krDetail.o_id){return false}
+      let data={
+        o_id:this.krDetail.o_id,//	是	string	目标id
+        kr_ids:this.kr_id,
+        plan_calc:1,
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/plan/list/o',data).then(res => {
+        let list=res.data.data.list;
+        list.forEach(e=>{
+          if(e.plans&&e.plans.length>0){
+            e.plans.forEach(item=>{
+              item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
+            })
+          }
+        })
+        this.krsListAll=list;
+      })
+    },
+    //关联母任务
+    ActiveRelevanceTask(item){
+        if(item.id){
+          this.$axiosUser('POST', '/api/pro/okr/plan/relate/other',{plan_id:item.id,target_type:2,target_id:this.kr_id}).then(res => {
+               this.getkrTaskList();
+          })
+        }
+    },
+    //关联项目
+    ActiveRelevanceKr(item){
+      this.$axiosUser('post', '/api/pro/okr/project/bind',{project_id:item.item.id,kr_id:this.selectKr.id}).then(res => {
+           this.getkrTaskList();
+      });
+    },
+    activevArr(item){
+      if(this.addTaskIndex==1){
+        if(item.value==1){
+          let data={
+            target_type:	2,//是	string	计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
+            target_id:this.selectKr.id,//是	integer	绑定的对象id 跟对象种类配对使用
+          }
+          this.$router.push({name: 'addTask', query: data})
+        }else{
+          this.$router.push({name: 'addProject', query: {kr_id:this.selectKr.id}})
+        }
+      }else{
+        if(item.value==1){
+            this.kr_id=this.selectKr.id;
+            this.isShwoTaskSearch=true;
+        }else{
+            this.isShwoKrSearch=true;
+        }
+      }
+    },
+    addTask(item,index){
+      this.addTaskIndex=index;
+      this.selectKr=item;
+      if(index==1){
+        this.vArr=[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}];
+      }else{
+        this.vArr=[{value: 1,name: '关联任务'},{value: 2,name: '关联项目'}];
+      }
+      this.isShowV=true;
+    },
+    returnSum(arr){
+      if(arr.length==0){return 0};
+      let sum=0;
+      arr.forEach(item=>{
+        if(item.composite_state==6){
+          sum++;
+        }
+      })
+      return sum
+    },
+    onChange(e,val) {
+      this.pointNameArr.some(item=>{
+        if(val.code==item.code){
+          this.pointName=item.name
+          return true
+        }
+      })
+    },
+    pingJun(){
+      let weight=Math.floor((100/(this.krsList.length)) * 100) / 100
+      this.krsList.forEach(item=>{
+         item.weight=weight
+      })
+    },
+    // 沟通
+    openCommunication(){
+      let data = {
+        item: JSON.stringify(this.krDetail),
+        target_type:2,
+        readonly: 1
+      }
+      this.$router.push({name: 'communication', query: data})
+    },
+    update(){
+      this.getKrDetail();
+    },
+    //更新完成度
+    updateProgress(){
+        let item=this.krDetail;
+        this.progressData={
+          target_type:2,
+          id:item.id,
+          process:Number(item.process),
+          risk_level:item.risk_level,
+          process_conf:item.process_conf,
+        }
+        this.isShwoUpdateProgress=true;
+    },
+    //目标详情
+    getTargetDateil(){
+      this.$axiosUser('get', '/api/pro/okr/public/obj/detail',{object_id:this.krDetail.o_id}).then(res => {
+        let data=res.data.data;
+        if(!data.can_edit){ //不可编辑权重
+          this.scopeArr.forEach(item=>{
+            if(item.value==4){item.disabled=true}
+          })
+        }
+      })
+    },
+    //KR详情
+    getKrDetail(){
+      this.krOs=[];
+      this.krDetail={owner_userInfo:{},process:0,publisher_userInfo:{},visible:1,process_conf:{}};
+      if(!this.kr_id){return false}
+      this.$axiosUser('get', '/api/pro/okr/public/kr/detail',{kr_id:this.kr_id}).then(res => {
+          let data=res.data.data;
+          data.owner_userInfo=this.$getEmployeeMapItem(data.owner_id);
+          data.publisher_userInfo=this.$getEmployeeMapItem(data.publisher_id);
+          data.day=this.$moment(data.end_time).diff(this.$moment().format('YYYY-MM-DD'), 'day');
+          this.isOperation=getOperation(data.publisher_id,data.owner_id);
+          if(data.statistics.sub_o_total>0){
+            this.getKrTarget(data.id);
+          }
+          this.krDetail=data;
+          if(!data.can_edit){ //不可编辑
+            this.scopeArr.forEach(item=>{
+              if(item.value==3){item.disabled=true}
+            })
+          }
+          if(!this.isOperation){ //完成度
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){item.disabled=true}
+            })
+          }
+          if(!data.can_score){ //不可评分
+            this.scopeArr.forEach(item=>{
+              if(item.value==1){item.disabled=true}
+            })
+          }
+          if(!data.can_delete){ //不可删除
+            this.scopeArr.forEach(item=>{
+              if(item.value==5){item.disabled=true}
+            })
+          }
+          this.getTargetDateil();
+      }).finally(()=>{
+          if(!this.tabActive){
+            this.tabActive=1;
+          }
+      })
+    },
+    //kr 子目标列表
+    getKrTarget(id){
+      this.$axiosUser('get', 'api/pro/okr/public/kr/sub/list', {kr_id:id}).then(res => {
+        this.krOs=res.data.data.os;
+      })
+    },
+    deletekr(){
+      if(this.krsList.length==0){
+        this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.krDetail.o_id}).then(res => {
+            let list=res.data.data.list;
+            if(list.length==1){
+              this.$toast('当前KR为最后一个,不能删除')
+              return false
+            }else{
+              this.$axiosUser('POST', '/api/pro/okr/kr/d',{kr_id:this.kr_id}).then(res => {
+                  setTimeout(()=>{
+                    this.$toast('已删除')
+                    this.$route_back()
+                  },500)
+              })
+            }
+        })
+        return false
+      }else if(this.krsList.length==1){
+        this.$toast('当前KR为最后一个,不能删除')
+        return false
+      }
+      this.$axiosUser('POST', '/api/pro/okr/kr/d',{kr_id:this.kr_id}).then(res => {
+            setTimeout(()=>{
+              this.$toast('已删除')
+              this.$route_back()
+            },500)
+      })
+    },
+    confirmWeight(){
+      let sumWeight=0;
+      let krs=[]
+      this.krsList.forEach(item=>{
+          sumWeight+=Number(item.weight);
+          krs.push({id:item.id,weight:item.weight*100})
+      })
+      sumWeight=Math.round(sumWeight);
+      // if(sumWeight!=100){
+      //    this.$toast("KR权重总和要为100");
+      //    return false
+      // }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_weight',{object_id:this.krDetail.o_id,kr:JSON.stringify(krs)}).then(res => {
+        if(this.krDetail.o_id){ //kr详情调整权重
+          this.getKrDetail();
+        }
+        this.isShowUpdateWeight=false
+      })
+    },
+    selectConfirm(val){
+      if(this.timeIndex==1){
+        this.form.start_date=this.$moment(this.currentDate).format('YYYY-MM-DD');
+      }else{
+        this.form.end_date=this.$moment(this.currentDate).format('YYYY-MM-DD');
+      }
+      this.isShowSelectTime = false;
+    },
+    onConfirmConfidence(v){
+      this.form.confident=v.value*2;
+      this.isShowSelectConfidence=false
+    },
+    confirmUpdateKr(){
+      if(this.form.start_date&&this.form.end_date){
+        if(this.form.start_date>this.form.end_date){
+          this.$toast("开始时间不能大于截止时间")
+          return false
+        }
+      }
+      this.form.kr_id=this.kr_id;
+      this.$axiosUser('post', '/api/pro/okr/kr/ms',this.form).then(res=>{
+         this.isShowUpdateKr=false
+         this.getKrDetail();
+      })
+    },
+    openTime(index){
+      this.timeIndex=index;
+      if(index==1){
+        this.currentDate=new Date(this.form.start_date);
+      }else{
+        this.currentDate=new Date(this.form.end_date);
+      }
+      this.isShowSelectTime = true;
+    },
+    confirmUser(item){
+       let employee=item.employee[0];
+       this.form.owner_id=employee.id;
+       this.form.owner_name=employee.name;
+    },
+    openSelectUser(index){
+      if(index==1){
+        this.selected_user_all.employee=this.employees;
+        this.selectUserAll=true;
+      }else if(index==2){
+        this.selected_user.employee=[{name:this.form.owner_name,id:this.form.owner_id}];
+        this.selectUser=true;
+      }
+    },
+    confirmCreator(item){
+      let employee=item.employee;
+      this.employees=employee;
+      let to_employee_id=employee.map(e=>{
+        return e.id
+      })
+      this.pointData.to_employee_id=to_employee_id.toString();
+    },
+    confirmPoint(){
+      if(this.pointData.score===''){
+        this.$toast("请输入分值");
+        return false
+      }
+      if(this.pointData.score>10){
+        this.$toast("请输入0~10之间数值");
+        return false
+      }
+      let params={
+        kr_id:this.kr_id,
+        score:Number(this.pointData.score),
+      }
+      if(this.employees.length>0){
+        params.to_employee_ids=this.pointData.to_employee_id
+      }
+      if(this.pointData.score_detail){
+        params.score_detail=this.pointData.score_detail;
+      }
+      this.$axiosUser('post', '/api/pro/okr/kr/score',params).then(res => {
+          this.isShowUpdatePoint=false;
+          this.$toast("已评分");
+          this.getKrDetail();
+      })
+    },
+
+    activebelong(item){
+      if(item.value==1){
+        this.pointData={kr_id:'',score:this.krDetail.score==-1? 0:this.krDetail.score,score_detail:this.krDetail.score_detail,to_employee_id:[]};
+        this.isShowUpdatePoint=true;
+        this.$nextTick(() => {
+            setTimeout(()=>{
+              this.$refs.input.focus();
+            },500)
+        });
+      }else if(item.value==2){
+        this.updateProgress();
+      }else if(item.value==3){
+        this.form={
+          name:this.krDetail.name,
+          owner_id:this.krDetail.owner_userInfo.id,
+          owner_name:this.krDetail.owner_userInfo.name,
+          start_date:this.krDetail.start_time,//	是	string	开始日期,格式:2022-01-01
+          end_date:this.krDetail.end_time,//	是	string	结束日期,格式:2022-01-01
+          confident:this.krDetail.confident
+        },
+        this.isShowUpdateKr=true;
+      }else if(item.value==4){
+        this.getKrList()
+      }else{
+        this.$dialog.confirm({ title:'删除', message: 'kr删除操作不可恢复!请谨慎操作'}).then(() => {
+            this.deletekr();
+        });
+      }
+    },
+    getKrList(){
+      this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.krDetail.o_id}).then(res => {
+          let list=res.data.data.list;
+          this.krsList =list;
+          this.isShowUpdateWeight=true;
+      })
+    },
+  },
+};
+</script>
+
+<style scoped lang="less">
+  .btns span {
+    width: 1.4rem;
+    text-align: center;
+    padding: 0.04rem 0.1rem;
+    color: #26A2FF;
+    margin-left: 0.2rem;
+    border: 0.02rem solid #26A2FF;
+    border-radius: 0.06rem;
+    font-size: 0.26rem;
+  }
+  .list-box {
+    // padding: 0.2rem;
+    font-size: 0.32rem;
+    background-color: #fff;
+    border-radius: 5px;
+    margin: 0 0.2rem;
+    margin-top: 0.2rem;
+  }
+  .shadow {
+    border-bottom: 1px solid #f5f7fa;
+  }
+  .footer {
+    padding: 0.14rem 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+  }
+  .footer .gt {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    border: 0.02rem solid #f1f1f1;
+    font-size: 0.32rem;
+  }
+  .footer i{
+    font-size: 0.6rem;
+  }
+  .footer .btn {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    // border: 0.02rem solid #26A2FF;
+    color: #fff;
+    text-align: center;
+    background: #26A2FF;
+    font-size: 0.32rem;
+  }
+.updateprocess {
+    border: 1px solid #409EFF;
+    padding: 2px 6px;
+    border-radius: 25px;
+    font-size: 12px;
+    cursor: pointer;
+    margin-left: 10px;
+    color: #409EFF;
+}
+.wInput /deep/ .van-field__label{
+  width: 5rem;
+}
+.o-content {
+  border-radius: 5px;
+  padding: 5px;
+  margin-left: 16px;
+}
+.o-content:hover {
+  background-color: #f7f8fa;
+}
+.o-content:hover .fontColorC {
+  display: block !important;
+  cursor: pointer;
+}
+.biaos {
+  width: 10px;
+  height: 10px;
+  background-color: #26a2ff;
+  border: 1px solid #fff;
+  border-radius: 100%;
+  box-shadow: 0 0 10px #26a2ff;
+  display: inline-block;
+  margin-right: 10px;
+}
+.biaos2 {
+  background-color: #ff9600;
+  box-shadow: 0 0 10px #ff9600;
+}
+.biaos3 {
+  background-color: #f56c6c;
+  box-shadow: 0 0 10px #f56c6c;
+}
+ .label{
+   color: #89919F;
+ }
+.box{
+   padding:0.24rem;
+   font-size: 0.3rem;
+}
+ .box .flex-box{
+   margin-top: 0.2rem;
+ }
+.title{
+  position: relative;
+  padding-left: 0.14rem;
+}
+.title::after {
+    content: "";
+    position: absolute;
+    width: 0.06rem;
+    height: 0.26rem;
+    border-radius: 0.06rem;
+    background-color: #26A2FF;
+    left: 0;
+    top: 0.07rem;
+}
+.scroller {
+  height: calc(100% - 1.76rem) !important;
+  overflow-y: auto;
+  background-color: #fff;
+}
+.header-message span{
+  padding-left: 5px;
+  padding-right: 10px;
+}
+.aite {
+  width: 1rem;
+  height: 1rem;
+  text-align: center;
+  line-height: 1rem;
+  font-size: 0.6rem;
+  cursor: pointer;
+  display: inline-block;
+  box-shadow: 0 0 3px #89919f;
+  border-radius: 100%;
+  background-color: #fff;
+  position: fixed;
+  z-index: 2;
+  bottom: 0.4rem;
+  right: 0.4rem;
+}
+.aite i {
+  font-size: 0.36rem;
+}
+.header {
+  padding: 0.24rem;
+  background-color: #fff;
+  border-bottom: 1px solid #f1f1f1;
+}
+</style>

+ 606 - 0
src/performance/view/myTarget/myTarget.vue

@@ -0,0 +1,606 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="目标管理" left-text="返回" @click-left="$route_back" left-arrow>
+      <div slot="right" @click="isShowPopup = true" style="color: #fff;">筛选<van-icon name="list-switch" /></div>
+    </van-nav-bar>
+    <div class="all">
+      <div style="background-color: #fff;">
+        <div style="padding: 0.24rem;border-bottom: 1px solid #f1f1f1;" class="flex-box-ce flex-center-center" @click="openPanel()">
+          <icon name="YMPicker_item_icon" style="margin-right: 6px;width: 0.3rem;height: 0.3rem;" class="fontColorC"></icon>
+          <div>{{ dateParameter.year }}年</div>
+          <div style="margin: 0 6px;">{{ dateParameter.name }}</div>
+          <van-icon name="arrow-down" />
+        </div>
+        <!-- <van-tabs v-model="activeName">
+          <van-tab v-for="(item,index) in tabs" :title="item.title" :name="item.name" :key="index" v-if="item.isShow"></van-tab>
+        </van-tabs> -->
+      </div>
+
+      <template v-if="activeName=='a'">
+        <!-- <div class="flex-box-ce flex-d-wrap" style="padding: 0 0.2rem;margin-top: 0.24rem;">
+          <div class="search-item" style="border-radius: 25px;font-size: 0.28rem;" @click="targetType=item.id" v-for="(item, index) in targetTypeArr" :key="index" :class="item.id==targetType? 'searchActive':''">{{ item.name }}</div>
+        </div> -->
+      </template>
+      <template v-if="activeName=='b'">
+        <div class="selector" @click="isShowDept=true">
+          <span>{{ deptInfo.dept_name }}</span>
+          <van-icon name="arrow-down" />
+        </div>
+        <div style="overflow-x: scroll;margin: 0.2rem;">
+            <div class="flex-box-ce">
+                <div
+                :class="{userActive:ownerUserInfo.id==item.id}"
+                @click="ownerUserInfo = item"
+                style="padding:0.14rem;border-radius: 5px;"
+                class="flex-box-v flex-center-center"
+                v-for="(item,index) in userList" :key="index">
+                  <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                  <div class="clamp userName">{{item.name}}</div>
+                </div>
+            </div>
+        </div>
+      </template>
+      <template v-if="activeName=='c'">
+        <div style="overflow-x: scroll;margin: 0.2rem;">
+            <div class="flex-box-ce">
+                <div class="flex-box-v flex-center-center" style="padding: 0.14rem;" @click="openGz">
+                   <div class="addUser" style="">+</div>
+                   <div class="clamp userName">设置</div>
+                </div>
+
+                <div
+                :class="{userActive:follUserInfo.id==item.id}"
+                @click="follUserInfo=item"
+                style="padding:0.14rem;border-radius: 5px;"
+                class="flex-box-v flex-center-center"
+                v-for="(item,index) in followList" :key="index">
+                  <userImage :id="item.id" :user_name="item.name" :img_url="item.img_url" fontSize="0.20" width="0.8rem" height="0.8rem"></userImage>
+                  <div class="clamp userName">{{item.name}}</div>
+                </div>
+            </div>
+        </div>
+      </template>
+      <template v-if="activeName=='d'">
+        <div class="selector" @click="isShowSelectUser=true">
+          <span v-if="selectDataBox.name">{{ selectDataBox.name }}</span>
+          <span v-else class="fontColorC">选择人员或部门</span>
+          <van-icon name="arrow-down" />
+        </div>
+        <div style="height: 0.2rem;"></div>
+      </template>
+      <div class="scroller" :class="{scroller2:activeName=='b',scroller3:activeName=='c',scroller4:activeName=='d'}">
+        <scroller ref="scroller" :isInitRefresh="false" :on-refresh="refresh" :on-infinite="infinite" noDataText="没有了噢" :list="targetList">
+          <div class="list-box" v-for="(item,index) in targetList" :key="index" >
+              <div class="flex-box" @click="openDetail(item,1)">
+                  <div class="huan"><span></span></div>
+                  <div class="flex-1">
+                    <div class="clamp2" style="margin-bottom: 5px;">{{item.name}}</div>
+                    <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                        <van-icon name="contact" v-show="item.belong_type==4"/>
+                        <van-icon name="cluster-o" v-show="item.belong_type==2"/>
+                        <van-icon name="hotel-o" v-show="item.belong_type==1"/>
+                        <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;">{{$getEmployeeMapItem(item.owner_id).name}}</span>
+                        <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.composite_state==6">已结束</span>
+                        <template v-else>
+                          <span style="border-left: 1px solid #f1f1f1;padding-left: 0.1rem;margin-left: 0.1rem;" v-if="item.process_ut">{{item.process_ut}} 更新</span>
+                        </template>
+                        <span class="flex-1"></span>
+                        <div class="progress"><div class="progress-inner" :class="{bjYellow:item.risk_level==2,bjRed:item.risk_level==3}" :style="{width:item.process>100? '100%':item.process+'%'}"></div></div>
+                        <span style="padding-left: 0.1rem;font-size: 0.24rem;" class="blue" :class="{orange:item.risk_level==2,red:item.risk_level==3}">{{ item.process }}%</span>
+                    </div>
+                  </div>
+              </div>
+              <div class="flex-box-ce" style="margin-top: 0.2rem;" @click="openDetail(krItem,2)" v-for="(krItem,index2) in item.krs" :key="index2" >
+                  <div class="blue" style="font-size: 0.26rem;margin-right: 0.13rem;">KR{{index2+1}}</div>
+                  <div class="flex-1 font-flex-word" style="padding-right: 0.2rem;font-size: 0.28rem;">{{krItem.name}}</div>
+                  <van-circle layer-color="#E5E9F2" v-model="krItem.currentRate" :color="krItem.risk_level==2? '#FF9600':krItem.risk_level==3? '#f56c6c':' #2879ff'" :rate="krItem.process" :key="index2"  :stroke-width="120" size="20px"/>
+                  <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:krItem.risk_level==2,red:krItem.risk_level==3}">{{ krItem.process }}%</span>
+              </div>
+          </div>
+          <div v-if="targetList.length == 0" style="text-align: center;margin-top: 2rem;" class="fontColorC">
+              <span>未找到相关的目标</span>
+          </div>
+        </scroller>
+      </div>
+
+    </div>
+
+    <!-- 选择部门 -->
+    <van-dialog v-model="isShowDept" title="" width="300" :show-confirm-button="false" closeOnClickOverlay>
+      <van-radio-group v-model="deptInfo.dept_id">
+        <div v-for="(item, index) in dept_list" :key="index">
+          <van-radio :name="item.dept_id" @click="confirmDept2(item)" style="margin:.3rem 0 .3rem .4rem;font-size:.3rem" icon-size="16px">
+            <span style="margin-left:.3rem">{{ item.dept_name }}</span>
+          </van-radio>
+        </div>
+      </van-radio-group>
+    </van-dialog>
+
+    <!-- 周期选择 -->
+    <van-action-sheet v-model="pullonThePanel" :closeable="false">
+      <div class="content">
+        <van-picker ref="van_picker" show-toolbar :columns="columns" @cancel="pullonThePanel=false" value-key="name" @confirm="onConfirm" confirm-button-text="完成" />
+      </div>
+    </van-action-sheet>
+
+    <!-- 人员选择 -->
+    <EmployeeDeptSelector
+      title="选择人员"
+      :visible.sync="isShowSelectUser"
+      @confirm="confirmUser"
+      :selectDataBox.sync="selectDataBox">
+    </EmployeeDeptSelector>
+
+    <!-- 筛选 -->
+    <van-popup v-model="isShowPopup" position="right" style="height: 100%;left: 20%;">
+      <div style="position: relative;height: 100%;">
+        <div style="border-bottom: 1px solid #f1f1f1;font-size: 16px;font-weight: 700;height: 0.92rem;line-height: 0.92rem;padding: 0 0.2rem;">高级筛选</div>
+        <div style="padding: 10px;">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">类型</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" @click="belong_type=item.id" v-for="(item, index) in targetArr" :key="index" :class="item.id==belong_type? 'searchActive':''">{{ item.name }}</div>
+            </div>
+        </div>
+       <!-- <div style="padding: 10px;">
+          <div style="margin-bottom: 15px;font-size: 0.32rem;">状态</div>
+            <div class="flex-box-ce flex-d-wrap">
+              <div class="search-item" @click="sortId=item.id" v-for="(item, index) in sortArr" :key="index" :class="item.id==sortId? 'searchActive':''">{{ item.name }}</div>
+            </div>
+        </div> -->
+        <div style="position: fixed;bottom: 0.2rem;left: 0.2rem;right: 0.2rem;">
+          <div class="btn" @click="isShowPopup=false">确认</div>
+        </div>
+      </div>
+    </van-popup>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import {Picker,Popup,Circle,Icon,Tab, Tabs,} from 'vant';
+import { _debounce, _throttle } from '@/utils/auth';
+import { getBelongType,getColumns,cycleTypeArr} from '@/okr/utils/auth';
+
+import EmployeeSelector from '@/components/EmployeeSelector';
+import EmployeeDeptSelector from '@/components/EmployeeDeptSelector';
+Vue.use(Picker).use(Popup).use(Circle).use(Icon).use(Tabs).use(Tab)
+export default {
+  components:{EmployeeSelector,EmployeeDeptSelector},
+  name: 'Target',
+  props: {
+    skeLoad: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      page:1,
+      page_size:10,
+      cycleTypeArr:cycleTypeArr(true),
+      value:5,
+      userId:this.$userInfo().id,
+      userInfo: this.$userInfo(),
+      dept_list:this.$userInfo().employee_detail.dept_list,
+      deptInfo:this.$userInfo().employee_detail.dept_list[0]? this.$userInfo().employee_detail.dept_list[0]:{},
+      isShowDept:false,
+      targetTypeArr: [{ name: '我负责的', id: 1 }, { name: '我参与的', id: 2 }, { name: '我关注的', id: 3 }],
+      targetType:1,
+      dateParameter: {
+        year: '',
+        cycle_type: 0,
+        dateId: 1,
+        name: '全部周期'
+      },
+      selectPftiTheEcho: [0, 0], // 选项回显
+      pullonThePanel:false,
+      columns: getColumns(),
+      isShowPopup:false,
+
+      targetArr: [{ name: '全部类型', id: 0 }, { name: '公司', id: 1 }, { name: '部门', id: 2 },{ name: '个人', id: 4 }],
+      belong_type: 0,
+
+      sortArr: [
+        { name: '全部状态', id: 0,value:'0' },
+        { name: '进行中', id: 1,value:'1,2,3,4,5,7,8,9' },
+        { name: '已结束', id: 2,value:'6' },
+      ],
+      sortId: 0,
+      targetList:[],
+      isShowSelectUser:false,
+      selected_user: { dept: [], employee: [] } ,//传入已选部门
+      selectDataBox:{},
+      tabs:[{title:'我的目标',name:'a',isShow:true},{title:'我的部门',name:'b',isShow:true},{title:'关注的人',name:'c',isShow:true},{title:'全公司',name:'d',isShow:true}],
+      activeName: 'd',
+      userList:[],
+      ownerUserInfo:{},
+      followList:[],
+      follUserInfo:{},
+    };
+  },
+  watch:{
+    isShowSelectUser(val){
+      if(val){
+        this.selected_user.employee=[this.userInfo];
+      }
+    },
+    isShowPopup(val){
+      if(!val){
+        this.pullDown();
+      }
+    },
+    targetType(){
+      this.pullDown();
+    },
+    ownerUserInfo(){
+      this.pullDown();
+    },
+    follUserInfo(){
+      this.pullDown();
+    },
+    activeName(val){
+      if(this.activeName=='a'){
+        this.pullDown();
+      }
+      if(this.activeName=='d'){
+        this.pullDown();
+      }
+      if(this.activeName=='b'){
+        this.get_employee_list();
+      }
+      if(this.activeName=='c'){
+        this.getGzUserList();
+      }
+    },
+  },
+  methods: {
+    openGz(){
+      this.$router.push({name: 'attentionList',query:{index:1}})
+    },
+    getGzUserList(){
+      this.$axiosUser('get', '/api/pro/okr/follow', { type:1 }).then(res=>{
+         this.followList = res.data.data.list;
+         if(this.followList.length>0){
+           this.follUserInfo=this.followList[0];
+         }else{
+           this.follUserInfo={};
+           this.pullDown();
+         }
+      })
+    },
+    confirmDept2(data){
+      this.deptInfo=JSON.parse(JSON.stringify(data));
+      this.get_employee_list();
+      this.isShowDept=false;
+    },
+    get_employee_list() {
+      this.$axiosUser('get', '/api/pro/employee/list', { dept_id:this.deptInfo.dept_id }, 'v2').then(res => {
+        let list=res.data.data.list;
+        list.unshift({name:'全部',id:0})
+        this.userList=list;
+        if(this.userList.length>0){
+          this.ownerUserInfo=this.userList[0];
+        }
+      });
+    },
+
+    openPanel(){
+      this.pullonThePanel=true;
+      this.$nextTick(() => {
+        this.theEchoVanPicker()
+      })
+    },
+
+    confirmUser(item){
+      this.selectDataBox = item;
+      this.pullDown();
+    },
+    openDetail(item,type){
+      if(type==1){
+        this.$router.push({name: 'myTargetDetail', query: {id: item.id}})
+      }else {
+        this.$router.push({name: 'myKrDetail', query: {id: item.id}})
+      }
+    },
+    // 考核包搜索
+    onConfirm (data, list) { // 确认
+      let columns=this.columns[list[0]];
+      let options=this.cycleTypeArr[list[1]]
+      this.selectPftiTheEcho=list
+      this.dateParameter={
+        year: columns.value,
+        cycle_type: options.cycle_type,
+        dateId: options.id,
+        name: options.name
+      };
+      this.pullDown();
+      this.pullonThePanel = false
+    },
+    pullDown(){
+      setTimeout(() => {
+        this.$refs.scroller.triggerPullToRefresh();
+      }, 50);
+    },
+    theEchoVanPicker() { // 回显
+      this.$refs.van_picker.setIndexes(this.selectPftiTheEcho);
+    },
+
+    getList(is,callback){
+      let hasMore = false
+      is? '':this.page=1;
+      let params = {
+        page:is? this.page:1,
+        page_size: this.page_size,
+        cycle_type:this.dateParameter.cycle_type,
+        year:this.dateParameter.year,
+        belong_type:this.belong_type,
+        quarter:0,
+        half_year:0,
+        month:0,
+        sort_ct:2,
+        ids: []
+      };
+      if(!params.year) delete params.year
+      if(!params.quarter) delete params.quarter
+      if(!params.half_year) delete params.half_year
+      if(!params.month) delete params.month
+      params.ids = this.$route.query.ids || "[]";
+      if(this.activeName=='a'){ //我的目标
+        this.targetType==1? params.owner_id=this.userId:this.targetType==2? params.joiner_id=this.userId:params.follower_id=this.userId;
+      }else if(this.activeName=='b'){//我的部门
+        params.dept=this.deptInfo.dept_id;
+        params.owner_id=this.ownerUserInfo.id;
+      }else if(this.activeName=='c'){//我关注的
+        if(this.follUserInfo.id){
+          params.owner_id=this.follUserInfo.id;
+        }else{
+          this.targetList=[];
+          callback && callback(hasMore)
+          return false
+        }
+      }else if(this.activeName=='d'){//全公司
+        if(this.selectDataBox.type == 'user'){
+          params.owner_id = this.selectDataBox.id;
+        }else if(this.selectDataBox.type=='dept'){
+          params.dept=this.selectDataBox.id;
+        }
+      }
+
+      if(this.sortId){//状态
+          params.composite_states=this.sortId==1? '1,2,3,4,5,7,8,9':'6';
+      }
+      if(this.dateParameter.cycle_type==2){
+        params.quarter=this.dateParameter.dateId
+      }
+      if(this.dateParameter.cycle_type==3){
+        params.half_year=this.dateParameter.dateId
+      }
+      if(this.dateParameter.cycle_type==4){
+        params.month=this.dateParameter.dateId
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/obj/list', params).then(res => {
+          let list=res.data.data.list
+          list.forEach(item=>{
+            item.krs.forEach(e=>{
+              e.currentRate=Number(e.process);
+              e.process=Number(e.process)
+            })
+          })
+          if (this.page === 1) {
+            this.targetList = list
+          } else {
+            this.targetList = this.targetList.concat(list)
+          }
+          hasMore = list.length !== 10
+          callback && callback(hasMore)
+      })
+    },
+    // 上拉刷新
+    refresh (done) {
+      this.getList(false,done)
+    },
+    // 下拉加载
+    infinite (done) {
+      this.page++;
+      this.getList(true,done)
+    },
+    getUnitList(){
+      this.$axiosUser('get', '/api/pro/okr/public/kr/unit_list').then(res => {
+    	let data=res.data.data;
+    	data.reverse()
+       this.$setCache('unitList',data)
+      })
+    },
+  },
+  created() {
+    this.getUnitList();
+    this.columns.forEach((e,index)=>{
+      if(e.value==this.dateParameter.year){
+        this.selectPftiTheEcho[0]=index
+      }
+    })
+    this.tabs=[
+      {title:'我的目标',name:'a',isShow:true},
+      {title:'我的部门',name:'b',isShow:!this.$userInfo().is_okr_manager&&this.dept_list.length>0},
+      {title:'关注的人',name:'c',isShow:true},
+      {title:'全公司',name:'d',isShow:true},
+    ]
+    this.getList();
+  },
+  activated() {
+    if(this.activeName=='c'){
+      this.getGzUserList();
+    }else{
+      this.pullDown();
+    }
+  },
+};
+</script>
+
+<style scoped lang="less">
+.addUser{
+    font-size: .6rem;
+    padding: 0.2rem;
+    border: 0.02rem dashed #89919f;
+    text-align: center;
+    height: 0.4rem;
+    width: 0.4rem;
+    line-height: .4rem;
+    color: #89919f;
+    border-radius: 2rem;
+}
+.userName{
+    font-size: 0.28rem;
+    width: 1rem;
+    text-align: center;
+    color: #89919F;
+}
+.userActive{
+  background-color: #E9F0FD;
+}
+.userActive .userName{
+ color: #26A2FF;
+}
+.selector {
+  z-index: 1;
+  display: flex;
+  justify-content: center;
+  width: 100%;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: #fff;
+  text-align: center;
+  font-size: 0.28rem;
+  border-top: 1px solid #f1f1f1;
+  i {
+    margin: 0.23rem 0 0 0.1rem;
+    color: #c3c3c3;
+  }
+  span {
+    max-width: 3.5rem;
+    overflow: hidden;
+  }
+}
+.aite{
+    width: 1rem;
+    height: 1rem;
+    text-align: center;
+    line-height: 1rem;
+    font-size: 0.6rem;
+    cursor: pointer;
+    color: #fff;
+    display: inline-block;
+    border-radius: 100%;
+    background-color: #26A2FF;
+    position: absolute;
+    z-index: 2;
+    bottom: 0.4rem;
+    right: 0.4rem;
+}
+.progress {
+  border-radius: 100px;
+  background-color: #ebeef5;
+  overflow: hidden;
+  position: relative;
+  vertical-align: middle;
+  height: 0.2rem;
+  width: 1rem;
+}
+.progress-inner {
+  width: 0%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding-top: 1px;
+  height: 100%;
+  background-image: linear-gradient(to right, #99BBFF 0%, #26A2FF 100%);
+  border-radius: 100px;
+  color: #fff;
+  white-space: nowrap;
+  transition: width 0.6s ease;
+}
+.bjYellow{
+  background-image: linear-gradient(to right, #fedf86 0%, #FF9600 100%);
+}
+.bjRed{
+  background-image: linear-gradient(to right, #FEA2A2 0%, #F16060 100%);
+}
+.huan{
+  position: relative;
+  width: 0.4rem;
+  height: 0.4rem;
+  border-radius: 100%;
+  background-color: #E9F1FE;
+  box-sizing: border-box;
+  text-align: center;
+  margin-right: 0.2rem;
+  padding-top: 0.036rem;
+}
+.huan span{
+  border: 2px solid #26A2FF;
+  border-radius: 100%;
+  width: 0.16rem;
+  height: 0.16rem;
+  display: inline-block;
+}
+.list-box{
+  padding: 0.2rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0.2rem;
+  margin-bottom: 0.24rem;
+}
+.scroller{
+   height: calc(100% - 2.75rem);
+   position: relative;
+}
+.scroller2{
+   height: calc(100% - 4.5rem);
+}
+.scroller3{
+   height: calc(100% - 3.7rem);
+}
+.scroller4{
+   height: calc(100% - 2.84rem);
+}
+.all {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+}
+.search-box {
+  border-radius: 25px;
+  padding:0.1rem;
+  border: 1px solid #f1f1f1;
+  font-size: 0.28rem;
+}
+.header {
+  background-color: #fff;
+  padding: 0.2rem;
+  font-size: 0.28rem;
+  margin-bottom: 0.2rem;
+}
+.search-item{
+  padding: 0.06rem 0.1rem;
+  background-color: #F7F8FA;
+  color: #89919F;
+  width: 1.2rem;
+  text-align: center;
+  margin-right: 0.2rem;
+  margin-bottom: 0.2rem;
+  border-radius: 3px;
+  font-size: 0.3rem;
+}
+.searchActive{
+  color: #26A2FF;
+  background-color: #E9F0FD;
+}
+.btn{
+  background-color: #26A2FF;
+  color: #fff;
+  text-align: center;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  border-radius: 25px;
+}
+</style>

+ 945 - 0
src/performance/view/myTarget/targetDetail.vue

@@ -0,0 +1,945 @@
+<template>
+  <div style="height: 100%;">
+    <van-nav-bar title="目标详情" left-text="返回" left-arrow @click-left="$route_back" />
+    <div class="all-box">
+      <template v-if="targetDetail.visible==1">
+        <header class="header">
+          <div class="flex-box">
+            <!-- 目标综合状态 1-未开始 2-负责人未接收 3-运行中 4-已延期 5-已达标(进度大于等于100) 6-已结束 -->
+<!--            <span class="status" v-if="targetDetail.composite_state==1">未开始</span>
+            <span class="status" v-if="targetDetail.composite_state==2">未接收</span>
+            <span class="status" v-if="targetDetail.composite_state==3">进行中</span>
+            <span class="status" v-if="targetDetail.composite_state==4">已延期</span>
+            <span class="status" v-if="targetDetail.composite_state==5">已达标</span> -->
+            <span class="status" v-if="targetDetail.composite_state==6">已结束</span>
+            <div class="flex-1" style="font-weight: 600;padding: 0 0.2rem;padding-left: 0.1rem;">{{targetDetail.name}}</div>
+          </div>
+          <div class="flex-box-ce" style="margin: 0.16rem 0;">
+            <div class="progress"><div class="progress-inner" :class="{bjYellow:targetDetail.risk_level==2,bjRed:targetDetail.risk_level==3}" :style="{width:targetDetail.process>100? '100%':targetDetail.process+'%'}"></div></div>
+            <span style="padding-left: 0.1rem;font-size: 0.24rem;" class="blue" :class="{orange:targetDetail.risk_level==2,red:targetDetail.risk_level==3}">{{ targetDetail.process }}%</span>
+            <template v-if="targetDetail.process != targetDetail.process_last">
+              <span v-if="targetDetail.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ targetDetail.updatePro }}%</span>
+              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ targetDetail.updatePro }}%</span>
+            </template>
+            <div class="flex-1"></div>
+            <div class="orange" v-if="targetDetail.score>=0">{{targetDetail.score}}</div>
+          </div>
+          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+            <span>{{$getEmployeeMapItem(targetDetail.owner_id).name}}</span>
+            <span style="margin: 0 0.1rem;padding: 0 0.1rem;border-left: 1px solid #f1f1f1;border-right: 1px solid #f1f1f1;">
+
+                {{targetDetail.belong_type==2? (dept_tree[targetDetail.dept_id]? dept_tree[targetDetail.dept_id].name:''):getBelongType(targetDetail.belong_type).name}}
+            </span>
+            <span class="flex-1">{{targetDetail.year}}年 {{targetDetail.dateStr}}</span>
+          </div>
+          <template v-if="targetDetail.kr_id">
+            <div class="flex-box" v-if="targetDetail.p_kr" style="font-size: 0.26rem;margin-top: 0.2rem;border-top: 1px solid #f1f1f1;padding-top: 0.2rem;height: 0.36rem;">
+                <span class="fontColorC">对齐目标:</span>
+                <div class="flex-1 font-flex-word">{{targetDetail.p_kr.name}}</div>
+            </div>
+          </template>
+          <template v-else-if="targetDetail.o_id">
+            <div class="flex-box" v-if="targetDetail.p_objectives" style="font-size: 0.26rem;margin-top: 0.2rem;border-top: 1px solid #f1f1f1;padding-top: 0.2rem;height: 0.36rem;">
+                <span class="fontColorC">对齐目标:</span>
+                <div class="flex-1 font-flex-word">{{targetDetail.p_objectives.name}}</div>
+            </div>
+          </template>
+        </header>
+        <van-tabs v-model="tabActive" class="shadow"><van-tab :title="item" v-for="(item, index) in tabs" :key="index"></van-tab></van-tabs>
+        <div class="scroller">
+          <scroller ref="scroller">
+            <template v-if="tabActive == 0">
+              <div class="list-box" v-for="(item, index) in krsList" :key="index" @click="openDetail(item,2)">
+                <div class="clamp2" style="margin-bottom: 5px;">{{item.name}}</div>
+                <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                  <span>{{$getEmployeeMapItem(item.owner_id).name}}</span>
+                  <span class="padding-l-r flex-box-ce">{{item.weight}}%</span>
+                  <span class="flex-box-ce" style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;"><van-icon name="star" class="yellow" />{{item.confident}}分</span>
+                  <van-circle :key="item.id" layer-color="#E5E9F2" v-model="item.currentRate" :color="item.risk_level==2? '#FF9600':item.risk_level==3? '#f56c6c':' #2879ff'" :rate="item.process"  :stroke-width="120" size="20px"/>
+                  <span style="padding-left: 5px;font-size: 0.24rem;" class="blue" :class="{orange:item.risk_level==2,red:item.risk_level==3}">{{ item.process }}%</span>
+                </div>
+              </div>
+
+            </template>
+            <template v-if="tabActive == 1">
+              <div class="list-box" v-for="(item, index) in krsListAll" :key="index">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;border-bottom: 1px solid #f1f1f1;padding-bottom: 0.2rem;">
+                  <div class="blue" style="font-size: 0.26rem;font-weight: 600;margin-right: 0.1rem;">KR{{index+1}}</div>
+                  <div class="flex-1 font-flex-word" style="padding-right: 0.2rem;font-size: 0.3rem;">{{item.name}}</div>
+                  <!-- <span style="font-size: 0.26rem;" v-if="item.plans.length>0">计划任务<span class="blue">{{returnSum(item.plans)}}</span>/<span>{{item.plans.length}}</span></span> -->
+                </div>
+                <div style="padding:0 0.1rem;">
+
+                  <template v-if="item.projects.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index3) in item.projects" :key="task_item.id" @click="openDetail(task_item,3)">
+                        <van-icon name="paid" class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"/>
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD')}} 截止</span>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <template v-if="item.plans.length>0">
+                      <div class="flex-box" style="margin-top: 0.2rem;" v-for="(task_item, index2) in item.plans" :key="index2" @click="openDetail(task_item,1)">
+                        <van-icon :name="taskStatus(task_item.composite_state).icon"
+                        class="blue" style="margin-right: 0.2rem;position: relative;top: 3px;"
+                        :class="(task_item.day<=0&&$moment(task_item.end_date).format('YYYY-MM-DD')!=$moment().format('YYYY-MM-DD')) ? 'red':''"
+                        />
+                        <div class="flex-1">
+                          <div class="clamp2" style="margin-bottom: 5px;font-size: 0.28rem;">{{task_item.name}}</div>
+                          <div class="flex-box-ce fontColorC" style="font-size: 0.26rem;">
+                            <span style="padding-right: 0.1rem;border-right: 1px solid #f1f1f1;margin-right: 0.1rem;">{{$getEmployeeMapItem(task_item.owner_id).name}}</span>
+                            <span class="flex-1">{{$moment(task_item.end_date).format('MM/DD HH:mm')}} 截止</span>
+                            <template v-if="task_item.statistics.plan_total">
+                              <van-icon name="orders-o" />
+                              <span style="font-size: 0.26rem;">
+                                <span class="blue">{{task_item.statistics.plan_finish}}</span>/<span>{{task_item.statistics.plan_total}}</span>
+                              </span>
+                            </template>
+                          </div>
+                        </div>
+                      </div>
+                  </template>
+                  <div v-if="item.projects.length==0&&item.plans.length==0" style="text-align: center;margin: 0.2rem 0;font-size: 0.28rem;" class="fontColorC">用“项目/任务”推动目标达成,合理规划安排工作</div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive == 3">
+              <div style="height: 100%;background-color: #fff;padding: 0.2rem;border-top: 1px solid #f1f1f1;">
+                <div class="flex-box-ce" style="margin-bottom: 0.2rem;">
+                  <div class="flex-1">
+                    <div class="user-title">发布人</div>
+                    <div class="flex-box-v" style="text-align: center;width: 1.06rem">
+                      <userImage :id="targetDetail.publisher_id" :user_name="$getEmployeeMapItem(targetDetail.publisher_id).name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;" class="font-flex-word">{{ $getEmployeeMapItem(targetDetail.publisher_id).name }}</div>
+                    </div>
+                  </div>
+                  <div class="flex-1">
+                    <div class="user-title">负责人</div>
+                    <div class="flex-box-ce">
+                      <div style="text-align: center;width: 1.06rem">
+                        <userImage :img_url="targetDetail.owner_userInfo.img_url" :user_name="targetDetail.owner_userInfo.name" width="0.7rem" height="0.7rem"></userImage>
+                        <div style="font-size: 0.26rem;padding: 0.1rem 0;" class="font-flex-word">{{ targetDetail.owner_userInfo.name }}</div>
+                      </div>
+                      <div class="zj" v-if="isUpdate" @click="openSelectUser(1)">转交</div>
+                    </div>
+                  </div>
+                </div>
+                <div style="margin-bottom: 0.2rem;">
+                  <div class="user-title">参与人员</div>
+                  <div class="flex-box-ce flex-d-wrap">
+                    <div class="flex-box-v" style="margin-right: 0.2rem;text-align: center;margin-bottom: 0.2rem;position: relative;"  v-for="(item, index) in targetDetail.joiner_employee_items"  :key="index" >
+                      <userImage :img_url="item.img_url" :user_name="item.name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;width: 1.06rem" class="font-flex-word">{{ item.name }}</div>
+                      <!-- <van-icon name="clear" class="delete-user red" /> -->
+                      <div class="zj2" v-if="isUpdate" @click="joinerUpdate(false,item.id)">删除</div>
+                    </div>
+                    <div class="addUser" v-if="isUpdate" @click="openSelectUser(2)">+</div>
+                  </div>
+                </div>
+                <div style="margin-bottom: 0.2rem;">
+                  <div class="user-title">关注人员</div>
+                  <div class="flex-box-ce flex-d-wrap">
+                    <div class="flex-box-v" style="margin-right: 0.2rem;text-align: center;margin-bottom: 0.2rem;" v-for="(item, index) in targetDetail.follower_employee_items" :key="index">
+                      <userImage :img_url="item.img_url" :user_name="item.name" width="0.7rem" height="0.7rem"></userImage>
+                      <div style="font-size: 0.26rem;padding: 0.1rem 0;width: 1.06rem" class="font-flex-word">{{ item.name }}</div>
+                      <div class="zj2" v-if="isUpdate" @click="deleteFollower(false,item.id)">删除</div>
+                    </div>
+                    <div class="addUser" v-if="isUpdate" @click="openSelectUser(3)">+</div>
+                  </div>
+                </div>
+              </div>
+            </template>
+            <template v-if="tabActive == 2">
+              <div style="padding: 0.2rem;background-color: #fff;border-top: 1px solid #f1f1f1;">
+                <div class="flex-box-ce flex-d-wrap">
+                  <div class="search-item" @click="targetType = item.id"  v-for="(item, index) in targetTypeArr" :key="index"  :class="item.id == targetType ? 'searchActive' : ''">{{ item.name }}</div>
+                  <div class="flex-1"></div>
+                </div>
+                <template v-if="targetType==1">
+                  <div v-for="(item, index) in processList" :key="index" style="margin-top: 0.24rem;">
+                    <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                      <span class="biaos" :class="{ biaos2: item.risk_level == 2, biaos3: item.risk_level == 3 }"></span>
+                      <div class="black flex-1" style="font-weight: 700;font-size: 16px;">
+                      {{ item.process }}%
+                        <template v-if="item.process != item.process_last">
+                          <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                          <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                        </template>
+                      </div>
+                      <span class="fontColorC" style="font-size: 0.26rem;">{{ item.create_time }}</span>
+                    </div>
+                    <div class="flex-box o-content">
+                      <pre v-if="item.content" class="flex-1 fontColorB" style="margin: 0px;">{{ item.content }}</pre>
+                      <div v-else class="flex-1 fontColorD">暂无内容</div>
+                    </div>
+                  </div>
+                  <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processList.length==0">目标进展一目了然?赶快更新完成度吧</div>
+                </template>
+                <template v-if="targetType==2">
+                    <div v-for="(item, index) in processData.kr" :key="index" style="margin-top: 0.24rem;">
+                      <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                        <span class="biaos" :class="{biaos2:item.process_info&&item.process_info.risk_level==2,biaos3:item.process_info&&item.process_info.risk_level==3}"></span>
+                        <span class="okr-index">KR{{ index + 1 }}</span>
+                        <div class="font-flex-word fontColorC flex-1" style="padding-right:0.2rem;font-size: 0.28rem;">{{item.name}}</div>
+                        <div class="black" style="font-weight: 700;font-size: 16px;">
+                            {{ item.process }}%
+                            <template v-if="item.process != item.process_last">
+                              <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                            </template>
+                        </div>
+                      </div>
+                      <div v-if="item.process_info">
+                        <div class="o-content fontColorB">
+                            <pre v-if="item.process_info.content" style="margin: 0px;">{{item.process_info.content}}</pre>
+                            <span v-else class="fontColorD" style="font-size: 13px;">暂未更新</span>
+                        </div>
+                        <div style="padding-left: 0.34rem;font-size: 12px;" class="fontColorC">{{item.process_info.create_time}}</div>
+                      </div>
+                      <div class="pre fontColorD" v-else style="font-size: 13px;padding: 5px 0.5rem;">暂未更新</div>
+                    </div>
+                    <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processData.kr==0">暂无进展</div>
+                </template>
+                <template v-if="targetType==3">
+                    <div v-for="(item, index) in processData.objectives" :key="index" style="margin-top: 0.24rem;">
+                      <div class="flex-box-ce" style="padding-bottom: 0.2rem;">
+                        <span class="biaos" :class="{biaos2:item.process_info&&item.process_info.risk_level==2,biaos3:item.process_info&&item.process_info.risk_level==3}"></span>
+                        <div class="huan"><span></span></div>
+                        <div class="font-flex-word fontColorC flex-1" style="padding-right:0.2rem;font-size: 0.28rem;">{{item.name}}</div>
+                        <div class="black" style="font-weight: 700;font-size: 16px;">
+                            {{ item.process }}%
+                            <template v-if="item.process != item.process_last">
+                              <span v-if="item.isUpdatePro>0" class="green" style="font-size: 12px;"><van-icon name="back-top" />{{ item.updatePro }}%</span>
+                              <span v-else class="red" style="font-size: 12px;"><van-icon name="down" />{{ item.updatePro }}%</span>
+                            </template>
+                        </div>
+                      </div>
+                      <div v-if="item.process_info">
+                        <div class="o-content fontColorB">
+                            <per v-if="item.process_info.content" style="margin: 0px;">{{item.process_info.content}}</per>
+                            <span v-else class="fontColorD" style="font-size: 13px;">暂未更新</span>
+                        </div>
+                        <div style="padding-left: 0.34rem;font-size: 12px;" class="fontColorC">{{item.process_info.create_time}}</div>
+                      </div>
+                      <div class="pre fontColorD" v-else style="font-size: 13px;padding: 5px 0.5rem;">暂未更新</div>
+                    </div>
+                    <div style="text-align: center;margin: 1rem 0;" class="fontColorC" v-if="processData.objectives==0">暂无进展</div>
+                </template>
+              </div>
+            </template>
+            <div style="height: 3rem;"></div>
+          </scroller>
+          <footer class="footer">
+            <div class="flex-box-ce">
+               <van-icon name="chat-o" @click="openCommunication" style="margin-left: 0.2rem;font-size:0.6rem;" class="fontColorC"/>
+            </div>
+          </footer>
+        </div>
+      </template>
+
+       <van-row type="flex" justify="space-around" class="c" v-else>
+          <van-col span="24">
+            <div style="text-align: center;margin-top: 2rem;margin-bottom: 1rem;">
+              <img src='static/images/noPeople.png' style="width: 3.5rem;"/>
+            </div>
+            <p class="text_center fontColorC">暂无查看权限</p>
+          </van-col>
+        </van-row>
+    </div>
+    <van-dialog v-model="isShowProcess" show-cancel-button :beforeClose="subContent">
+      <van-cell-group>
+        <van-field v-model="processInfo.content" rows="4"  class="textarea-box" type="textarea" maxlength="500" placeholder="请输入进展与障碍" show-word-limit/>
+      </van-cell-group>
+    </van-dialog>
+
+    <!-- 进度 -->
+    <Progress :visible.sync="isShwoUpdateProgress" :progressData="progressData" @confirm="update"></Progress>
+    <!-- 添加KR -->
+    <AddKr :o_id="Number(o_id)" :isShowWeight="false" :visible.sync="isShowAddKr" @confirm="confirmAddkr"></AddKr>
+    <!-- 详情 -->
+    <van-action-sheet v-model="isShowbelong" :actions="scopeArr" @select="activebelong" cancel-text="取消" close-on-click-action/>
+    <!-- 修改基本信息 -->
+    <UpdateTarget :visible.sync="isShwoUpdateDetail" :targetDetail="targetDetail" :o_id="Number(o_id)" @confirm="getTargetDateil"></UpdateTarget>
+    <!-- 关联任务 -->
+    <TaskSearch :visible.sync="isShwoTaskSearch" @confirm="ActiveRelevanceTask"></TaskSearch>
+    <!-- 人员选择 -->
+    <EmployeeSelector :multi="false" :isRequired="true" key="selected_user" title="选择人员" :visible.sync="selectUser" @confirm="confirmUser" :can_select_dept="false" :selected.sync="selected_user"></EmployeeSelector>
+
+    <!-- 可见范围 -->
+    <van-action-sheet v-model="isShowV" :actions="vArr" @select="activevArr" cancel-text="取消" close-on-click-action/>
+
+    <!-- 关联KR -->
+    <TargetSearch :visible.sync="isShwoKrSearch" :showSelectType="2" @confirm="ActiveRelevanceKr"></TargetSearch>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue';
+import { Tab, Tabs, Circle,ActionSheet } from 'vant';
+import UpdateTarget from '@/okr/components/public/UpdateTarget';
+import TaskSearch from '@/okr/components/public/TaskSearch';
+import AddKr from '@/okr/components/public/AddKr';
+import EmployeeSelector from '@/components/EmployeeSelector';
+import Progress from '@/okr/components/public/Progress';
+import TargetSearch from '@/okr/components/public/TargetSearch';
+
+import {taskStatus,getBelongType,getDateStr,getOperation} from '@/okr/utils/auth';
+Vue.use(Tabs).use(Tab).use(Circle).use(ActionSheet);
+export default {
+  components:{UpdateTarget,AddKr,TaskSearch,EmployeeSelector,Progress,TargetSearch},
+  data() {
+    return {
+      targetDetail:{visible:1},
+      processInfo:{},
+      getBelongType:getBelongType,
+      taskStatus:taskStatus,
+      userInfo: this.$userInfo(),
+      tabActive: 0,
+      tabs: ['OKRs', '计划', '进展','成员'],
+      targetTypeArr: [{ name: '目标进展', id: 1 }, { name: 'KR进展', id: 2 }, { name: '子目标进展', id: 3 }],
+      targetType: 1,
+      isShowbelong:false,
+      isShwoTaskSearch:false,
+      scopeArr:[{value: 0, name:'关注目标', disabled: false},{value: 1, name:'编辑基本信息',disabled: false},{value: 2,name:'结束目标',disabled: false},{value: 4,name:'复制目标',disabled: false},{value: 3,name:'删除目标',color: '#f56c6c',disabled: false}],
+      processList: [],
+      processData:{kr:[],objectives:[]},
+      isShwoUpdateDetail:false,
+      isShowAddKr:false,
+      userId:0,
+      krName:'',
+      weight:0,
+      o_id:0,
+      kr_id:0,
+      krsList:[],
+      krsListAll:[],//包括任务
+      isFollower:false,//是否关注
+      isUpdate:false,
+      selectUser:false,
+      selected_user: { dept: [], employee: [] } ,//传入已选部门
+      isShwoUpdateProgress:false,
+      progressData:{},
+      isShowProcess:false,
+      isOperation:true,
+      dept_tree:{},
+
+      // 可见范围
+      isShowV:false,
+      vArr:[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}],
+      addTaskIndex:1,
+      selectKr:{},
+      isShwoKrSearch:false,
+    };
+  },
+  watch:{
+    isFollower(val){
+      if(val){
+        this.scopeArr.forEach(item=>{
+          if(item.value==0){item.name='取消关注'}
+        })
+      }else{
+        this.scopeArr.forEach(item=>{
+          if(item.value==0){item.name='关注目标'}
+        })
+      }
+    },
+    tabActive(val){
+      if(val==0){
+        this.getKrList();
+      }else if(val==1){
+        this.getkrTaskList();
+      }else if(val==2){
+        this.getProcess();
+      }
+    }
+  },
+  methods: {
+    //关联项目
+    ActiveRelevanceKr(item){
+      this.$axiosUser('post', '/api/pro/okr/project/bind',{project_id:item.item.id,kr_id:this.selectKr.id}).then(res => {
+       this.getkrTaskList();
+      });
+    },
+    activevArr(item){
+      if(this.addTaskIndex==1){
+        if(item.value==1){
+          let data={
+            target_type:	2,//是	string	计划绑定的对象种类 1-目标 2-KR 3-计划(分解计划下的子计划的时候)
+            target_id:this.selectKr.id,//是	integer	绑定的对象id 跟对象种类配对使用
+          }
+          this.$router.push({name: 'addTask', query: data})
+        }else{
+          this.$router.push({name: 'addProject', query: {kr_id:this.selectKr.id}})
+        }
+      }else{
+        if(item.value==1){
+            this.kr_id=this.selectKr.id;
+            this.isShwoTaskSearch=true;
+        }else{
+            this.isShwoKrSearch=true;
+        }
+      }
+    },
+    openDetail(item,type){
+
+      if(type==1){
+        this.$router.push({name: 'myTargetDetail', query: {id: item.id}})
+      }else if(type==2){
+        this.$router.push({name: 'myKrDetail', query: {id: item.id}})
+      }else if(type==3){
+        // this.$router.push({name: 'projectDetail', query: {id: item.id}})
+        return
+      }
+    },
+    subContent(action, done){
+       if (action == 'confirm') {
+         this.$axiosUser('post', '/api/pro/okr/process/content',{p_id: this.processInfo.id, content: this.processInfo.content}).then(res => {
+           this.getProcess();
+           this.isShowProcess = false;
+         })
+         done()
+       }else{
+         done()
+       }
+    },
+    compileContent(item){
+      this.processInfo = JSON.parse(JSON.stringify(item));
+      this.isShowProcess = true;
+    },
+    update(){
+      this.getTargetDateil();
+      this.getProcess();
+    },
+    // 沟通
+    openCommunication(){
+      let data = {
+        item: JSON.stringify(this.targetDetail),
+        target_type: 1,
+        readonly: 1
+      }
+      this.$router.push({name: 'communication', query:data})
+    },
+    // 获取部门列表
+    returnArr(list,arr){
+      list.forEach(item=>{
+        arr[item.id]=item
+        if(item.children.length>0){
+          this.returnArr(item.children,arr)
+        }
+      })
+    },
+    // 获取部门列表
+    get_department_list() {
+      this.$axiosUser('get','/api/pro/department/tree','','v2').then((res) => {
+          let list=res.data.data.list
+          let dept_tree={};
+          this.returnArr(list,dept_tree)
+          this.dept_tree=dept_tree
+      })
+    },
+    //更新完成度
+    updateProgress(){
+      let item=this.targetDetail;
+      this.progressData={
+        target_type:1,
+        id:item.id,
+        o_id:item.id,
+        process:Number(item.process),
+        risk_level:item.risk_level,
+        process_conf:item.process_conf,
+      }
+      this.isShwoUpdateProgress=true;
+    },
+    //获取最新字段
+    getProcess(){
+      let axios= this.$axiosUser('get', '/api/pro/okr/public/process/list', {target_type:1,target_id:this.o_id,page:1,page_size:100})
+      let axios2= this.$axiosUser('get', '/api/pro/okr/public/process/sub', {target_type:1,target_id:this.o_id})
+      Promise.all([axios,axios2]).then(res => {
+          let data=res[1].data.data
+          data.objectives=this.updatePro(data.objectives);
+          data.kr=this.updatePro(data.kr);
+          this.processData=data;
+          this.processList=this.updatePro(res[0].data.data.list)
+      })
+    },
+    updatePro(arr){
+      arr.forEach(item=>{
+         item.updatePro=Math.abs(item.process-item.process_last).toFixed(2);
+         item.isUpdatePro=item.process-item.process_last
+      })
+      return arr;
+    },
+    openSelectUser(index){
+      this.selectUserIndex=index;
+      this.selectUser=true;
+    },
+    confirmUser(data) {
+      let user=data.employee[0]
+      if(this.selectUserIndex==1){
+        let params={object_id:this.targetDetail.id,owner_id:user.id,}
+        this.$axiosUser('POST', 'api/pro/okr/obj/change_owner', params).then(res => {
+            this.getTargetDateil();
+        })
+      }else if(this.selectUserIndex==2){
+        this.joinerUpdate(true,user.id);
+      }else{
+        this.deleteFollower(true,user.id);
+      }
+    },
+    //参与者
+    joinerUpdate(is,id){
+      let data={
+        object_id:this.o_id,
+        joiner_id:id,
+        action:is? 'add':'remove',
+      }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_joiner',data).then(res => {
+          this.getTargetDateil();
+      })
+    },
+    //关注者
+    deleteFollower(is,id){
+      let data={
+        object_id:this.o_id,
+        employee_id:id,
+        action:is? 'add':'remove',
+      }
+      this.$axiosUser('post', '/api/pro/okr/obj/change_focus',data).then(res => {
+          this.getTargetDateil();
+      })
+    },
+    //关联母任务
+    ActiveRelevanceTask(item){
+        if(item.id){
+          this.$axiosUser('POST', '/api/pro/okr/plan/relate/other',{plan_id:item.id,target_type:2,target_id:this.kr_id}).then(res => {
+               this.getkrTaskList();
+          })
+        }
+    },
+    addTask(item,index){
+      this.addTaskIndex=index;
+      this.selectKr=item;
+      if(index==1){
+        this.vArr=[{value: 1,name: '添加任务'},{value: 2,name: '添加项目'}];
+      }else{
+        this.vArr=[{value: 1,name: '关联任务'},{value: 2,name: '关联项目'}];
+      }
+      this.isShowV=true;
+    },
+    confirmAddkr(item){
+      this.$axiosUser('POST','api/pro/okr/kr/create',item).then(res => {
+         this.$toast("已添加");
+         this.getKrList()
+      })
+    },
+    activebelong(item){
+      if(item.value==0){//关注
+        this.$axiosUser('POST','/api/pro/okr/obj/follow',{o_id:this.o_id}).then(res => {
+           this.$toast(this.isFollower? "已取消":'已关注');
+           this.getTargetDateil();
+        })
+      }else if(item.value==1){//编辑
+        this.isShwoUpdateDetail=true;
+      }else if(item.value==2){//结束目标
+        if(item.name=='结束目标'){
+          this.$dialog.confirm({ title:'结束', message: '确定要结束目标吗?'}).then(() => {
+            this.$axiosUser('post', '/api/pro/okr/obj/to_finish', { object_id: this.o_id }).then(res => {
+                this.getTargetDateil()
+            });
+          });
+        }else{
+          this.$axiosUser('POST', '/api/pro/okr/obj/to_start',{object_id:this.o_id}).then(res => {
+             this.getTargetDateil()
+          })
+        }
+      }else if(item.value==3){//删除
+        this.$dialog.confirm({ title:'删除', message: '目标删除操作不可恢复!请谨慎操作'}).then(() => {
+          this.$axiosUser('post', '/api/pro/okr/public/obj/d', { o_id: this.o_id }).then(res => {
+              this.$toast("已删除");
+              setTimeout(()=>{
+                this.$route_back()
+              },500)
+          });
+        });
+      }else if(item.value==4){//复制目标
+        this.$router.push({name: 'copyTarget', query: {id:this.o_id}})
+      }
+    },
+    returnSum(arr){
+      if(arr.length==0){return 0};
+      let sum=0;
+      arr.forEach(item=>{
+        if(item.composite_state==6){
+          sum++;
+        }
+      })
+      return sum
+    },
+    //执行
+    getkrTaskList(){
+	  if(!this.o_id){
+		  return false
+	  }
+      let data={
+        o_id:this.o_id,//	是	string	目标id
+        plan_calc: 1
+      }
+      this.$axiosUser('get', '/api/pro/okr/public/plan/list/o',data).then(res => {
+        let list=res.data.data.list;
+        list.forEach(e=>{
+          if(e.plans&&e.plans.length>0){
+            e.plans.forEach(item=>{
+              item.day=this.$moment(item.end_date).diff(this.$moment().format('YYYY-MM-DD'), 'day')
+            })
+          }
+        })
+        this.krsListAll=list;
+      })
+    },
+    //OKRs
+    getKrList(){
+      this.krsList=[];
+      this.$axiosUser('get', '/api/pro/okr/public/kr/list',{o_id:this.o_id}).then(res => {
+          let list=res.data.data.list;
+          this.krsList=list
+      })
+    },
+    //目标详情
+    getTargetDateil(){
+      this.isFollower=false;
+      this.$axiosUser('get', '/api/pro/okr/public/obj/detail',{object_id:this.o_id}).then(res => {
+          let data=res.data.data;
+          data.dateStr=getDateStr(data)
+          data.owner_userInfo=this.$getEmployeeMapItem(data.owner_id);//负责人
+          data.special_employee_items=data.special_employee_ids.map(e=>{ //可见人员
+              return this.$getEmployeeMapItem(e)
+          })
+          data.joiner_employee_items=data.joiner_ids.map(e=>{//参与人员
+              return this.$getEmployeeMapItem(e)
+          })
+          data.follower_employee_items=data.follower_ids.map(e=>{//关注者
+              return this.$getEmployeeMapItem(e)
+          })
+          if(data.follower_ids.length>0){
+            data.follower_ids.some(e=>{//关注者
+                if(e==this.userInfo.id){
+                   this.isFollower=true;
+                   return true
+                }
+            })
+          }
+          if(data.finish_status!=0){
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){item.name='重启目标'}
+            })
+          }else{
+            this.scopeArr.forEach(item=>{
+              if(item.value==2){ item.name='结束目标' }
+            })
+          }
+
+          // 权限[{value: 0, name:'关注目标'},{value: 1, name:'编辑基本信息'},{value: 2,name:'结束目标'},{value: 3,name:'删除目标',color: '#f56c6c'}],
+          if(!data.can_edit){ //不可编辑
+            this.scopeArr.forEach(item=>{
+              if(item.value==1){
+                item.disabled=true
+              }
+              if(item.value==2&&item.name=='结束目标'){
+                item.disabled=true
+              }
+              // if(item.value==4){
+              //   item.disabled=true
+              // }
+            })
+          }
+          if(!data.can_delete){ //不可删除
+            this.scopeArr.forEach(item=>{
+              if(item.value==3){item.disabled=true}
+            })
+          }
+
+          this.isOperation=getOperation(data.publisher_id,data.owner_id);
+          this.targetDetail=this.updatePro([data])[0];
+      })
+    },
+  },
+  mounted() {
+    this.get_department_list();
+    if(this.$route.query.id){
+      this.o_id=this.$route.query.id;
+      this.getTargetDateil();
+      this.getKrList();
+    }
+  },
+  activated() {
+  	 this.getkrTaskList();
+  }
+};
+</script>
+
+<style scoped lang="less">
+  .textarea-box /deep/ .van-field__control{
+    max-height: 400px;
+  }
+  .footer {
+    padding: 0.14rem 0.2rem;
+    border-top: 0.02rem solid #f1f1f1;
+    background: #fff;
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 999;
+    box-shadow: 0px -3px 0.15rem #f7f8fa;
+  }
+  .footer .gt {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    border: 0.02rem solid #f1f1f1;
+    font-size: 0.32rem;
+  }
+  .footer i{
+    font-size: 0.6rem;
+  }
+  .footer .btn {
+    border-radius: 0.5rem;
+    padding:0.18rem 0.14rem;
+    // border: 0.02rem solid #26A2FF;
+    color: #fff;
+    text-align: center;
+    background: #26A2FF;
+    font-size: 0.32rem;
+  }
+  .huan{
+    position: relative;
+    width: 0.4rem;
+    height: 0.4rem;
+    border-radius: 100%;
+    background-color: #E9F1FE;
+    box-sizing: border-box;
+    text-align: center;
+    margin-right: 0.1rem;
+  }
+  .huan span{
+    border: 2px solid #26A2FF;
+    border-radius: 100%;
+    width: 0.16rem;
+    height: 0.16rem;
+    display: inline-block;
+  }
+  .status{
+    position: relative;
+    // top: 1px;
+    font-size: 0.24rem;
+    border-radius: 15px;
+    line-height:0.32rem;
+    color: #26A2FF;
+    height: 0.32rem;
+    padding: 0px 0.04rem;
+    border: 1px solid #26A2FF;
+  }
+  .aite{
+      width: 1rem;
+      height: 1rem;
+      text-align: center;
+      line-height: 1rem;
+      font-size: 0.6rem;
+      cursor: pointer;
+      display: inline-block;
+      box-shadow: 0 0 3px #89919f;
+      border-radius: 100%;
+      background-color: #fff;
+      position: absolute;
+      z-index: 2;
+      bottom: 0.4rem;
+      right: 0.4rem;
+  }
+  .aite i{
+    font-size: 0.36rem;
+  }
+.o-content {
+  border-radius: 5px;
+  padding: 5px;
+  margin-left: 0.24rem;
+  margin-bottom: 5px;
+  font-size: 0.28rem;
+}
+.o-content:hover {
+  background-color: #f7f8fa;
+}
+.o-content:hover .fontColorC {
+  display: block !important;
+  cursor: pointer;
+}
+.biaos {
+  width: 0.14rem;
+  height: 0.14rem;
+  background-color: #26a2ff;
+  border: 1px solid #fff;
+  border-radius: 100%;
+  box-shadow: 0 0 0.14rem #26a2ff;
+  display: inline-block;
+  margin-right: 0.14rem;
+}
+.biaos2 {
+  background-color: #ff9600;
+  box-shadow: 0 0 0.14rem #ff9600;
+}
+.biaos3 {
+  background-color: #f56c6c;
+  box-shadow: 0 0 0.14rem #f56c6c;
+}
+.add-jz {
+  width: 1.4rem;
+  text-align: center;
+  padding: 0.04rem 0.08rem;
+  color: #26a2ff;
+  border: 1px solid #26a2ff;
+  border-radius: 25px;
+  cursor: pointer;
+  font-size: 0.26rem;
+}
+.search-item {
+  padding: 0.06rem 0.1rem;
+  background-color: #f7f8fa;
+  color: #89919f;
+  width: 1.3rem;
+  text-align: center;
+  margin-right: 0.2rem;
+  border-radius: 3px;
+  font-size: 0.3rem;
+  border-radius: 25px;
+  font-size: 0.26rem;
+}
+.searchActive {
+  color: #26A2FF;
+  background-color: #e9f0fd;
+}
+.delete-user {
+  position: absolute;
+  right: -4px;
+  top: -4px;
+  padding: 0;
+}
+.btns span {
+  width: 1.4rem;
+  text-align: center;
+  padding: 0.04rem 0.1rem;
+  color: #26A2FF;
+  margin-right: 0.2rem;
+  border: 0.02rem solid #26A2FF;
+  border-radius: 0.06rem;
+  font-size: 0.26rem;
+}
+.user-title {
+  font-size: 0.28rem;
+  // font-weight: 700;
+  color: #89919f;
+  margin: 0.2rem 0;
+}
+.addUser {
+  font-size: 0.6rem;
+  padding: 0.2rem;
+  border: 1px dashed #89919f;
+  text-align: center;
+  height: 0.4rem;
+  width: 0.4rem;
+  line-height: 0.4rem;
+  color: #89919f;
+  border-radius: 100px;
+}
+.zj {
+  width: 1rem;
+  text-align: center;
+  color: #26A2FF;
+  border: 0.02rem solid #26A2FF;
+  border-radius: 0.04rem;
+  font-size: 0.24rem;
+}
+.zj2 {
+  width: 1rem;
+  text-align: center;
+  color: #f56c6c;
+  border: 0.02rem solid #f56c6c;
+  border-radius: 0.04rem;
+  font-size: 0.24rem;
+}
+.addKr {
+  padding: 0.2rem;
+  font-size: 0.3rem;
+  background-color: #fff;
+  border-radius: 5px;
+  text-align: center;
+  margin: 0 0.2rem;
+  margin-top: 0.2rem;
+}
+.padding-l-r {
+  padding: 0 0.1rem;
+  border-left: 1px solid #f1f1f1;
+  border-right: 1px solid #f1f1f1;
+  margin: 0 0.1rem;
+}
+.scroller {
+  height: calc(100% - 3.58rem) !important;
+  position: relative !important;
+}
+.list-box {
+  padding: 0.2rem;
+  font-size: 0.32rem;
+  background-color: #fff;
+  border-radius: 5px;
+  margin: 0 0.2rem;
+  margin-top: 0.2rem;
+}
+.shadow {
+  border-bottom: 1px solid #f5f7fa;
+}
+/deep/ .van-tabs__line {
+  width: 20px !important;
+  background-color: #26A2FF;
+}
+/deep/ .van-tab--active {
+  color: #26A2FF;
+}
+.all-box {
+  height: calc(100% - 0.92rem) !important;
+  position: relative !important;
+}
+.progress {
+  border-radius: 100px;
+  background-color: #ebeef5;
+  overflow: hidden;
+  position: relative;
+  vertical-align: middle;
+  height: 0.2rem;
+  width: 3rem;
+}
+.progress-inner {
+  width: 0%;
+  position: absolute;
+  left: 0;
+  top: 0;
+  padding-top: 1px;
+  height: 100%;
+  background-image: linear-gradient(to right, #99bbff 0%, #2879ff 100%);
+  border-radius: 100px;
+  color: #fff;
+  white-space: nowrap;
+  transition: width 0.6s ease;
+}
+  .bjYellow{
+    background-image: linear-gradient(to right, #fedf86 0%, #FF9600 100%);
+  }
+  .bjRed{
+    background-image: linear-gradient(to right, #FEA2A2 0%, #F16060 100%);
+  }
+.header {
+  padding: 0.24rem;
+  background-color: #fff;
+  z-index: 9999;
+  // background-image: linear-gradient(to bottom, #26A2FF 0%, #99BBFF 100%);
+}
+</style>

+ 37 - 2
src/performance/view/performanceHome.vue

@@ -1,6 +1,15 @@
 <template>
   <div>
     <div class="all">
+      
+      <div class="notice-bar" @click="toggelSystem()">
+        <div class="flex-box-ce flex-1">
+          <van-icon name="info-o"></van-icon>
+          <span>绩效系统已经升级,去体验新系统</span>
+        </div>
+        <span class="blue">切换新系统</span>
+      </div>
+
       <header class="workHeader">
         <van-grid :border="false" style="background-color: #fff;position: relative;" class="border-bottom">
           <van-grid-item v-if="app.isShow" v-for="(app, index) in topMenuList" :dot="app.dot" :badge="app.badge" :key="app.code" @click="openUrl(app)" :text="app.code">
@@ -39,7 +48,7 @@
                        </div>
                     </div>
                     <div>
-                      <div  style="font-size: 0.28rem;margin-bottom: 0.1rem;" class="flex-box-end">
+                      <div  style="font-size: 0.28rem; margin-bottom: 0.1rem;" class="flex-box-end">
                         <template v-if="typeIndex==1">
                           <span  class="green" v-if="item.count_record">{{item.count_record}}条管理记录</span>
                           <span  class="fontColorC" v-else>无管理记录</span>
@@ -197,6 +206,7 @@ Vue.use(Tabs).use(Tab).use(Search);
 export default {
   data() {
     return {
+      isAndroid: navigator.userAgent.indexOf('Android') > 0,
       selectpfdlg: false, // 选择时间弹窗开关
       selectpfList: [
         // 选择时间选项
@@ -249,7 +259,7 @@ export default {
       topMenuList:[
         {code:"待办",icon:"static/images/daiban.png",url:'backlog',badge:0,isShow:true},
         {code:"通知",icon:"static/images/tongzhi.png",url:'messageInform',badge:0,isShow:true},
-        {code:"绩效报表",icon:"static/images/jixiaobaobiao.png",url:'statement',isShow:this.$userInfo().employee_detail.manage_dept_ids.length>0||(this.$getRole(1) && this.$getPermis(16))},
+        {code:"考核明细",icon:"static/images/jixiaobaobiao.png",url:'statement',isShow:this.$userInfo().employee_detail.manage_dept_ids.length>0||(this.$getRole(1) && this.$getPermis(16))},
         {code:"我的绩效",icon:"static/images/wodejixiao.png",url:'me',isShow:this.$getRole(1)||this.$getRole(2)},
       ],
     };
@@ -306,6 +316,12 @@ export default {
     }
   },
   methods: {
+    // 切换新系统
+    toggelSystem() {
+      this.$emit("changeSystem", "chooseNew")
+      localStorage.setItem("chooseNew", true)
+    },
+
     openUrl(item) {
       this.$router.push({ name:item.url});
     },
@@ -646,6 +662,25 @@ export default {
   }
 }
 
+.notice-bar {
+  width: 100%;
+  height: 0.8rem;
+  font-size: 0.28rem;
+  line-height: 0.8rem;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  color: #606266;
+  background: rgb(236, 249, 255);
+  padding: 0 0.2rem;
+  box-sizing: border-box;
+  i {
+    margin-right: 0.2rem;
+    font-size: 0.3rem;
+    color: rgb(25, 137, 250);
+  }
+}
+
 
 .workHeader {
   background-color: #fff;

+ 1 - 1
src/point/view/body/add_common_menu.vue

@@ -67,7 +67,7 @@ export default {
       return JSON.stringify(item)
     },
     deleteEl(obj){
-      if(this.menuList.length==1){
+      if(this.menuList.length == 1){
         this.$toast('常用菜单最少保留一个')
         return false
       }

+ 1 - 1
src/point/view/integral/appealList.vue

@@ -101,7 +101,7 @@ export default {
       },
       list:[],
       ll:[],
-      appealStatusMap:{
+      appealStatusMap: {
         0:'全部',
         1:'审批中',
         2:'审批通过',

+ 3 - 0
src/point/view/integral/deptRank.vue

@@ -210,12 +210,15 @@ export default {
       this.timeScope = [new Date(moment().subtract(1,'month').startOf('month').format('YYYY-MM-DD')),new Date(moment().subtract(1,'month').endOf('month').format('YYYY-MM-DD'))]
       this.showCalendar = false
     },
+
     calendarOpen(){
       this.showCalendar = true;
     },
+
     calendarClose(){
       this.showCalendar = false;
     },
+
     calendarConfirm(event){
       const [start,end] = event;
       this.timeScope = [start,end];

+ 1 - 1
src/point/view/integral/event_list.vue

@@ -51,7 +51,7 @@ import Vue from 'vue';
 import moment from 'moment';
 
 import { _debounce, _throttle } from '@/utils/auth';
-import { DropdownMenu, DropdownItem, Empty, Search,NoticeBar } from 'vant';
+import { DropdownMenu, DropdownItem, Empty, Search, NoticeBar } from 'vant';
 import DateSelectorDropdown from '@/components/DateSelectorDropdown';
 import DeptSelectorDropdown from '@/components/DeptSelectorDropdown';
 import RuleCategorySelDropdown from '@/components/RuleCategorySelDropdown';

+ 2 - 0
src/point/view/integral/integral_entry_n.vue

@@ -374,8 +374,10 @@ export default {
     },
     openSelect(){
       if(this.rule_switch){
+        if(this.$refs.rule_selector)
           this.$refs.rule_selector.show_dept_selector=true;
       }else{
+        if(this.$refs.rule_selector2)
           this.$refs.rule_selector2.show_dept_selector=true;
       }
     },

Some files were not shown because too many files changed in this diff