From 119ead459f17a1a1c2fd5e0f4d08febc681d6d86 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期一, 30 三月 2026 16:17:58 +0800
Subject: [PATCH] 绩效管理:人员能力功能模块

---
 src/utils/request.js                                               |    2 
 src/api/performance/staffCompetencyLevelEvaluateRecord.js          |   29 ++
 src/views/performance/attendance/index.vue                         |   40 +--
 src/views/performance/competency/index.vue                         |  226 ++++++++++++++++++++
 src/api/performance/staffCompetencyInspectItemConfig.js            |   52 ++++
 src/views/performance/competency/components/config.vue             |  269 ++++++++++++++++++++++++
 src/views/performance/attendance/components/staffClockInRecord.vue |    2 
 7 files changed, 595 insertions(+), 25 deletions(-)

diff --git a/src/api/performance/staffCompetencyInspectItemConfig.js b/src/api/performance/staffCompetencyInspectItemConfig.js
new file mode 100644
index 0000000..95f02a6
--- /dev/null
+++ b/src/api/performance/staffCompetencyInspectItemConfig.js
@@ -0,0 +1,52 @@
+import request from '@/utils/request'
+
+// 鏌ヨ閮ㄩ棬鍒楄〃
+export function listConfig(query) {
+  return request({
+    url: '/staffCompetencyInspectItemConfig/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏌ヨ閮ㄩ棬鍒楄〃锛堟帓闄よ妭鐐癸級
+export function listConfigExcludeChild(configId) {
+  return request({
+    url: '/staffCompetencyInspectItemConfig/list/exclude/' + configId,
+    method: 'get'
+  })
+}
+
+// 鏌ヨ閮ㄩ棬璇︾粏
+export function getConfig(configId) {
+  return request({
+    url: '/staffCompetencyInspectItemConfig/' + configId,
+    method: 'get'
+  })
+}
+
+// 鏂板閮ㄩ棬
+export function addConfig(data) {
+  return request({
+    url: '/staffCompetencyInspectItemConfig',
+    method: 'post',
+    data: data
+  })
+}
+
+// 淇敼閮ㄩ棬
+export function updateConfig(data) {
+  return request({
+    url: '/staffCompetencyInspectItemConfig',
+    method: 'put',
+    data: data
+  })
+}
+
+// 鍒犻櫎閮ㄩ棬
+export function delConfig(configId) {
+  return request({
+    url: '/staffCompetencyInspectItemConfig/' + configId,
+    method: 'delete'
+  })
+}
diff --git a/src/api/performance/staffCompetencyLevelEvaluateRecord.js b/src/api/performance/staffCompetencyLevelEvaluateRecord.js
new file mode 100644
index 0000000..edf8df7
--- /dev/null
+++ b/src/api/performance/staffCompetencyLevelEvaluateRecord.js
@@ -0,0 +1,29 @@
+import request from '@/utils/request'
+
+// 鑾峰彇鐢ㄦ埛绛夌骇璇勫畾鍒楄〃
+export function getPageList(query) {
+  return request({
+    url: '/StaffCompetencyLevelEvaluateRecord/getPageList',
+    method: 'get',
+    params: query
+  })
+}
+
+// 淇敼鐢ㄦ埛绛夌骇
+export function changeLevel(data) {
+  return request({
+    url: '/StaffCompetencyLevelEvaluateRecord/changeLevel',
+    method: 'post',
+    data: data
+  })
+}
+
+// 瀵煎嚭浜哄憳鑳藉姏鍒楄〃
+export function exportRecords(data) {
+  return request({
+    url: '/StaffCompetencyLevelEvaluateRecord/exportRecords',
+    method: 'get',
+    params: data,
+    responseType: 'blob'
+  })
+}
diff --git a/src/utils/request.js b/src/utils/request.js
index d04da70..9a47e17 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -100,7 +100,7 @@
     // 鏈缃姸鎬佺爜鍒欓粯璁ゆ垚鍔熺姸鎬�
     const code = res.data.code || 200;
     // 鑾峰彇閿欒淇℃伅
-    const msg = errorCode[code] || res.data.msg || errorCode["default"];
+    const msg = res.data.message || res.data.msg || errorCode[code] || errorCode["default"];
     // 浜岃繘鍒舵暟鎹垯鐩存帴杩斿洖
     if (
       res.request.responseType === "blob" ||
diff --git a/src/views/performance/attendance/components/staffClockInRecord.vue b/src/views/performance/attendance/components/staffClockInRecord.vue
index c1860c2..7bdefbd 100644
--- a/src/views/performance/attendance/components/staffClockInRecord.vue
+++ b/src/views/performance/attendance/components/staffClockInRecord.vue
@@ -297,7 +297,7 @@
       changeEnableReport(data).then(res=>{
         if(res.code===200){
           this.$message.success("鎿嶄綔鎴愬姛")
-          this.refreshTable()
+          this.$emit("changeEnable")
         }
       })
     },
diff --git a/src/views/performance/attendance/index.vue b/src/views/performance/attendance/index.vue
index 3726bc0..d197b61 100644
--- a/src/views/performance/attendance/index.vue
+++ b/src/views/performance/attendance/index.vue
@@ -64,14 +64,14 @@
           </el-table-column>
           <el-table-column prop="swingDate" label="鑰冨嫟鏃堕棿" min-width="150" width="150"></el-table-column>
           <el-table-column label="绛惧叆/绛惧嚭鎯呭喌">
-            <el-table-column prop="workDateTime" label="涓婄彮鏃堕棿" min-width="160" width="160">
+            <el-table-column prop="workDateTime" label="涓婄彮鏃堕棿" min-width="160" >
               <template slot-scope="scope">
                 <el-tag type="success" v-if="scope.row.workDateTime && scope.row.workClockInState===1">{{ scope.row.workDateTime }}</el-tag>
                 <el-tag type="danger" v-else-if="scope.row.workDateTime && scope.row.workClockInState===0">{{ scope.row.workDateTime }}</el-tag>
                 <span v-else>{{ scope.row.workDateTime }}</span>
               </template>
             </el-table-column>
-            <el-table-column prop="offWorkDateTime" label="涓嬬彮鏃堕棿" min-width="160" width="160">
+            <el-table-column prop="offWorkDateTime" label="涓嬬彮鏃堕棿" min-width="160" >
               <template slot-scope="scope">
                 <el-tag type="success" v-if="scope.row.offWorkDateTime && scope.row.offClockInState===1">{{ scope.row.offWorkDateTime }}</el-tag>
                 <el-tag type="danger" v-else-if="scope.row.offWorkDateTime && scope.row.offClockInState===0">{{ scope.row.offWorkDateTime }}</el-tag>
@@ -80,19 +80,19 @@
             </el-table-column>
           </el-table-column>
           <el-table-column label="鑰冨嫟鏃堕暱(h)">
-            <el-table-column prop="plannedWorkHours" label="搴斿嫟鏃堕暱" min-width="80" width="80"></el-table-column>
-            <el-table-column prop="actualWorkHours" label="瀹為檯鏃堕暱" min-width="80" width="80"></el-table-column>
-            <el-table-column prop="absenceWorkHours" label="缂哄嫟鏃堕暱" min-width="80" width="80"></el-table-column>
+            <el-table-column prop="plannedWorkHours" label="搴斿嫟鏃堕暱" min-width="100" ></el-table-column>
+            <el-table-column prop="actualWorkHours" label="瀹為檯鏃堕暱" min-width="100"></el-table-column>
+            <el-table-column prop="absenceWorkHours" label="缂哄嫟鏃堕暱" min-width="100" ></el-table-column>
           </el-table-column>
-          <el-table-column prop="isSync" label="鏁版嵁鏉ユ簮" min-width="120">
+          <el-table-column prop="isSync" label="鏁版嵁鏉ユ簮" min-width="120" width="120">
             <template slot-scope="scope">
               <el-tag v-if="scope.row.isSync===0" type="success">ICC鍚屾</el-tag>
               <el-tag v-else-if="scope.row.isSync===1" type="info">鎵嬪姩鏂板</el-tag>
             </template>
           </el-table-column>
-          <el-table-column prop="createUser" label="鍒涘缓浜�" min-width="150" width="150" :formatter="(row)=>formatterUserName(row.createUser)"></el-table-column>
+          <el-table-column prop="createUser" label="鍒涘缓浜�" min-width="120" width="120" :formatter="(row)=>formatterUserName(row.createUser)"></el-table-column>
           <el-table-column prop="createTime" label="鍒涘缓鏃堕棿" min-width="180" width="180"></el-table-column>
-          <el-table-column prop="updateUser" label="鏇存柊浜�" min-width="150" width="150" :formatter="(row)=>formatterUserName(row.updateUser)"></el-table-column>
+          <el-table-column prop="updateUser" label="鏇存柊浜�" min-width="120" width="120" :formatter="(row)=>formatterUserName(row.updateUser)"></el-table-column>
           <el-table-column prop="updateTime" label="鏇存柊鏃堕棿" min-width="180" width="180"></el-table-column>
           <el-table-column fixed="right" width="180" label="鎿嶄綔">
             <template slot-scope="scope">
@@ -114,7 +114,7 @@
       title="杩涘嚭璁板綍"
       :visible.sync="dialogVisible"
       width="60%">
-      <staff-clock-in-record :key="Math.random()" :query-params="clockInQueryParams" ></staff-clock-in-record>
+      <staff-clock-in-record :query-params="clockInQueryParams" @changeEnable="refreshTable()"></staff-clock-in-record>
     </el-dialog>
     <el-dialog
       :title="attendanceForm.id?'缂栬緫鑰冨嫟璁板綍':'鏂板鑰冨嫟璁板綍'"
@@ -158,18 +158,11 @@
                 </el-select>
               </el-form-item>
             </el-col>
-            <el-col :span="12">
-<!--              <el-form-item label="鑰冨嫟缁撴灉" prop="result">-->
-<!--                <el-select size="small" style="width:100%" clearable v-model="attendanceForm.result" placeholder="璇烽�夋嫨鑰冨嫟缁撴灉">-->
-<!--                  <el-option v-for="(item,index) in resultList" :key="index" :label="item.label" :value="item.value"/>-->
-<!--                </el-select>-->
-<!--              </el-form-item>-->
-            </el-col>
           </el-row>
           <el-divider content-position="left">绛惧叆/绛惧嚭鎯呭喌</el-divider>
           <el-row>
             <el-col :span="12">
-              <el-form-item label="涓婄彮鏃堕棿" prop="workTime">
+              <el-form-item label="涓婄彮鏃堕棿" prop="workDateTime">
                 <el-time-picker
                   style="width:100%"
                   value-format="HH:mm"
@@ -180,7 +173,7 @@
               </el-form-item>
             </el-col>
             <el-col :span="12">
-              <el-form-item label="涓嬬彮鏃堕棿" prop="offWorkTime">
+              <el-form-item label="涓嬬彮鏃堕棿" prop="offWorkDateTime">
                 <el-time-picker
                   style="width:100%"
                   value-format="HH:mm"
@@ -492,11 +485,12 @@
     openAddAttendanceDialog(row){
       if(row){
         //澶勭悊涓�/涓嬬彮鏃堕棿鏍煎紡
-        let workTime = row.workDateTime&&row.workDateTime.length>8?row.workDateTime.substring(11,16):row.workDateTime
-        let offWorkTime = row.offWorkDateTime&&row.offWorkDateTime.length>8?row.offWorkDateTime.substring(11,16):row.offWorkDateTime
-        row.workDateTime = workTime
-        row.offWorkDateTime = offWorkTime
-        this.attendanceForm = {...row}
+        let formData = {...row}
+        let workTime = formData.workDateTime&&formData.workDateTime.length>8?formData.workDateTime.substring(11,16):formData.workDateTime
+        let offWorkTime = formData.offWorkDateTime&&formData.offWorkDateTime.length>8?formData.offWorkDateTime.substring(11,16):formData.offWorkDateTime
+        formData.workDateTime = workTime
+        formData.offWorkDateTime = offWorkTime
+        this.attendanceForm = formData
       }
       this.addAttendanceVisible = true
     },
diff --git a/src/views/performance/competency/components/config.vue b/src/views/performance/competency/components/config.vue
new file mode 100644
index 0000000..27a7666
--- /dev/null
+++ b/src/views/performance/competency/components/config.vue
@@ -0,0 +1,269 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" >
+      <el-form-item label="椤圭偣鍚嶇О" prop="itemName">
+        <el-input v-model="queryParams.itemName" placeholder="璇疯緭鍏ラ」鐐瑰悕绉�" clearable @keyup.enter.native="handleQuery" />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" size="mini" @click="handleQuery">鏌ヨ</el-button>
+        <el-button size="mini" @click="resetQuery">閲嶇疆</el-button>
+        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" >鏂板</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="info" plain icon="el-icon-sort" size="mini" @click="toggleExpandAll">灞曞紑/鎶樺彔</el-button>
+      </el-col>
+    </el-row>
+
+    <el-table :height="tableHeight" v-if="refreshTable" v-loading="loading" :data="configList" row-key="id"
+              :header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }" border
+              :default-expand-all="isExpandAll" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
+      <el-table-column prop="itemName" label="椤圭偣鍚嶇О" width="260"></el-table-column>
+      <el-table-column prop="isEnable" label="鐘舵��" width="100" align="center">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.isEnable">鍚敤</el-tag>
+          <el-tag v-else type="info">绂佺敤</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">淇敼</el-button>
+          <el-button size="mini" type="text" icon="el-icon-plus" @click="handleAdd(scope.row)">鏂板</el-button>
+          <el-button v-if="!scope.row.children" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" >鍒犻櫎</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 娣诲姞鎴栦慨鏀规楠岄」鐐瑰璇濇 -->
+    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-row>
+          <el-col :span="24" v-if="form.parentId > 0">
+            <el-form-item label="涓婄骇椤圭偣" prop="parentId">
+              <treeselect v-model="form.parentId" :options="configOptions" :normalizer="normalizer"
+                          placeholder="閫夋嫨涓婄骇椤圭偣" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="椤圭偣鍚嶇О" prop="itemName">
+              <el-input v-model="form.itemName" placeholder="璇疯緭鍏ラ」鐐瑰悕绉�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄剧ず鎺掑簭" prop="sort">
+              <el-input-number v-model="form.sort" controls-position="right" :min="0" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鏄惁鍚敤" prop="isEnable">
+              <el-switch v-model="form.isEnable"></el-switch>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+        <el-button @click="cancel">鍙� 娑�</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listConfig, getConfig, delConfig, addConfig, updateConfig, listConfigExcludeChild } from "@/api/performance/staffCompetencyInspectItemConfig";
+import Treeselect from "@riophae/vue-treeselect";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+
+export default {
+  name: "StaffCompetencyInspectItemConfig",
+  components: { Treeselect },
+  data() {
+    return {
+      //琛ㄦ牸楂樺害
+      tableHeight:0,
+      // 閬僵灞�
+      loading: true,
+      // 鏄剧ず鎼滅储鏉′欢
+      showSearch: true,
+      // 琛ㄦ牸鏍戞暟鎹�
+      configList: [],
+      // 閮ㄩ棬鏍戦�夐」
+      configOptions: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+      // 鏄惁灞曞紑锛岄粯璁ゅ叏閮ㄥ睍寮�
+      isExpandAll: true,
+      // 閲嶆柊娓叉煋琛ㄦ牸鐘舵��
+      refreshTable: true,
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        itemName: undefined
+      },
+      // 琛ㄥ崟鍙傛暟
+      form: {},
+      // 琛ㄥ崟鏍¢獙
+      rules: {
+        itemName: [
+          { required: true, message: "椤圭偣鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }
+        ],
+        sort: [
+          { required: true, message: "鏄剧ず鎺掑簭涓嶈兘涓虹┖", trigger: "blur" }
+        ]
+      }
+    };
+  },
+  created() {
+    this.getList();
+    this.calcTableHeight()
+  },
+  mounted() {
+    window.addEventListener('resize', this.calcTableHeight);
+  },
+  beforeDestroy() {
+    window.removeEventListener('resize', this.calcTableHeight);
+  },
+  methods: {
+    calcTableHeight(){
+      const innerHeight = window.innerHeight
+      const outerHeight = 36 + 51 + 97 + 20
+      this.tableHeight = innerHeight - outerHeight
+    },
+    /** 鏌ヨ妫�楠岄」鐐瑰垪琛� */
+    getList() {
+      this.loading = true;
+      listConfig(this.queryParams).then(response => {
+        this.configList = this.handleTree(response.data, "id");
+        this.loading = false;
+      });
+    },
+    /** 杞崲妫�楠岄」鐐规暟鎹粨鏋� */
+    normalizer(node) {
+      if (node.children && !node.children.length) {
+        delete node.children;
+      }
+      return {
+        id: node.id,
+        label: node.itemName,
+        children: node.children
+      };
+    },
+    // 鍙栨秷鎸夐挳
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 琛ㄥ崟閲嶇疆
+    reset() {
+      this.form = {
+        id: undefined,
+        parentId: undefined,
+        itemName: undefined,
+        sort: undefined,
+        isEnable: true
+      };
+      this.resetForm("form");
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd(row) {
+      this.reset();
+      if (row != undefined) {
+        this.form.parentId = row.id;
+      }
+      this.open = true;
+      this.title = "娣诲姞妫�楠岄」鐐�";
+      listConfig().then(response => {
+        this.configOptions = this.handleTree(response.data, "id");
+        this.configOptions = this.limitTreeDepth(this.configOptions, 2)
+      });
+    },
+    /** 灞曞紑/鎶樺彔鎿嶄綔 */
+    toggleExpandAll() {
+      this.refreshTable = false;
+      this.isExpandAll = !this.isExpandAll;
+      this.$nextTick(() => {
+        this.refreshTable = true;
+      });
+    },
+    /** 淇敼鎸夐挳鎿嶄綔 */
+    handleUpdate(row) {
+      this.reset();
+      getConfig(row.id).then(response => {
+        this.form = response.data;
+        this.open = true;
+        this.title = "淇敼妫�楠岄」鐐�";
+        listConfigExcludeChild(row.id).then(response => {
+          this.configOptions = this.handleTree(response.data, "id");
+          if (this.configOptions.length == 0) {
+            const noResultsOptions = { id: this.form.parentId, itemName: this.form.parentName, children: [] };
+            this.configOptions.push(noResultsOptions);
+          }
+          this.configOptions = this.limitTreeDepth(this.configOptions, 2)
+        });
+      });
+    },
+    /** 鎻愪氦鎸夐挳 */
+    submitForm: function () {
+      this.$refs["form"].validate(valid => {
+        if (valid) {
+          if (this.form.id != undefined) {
+            updateConfig(this.form).then(response => {
+              this.$modal.msgSuccess("淇敼鎴愬姛");
+              this.open = false;
+              this.getList();
+              this.$emit("refresh");
+            });
+          } else {
+            addConfig(this.form).then(response => {
+              this.$modal.msgSuccess("鏂板鎴愬姛");
+              this.open = false;
+              this.getList();
+              this.$emit("refresh");
+            });
+          }
+        }
+      });
+    },
+    /** 鍒犻櫎鎸夐挳鎿嶄綔 */
+    handleDelete(row) {
+      this.$modal.confirm('鏄惁纭鍒犻櫎鍚嶇О涓�"' + row.itemName + '"鐨勬暟鎹」锛�').then(function () {
+        return delConfig(row.id);
+      }).then(() => {
+        this.getList();
+        this.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+        this.$emit("refresh");
+      }).catch(() => { });
+    },
+    // 閫掑綊鍑芥暟锛岀敤浜庨檺鍒舵爲鐨勬繁搴�
+    limitTreeDepth(options, maxDepth, currentDepth = 1) {
+      return options.map(option => {
+        const newOption = { ...option };
+        if (currentDepth < maxDepth && option.children) {
+          // 濡傛灉褰撳墠娣卞害灏忎簬鏈�澶ф繁搴︿笖瀛樺湪瀛愯妭鐐癸紝鍒欓�掑綊澶勭悊瀛愯妭鐐�
+          newOption.children = this.limitTreeDepth(option.children, maxDepth, currentDepth + 1);
+        } else {
+          // 鍚﹀垯绉婚櫎瀛愯妭鐐�
+          delete newOption.children;
+        }
+        return newOption;
+      });
+    }
+  }
+};
+</script>
diff --git a/src/views/performance/competency/index.vue b/src/views/performance/competency/index.vue
new file mode 100644
index 0000000..92e05bb
--- /dev/null
+++ b/src/views/performance/competency/index.vue
@@ -0,0 +1,226 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
+      <el-form-item prop="keyword">
+        <el-input
+          v-model="queryParams.keyword"
+          placeholder="宸ュ彿鎴栧憳宸ュ悕绉�"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item prop="postName">
+        <el-select v-model="queryParams.postName" clearable placeholder="璇烽�夋嫨宀椾綅" @change="handleQuery">
+          <el-option
+            v-for="(post, index) in postList"
+            :key="index"
+            :label="post.postName"
+            :value="post.postName"
+          >
+            <span style="float: left">{{ post.postName }}</span>
+            <span style="float: right; color: #8492a6; font-size: 13px">{{ post.postCode }}</span>
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" size="mini" @click="handleQuery"
+          >鏌ヨ</el-button
+        >
+        <el-button plain size="mini" @click="resetQuery">閲嶇疆</el-button>
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-setting"
+          size="mini"
+          @click="handleAdd"
+          >妫�楠岄」閰嶇疆</el-button
+        >
+        <el-button
+          type="success"
+          icon="el-icon-download"
+          size="mini"
+          :loading="downloadLoading"
+          @click="downloadRecords()"
+          >瀵煎嚭</el-button
+        >
+      </el-form-item>
+    </el-form>
+    <el-table
+      v-if="refreshTable"
+      v-loading="loading"
+      :data="recordList"
+      :height="tableHeight"
+      :cell-style="{ textAlign: 'center' }"
+      :header-cell-style="{
+        background: '#f8f8f9',
+        color: '#515a6e',
+        textAlign: 'center',
+      }"
+      border
+    >
+      <el-table-column type="index" label="搴忓彿" width="80"></el-table-column>
+      <el-table-column
+        prop="userName"
+        label="浜哄憳鍚嶇О"
+        min-width="120"
+        width="120"
+      ></el-table-column>
+      <el-table-column
+        prop="postName"
+        label="宀椾綅"
+        min-width="120"
+        width="120"
+      ></el-table-column>
+      <!--鍔ㄦ�佸垪-->
+      <el-table-column v-for="(item, i) in tableHeaderList" :key="i" :prop="item.id + ''" :label="item.itemName">
+        <el-table-column min-width="130" v-if="item.children" v-for="(children,k) in item.children" :key="k"  :prop="children.id + ''" :label="children.itemName">
+          <template slot-scope="scope">
+            <el-select size="small" v-model="scope.row[children.id].level" clearable @change="changeSkillLevel(scope.row, children.id)">
+              <el-option v-for="(dict,j) in levelDictList" :label="dict.dictLabel" :value="dict.dictValue" :key="j"></el-option>
+            </el-select>
+          </template>
+        </el-table-column>
+      </el-table-column>
+    </el-table>
+    <el-drawer title="妫�楠岄」閰嶇疆" :visible.sync="open">
+      <ItemConfig @refresh="handleQuery()"></ItemConfig>
+    </el-drawer>
+  </div>
+</template>
+
+<script>
+import {transformExcel} from '@/utils/file'
+import { listConfig } from "@/api/performance/staffCompetencyInspectItemConfig";
+import {optionSelect} from '@/api/system/post'
+import { getPageList,changeLevel,exportRecords } from "@/api/performance/staffCompetencyLevelEvaluateRecord";
+import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+import {getDicts} from "@/api/system/dict/data";
+import ItemConfig from "./components/config.vue";
+export default {
+  name: "Competency",
+  components: {
+    ItemConfig,
+  },
+  data() {
+    return {
+      tableHeaderList: [],
+      // 閬僵灞�
+      loading: false,
+      // 琛ㄦ牸鏍戞暟鎹�
+      recordList: [],
+      // 寮瑰嚭灞傛爣棰�
+      title: "",
+      // 鏄惁鏄剧ず寮瑰嚭灞�
+      open: false,
+      // 鏄惁灞曞紑锛岄粯璁ゅ叏閮ㄥ睍寮�
+      isExpandAll: true,
+      // 閲嶆柊娓叉煋琛ㄦ牸鐘舵��
+      refreshTable: true,
+      // 鏌ヨ鍙傛暟
+      queryParams: {
+        keyword: undefined,
+        postName: undefined,
+      },
+      //鑳藉姏绛夌骇瀛楀吀
+      levelDictList:[],
+      tableHeight:0,
+      downloadLoading:false,
+      postList:[]
+    };
+  },
+  created() {
+    this.getLevelDict()
+    this.getTableHeader();
+    this.getList();
+    this.getTableHeight()
+    this.getPostList()
+  },
+  mounted() {
+    window.addEventListener("resize", this.getTableHeight);
+  },
+  beforeDestroy() {
+    window.removeEventListener("resize", this.getTableHeight);
+  },
+  methods: {
+    getPostList(){
+      optionSelect().then(res=>{
+        if(res.code===200){
+          this.postList = res.data
+        }
+      }).catch(error=>{
+        console.log(error)
+      })
+    },
+    downloadRecords(){
+      this.downloadLoading = true
+      exportRecords(this.queryParams).then(res=>{
+        transformExcel(res, "涓ぉ鑰愪笣璐ㄩ噺閮ㄦ楠屽憳鑳藉姏鐭╅樀鍥�.xlsx")
+        this.$message.success("瀵煎嚭鎴愬姛")
+        this.$nextTick(()=>{
+          this.downloadLoading = false
+        })
+      }).catch(error=>{
+        console.log(error)
+      })
+    },
+    getTableHeight() {
+      const innerHeight = window.innerHeight;
+      const otherHeight = 50+46+40+51;
+      this.tableHeight = innerHeight - otherHeight;
+    },
+    changeSkillLevel(row, itemId){
+      const configObj = {...row[itemId]}
+      let data = {
+        id:configObj.id,
+        level: configObj.level,
+        userId : row.userId,
+        itemConfigId : itemId
+      }
+     changeLevel(data).then(res=>{
+       if(res.code===200){
+         this.$message.success("淇敼鎴愬姛")
+       }
+     }).catch(error=>{
+       console.log(error)
+     })
+    },
+    getLevelDict() {
+      getDicts("staff_level_type").then((response) => {
+        this.levelDictList = response.data;
+      });
+    },
+    getTableHeader() {
+      listConfig({ isEnable: true }).then((response) => {
+        this.tableHeaderList = this.handleTree(response.data, "id");
+      });
+    },
+    /** 鏌ヨ鍒楄〃 */
+    getList() {
+      this.loading = true
+      this.getTableHeader();
+      getPageList(this.queryParams).then(res=>{
+        if(res.code===200){
+          this.recordList = res.data
+        }
+      }).catch(error=>{
+        console.log(error)
+      }).finally(() => {
+          this.loading = false;
+        });
+    },
+    /** 鎼滅储鎸夐挳鎿嶄綔 */
+    handleQuery() {
+      this.getList();
+    },
+    /** 閲嶇疆鎸夐挳鎿嶄綔 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    /** 鏂板鎸夐挳鎿嶄綔 */
+    handleAdd(row) {
+      this.open = true;
+    },
+  },
+};
+</script>

--
Gitblit v1.9.3