gaoluyang
2025-02-27 b1d1f0c6ebaa68380f000954162b17d7c8f0053d
人员搬迁
已修改2个文件
已重命名2个文件
已添加15个文件
5866 ■■■■■ 文件已修改
src/api/cnas/personal/personalList.js 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personalOverview.js 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personalTraining.js 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/user.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personalOverview/index.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/Edit.vue 453 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/index.vue 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue 393 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue 276 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue 621 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue 1067 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue 783 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue 358 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue 336 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personalList.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
import request from "@/utils/request";
// åˆ é™¤äººå‘˜æ˜Žç»†æ‰€åœ¨ç»„织架构
export function delUserDepardLimsId(query) {
  return request({
    url: "/user/delUserDepardLimsId",
    method: "delete",
    params: query,
  });
}
// ä¿®æ”¹äººå‘˜æ˜Žç»†æ‰€åœ¨ç»„织架构
export function upUserDepardLimsId(query) {
  return request({
    url: "/system/newUser/upUserDepardLimsId",
    method: "post",
    data: query,
  });
}
// å¯¼å‡º
export function exportPersonBasicInfo(query) {
  return request({
    url: "/personBasicInfo/exportPersonBasicInfo",
    method: "post",
    data: query,
    responseType: "blob"
  });
}
// å¯¼å‡º
export function exportPersonBasicInfoById(query) {
  return request({
    url: "/personBasicInfo/exportPersonBasicInfoById",
    method: "get",
    data: query,
    responseType: "blob"
  });
}
// èŽ·å–äººå‘˜åˆ—è¡¨
export function basicInformationOfPersonnelSelectPage(query) {
  return request({
    url: "/personBasicInfo/basicInformationOfPersonnelSelectPage",
    method: "get",
    params: query
  });
}
// åˆ é™¤éƒ¨é—¨
export function delDepartmentLims(query) {
  return request({
    url: "/department/delDepartmentLims",
    method: "delete",
    params: query
  });
}
// æ·»åŠ éƒ¨é—¨
export function addDepartmentLims(query) {
  return request({
    url: "/department/addDepartmentLims",
    method: "post",
    data: query
  });
}
// æŸ¥è¯¢CNAS人员侧边栏
export function selectCNSAPersonTree() {
  return request({
    url: "/personBasicInfo/selectCNSAPersonTree",
    method: "get"
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件列表
export function getBasicInfoFileList(query) {
  return request({
    url: "/personBasicInfo/getBasicInfoFileList",
    method: "get",
    params: query
  });
}
// åˆ é™¤é™„ä»¶
export function delBasicInfoFileList(query) {
  return request({
    url: "/personBasicInfo/delBasicInfoFileList",
    method: "delete",
    params: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†æ–°å¢ž
export function addBasicInfoWork(query) {
  return request({
    url: "/personBasicInfo/addBasicInfoWork",
    method: "post",
    data: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†ä¿®æ”¹
export function updateBasicInfoWorkList(query) {
  return request({
    url: "/personBasicInfo/updateBasicInfoWorkList",
    method: "post",
    data: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†åˆ é™¤
export function delBasicInfoWorkList(query) {
  return request({
    url: "/personBasicInfo/delBasicInfoWorkList",
    method: "delete",
    params: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†æŸ¥è¯¢
export function getBasicInfoWorkList(query) {
  return request({
    url: "/personBasicInfo/getBasicInfoWorkList",
    method: "get",
    params: query
  });
}
// èŽ·å–é™„ä»¶
export function getAnnex(query) {
  return request({
    url: "/personBasicInfo/getAnnex",
    method: "get",
    params: query
  });
}
// æ›´æ–°é™„ä»¶
export function updateAnnex(query) {
  return request({
    url: "/personBasicInfo/updateAnnex",
    method: "post",
    data: query
  });
}
// æ›´æ–°é™„ä»¶
export function getAnnexByUserId(query) {
  return request({
    url: "/personBasicInfo/getAnnexByUserId",
    method: "get",
    params: query
  });
}
// æ·»åР附件
export function addAnnex(query) {
  return request({
    url: "/personBasicInfo/addAnnex",
    method: "post",
    data: query
  });
}
// åˆ é™¤é™„ä»¶
export function deleteAnnex(query) {
  return request({
    url: "/personBasicInfo/deleteAnnex",
    method: "delete",
    params: query
  });
}
// äººå‘˜åŸºæœ¬ä¿¡æ¯æŸ¥è¯¢
export function getCNASPersonnelInfo(query) {
  return request({
    url: "/personBasicInfo/getCNASPersonnelInfo",
    method: "get",
    params: query
  });
}
// äººå‘˜åŸºæœ¬ä¿¡æ¯ä¿å­˜
export function saveCNASPersonnelInfo(query) {
  return request({
    url: "/personBasicInfo/saveCNASPersonnelInfo",
    method: "post",
    data: query
  });
}
// åˆ é™¤æ–‡ä»¶
export function deleteCNASFile(query) {
  return request({
    url: "/personBasicInfo/deleteCNASFile",
    method: "delete",
    params: query
  });
}
src/api/cnas/personal/personalOverview.js
src/api/cnas/personal/personalTraining.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,141 @@
import request from "@/utils/request";
// æŸ¥è¯¢äººå‘˜åŸ¹è®­
export function personTraining(query) {
  return request({
    url: "/personTraining/personTraining",
    method: "get",
    params: query
  });
}
// æŸ¥è¯¢åŸ¹è®­è®¡åˆ’年度计划明细表
export function queryTheAnnualPlanDetailsTable(query) {
  return request({
    url: "/personTraining/queryTheAnnualPlanDetailsTable",
    method: "get",
    params: query
  });
}
// åˆ é™¤äººå‘˜åŸ¹è®­ä¿¡æ¯
export function personTrainingDelete(query) {
  return request({
    url: "/personTraining/personTrainingDelete",
    method: "delete",
    params: query
  });
}
// å®¡æ ¸ å¹´åº¦äººå‘˜åŸ¹è®­
export function reviewAnnualPersonnelTraining(query) {
  return request({
    url: "/personTraining/reviewAnnualPersonnelTraining",
    method: "post",
    data: query
  });
}
// æ‰¹å‡† å¹´åº¦äººå‘˜åŸ¹è®­
export function approveAnnualPersonnelTraining(query) {
  return request({
    url: "/personTraining/approveAnnualPersonnelTraining",
    method: "post",
    data: query
  });
}
// å¯¼å‡ºäººå‘˜åŸ¹è®­
export function exportPersonTraining(query) {
  return request({
    url: "/personTraining/exportPersonTraining",
    method: "get",
    params: query,
    responseType: "blob"
  });
}
// å¯¼å‡ºäººå‘˜åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½•
export function exportPersonTrainingRecord(query) {
  return request({
    url: "/personTraining/exportPersonTrainingRecord",
    method: "get",
    params: query,
    responseType: "blob"
  });
}
// æ‰¹é‡åˆ é™¤ å¹´åº¦è®¡åˆ’明细表
export function deleteAnnualPlanDetailTable(query) {
  return request({
    url: "/personTraining/deleteAnnualPlanDetailTable",
    method: "delete",
    params: query
  });
}
// æ‰¹é‡åˆ é™¤ å¹´åº¦è®¡åˆ’明细表
export function addOrUpdatePersonTrainingDetailed(query) {
  return request({
    url: "/personTraining/addOrUpdatePersonTrainingDetailed",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æŸ¥è¯¢
export function trainingAndAssessmentRecordsPage(query) {
  return request({
    url: "/personTraining/trainingAndAssessmentRecordsPage",
    method: "get",
    params: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸ å¤±ç„¦æ›´æ–°
export function outOfFocusPreservation(query) {
  return request({
    url: "/personTraining/outOfFocusPreservation",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸ æ–°å¢žäººå‘˜
export function newPersonnelAddedToTrainingRecords(query) {
  return request({
    url: "/personTraining/newPersonnelAddedToTrainingRecords",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸ åˆ é™¤äººå‘˜
export function deleteTrainingAndAssessmentRecords(query) {
  return request({
    url: "/personTraining/deleteTrainingAndAssessmentRecords",
    method: "delete",
    params: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æäº¤
export function trainingAndAssessmentRecordsAdded(query) {
  return request({
    url: "/personTraining/trainingAndAssessmentRecordsAdded",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æäº¤è¯„ä»·
export function trainingAndAssessmentRecordsEvaluate(query) {
  return request({
    url: "/personTraining/trainingAndAssessmentRecordsEvaluate",
    method: "post",
    data: query
  });
}
// äººå‘˜åŸ¹è®­è¯¦æƒ…附件列表
export function getTrainingDetailedFileList(query) {
  return request({
    url: "/personTraining/getTrainingDetailedFileList",
    method: "get",
    params: query
  });
}
// äººå‘˜åŸ¹è®­è¯¦æƒ…附件删除
export function delTrainingDetailedFileList(query) {
  return request({
    url: "/personTraining/delTrainingDetailedFileList",
    method: "delete",
    params: query
  });
}
src/api/system/user.js
@@ -187,3 +187,11 @@
    method: 'get'
  })
}
// èŽ·å–ç”¨æˆ·åˆ—è¡¨
export function selectUserCondition(query) {
  return request({
    url: "/system/newUser/selectUserCondition",
    method: "get",
    params: query,
  });
}
src/views/CNAS/externalService/serviceAndSupplyPro/index.vue
@@ -47,10 +47,10 @@
  </div>
</template>
<script>
// import Contents from "@/components/do/a6.service-and-supply-purchase/contents.vue";
// import Store from "@/components/do/a6.service-and-supply-purchase/store.vue";
// import Contents from "@/tabs/do/a6.service-and-supply-purchase/contents.vue";
// import Store from "@/tabs/do/a6.service-and-supply-purchase/store.vue";
import ConsumableOverview from "../serviceAndSupplyPro/component/ConsumableOverview.vue";
// import ConsumableList from "@/components/do/a6.service-and-supply-purchase/ConsumableList.vue"
// import ConsumableList from "@/tabs/do/a6.service-and-supply-purchase/ConsumableList.vue"
export default {
  data() {
src/views/CNAS/personnel/personalOverview/index.vue
src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,175 @@
<template>
  <div>
    <el-dialog :visible.sync="addTrainingPlanDia" title="新增培训计划" width="50%" @close="closeAdd">
      <div class="body">
        <el-form ref="trainingPlanForm" :model="trainingPlan" label-position="right" label-width="90px" :rules="trainingPlanRules">
          <el-row>
            <el-col :span="12">
              <el-form-item label="培训日期:" prop="trainingDate">
                <el-date-picker v-model="trainingPlan.trainingDate" format="yyyy-MM"
                                placeholder="选择日期" size="small" value-format="yyyy-MM"
                                type="month" style="width: 100%"></el-date-picker>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="课时:" prop="classHour">
                <el-input type="number" v-model="trainingPlan.classHour" label="描述文字" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训目标:" prop="trainingObjectives">
                <el-input v-model="trainingPlan.trainingObjectives" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="参加对象:" prop="participants">
                <el-input v-model="trainingPlan.participants" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训内容:" prop="trainingContent">
                <el-input v-model="trainingPlan.trainingContent" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训讲师:" prop="trainingLecturerId">
                <el-select v-model="trainingPlan.trainingLecturerId"
                           clearable filterable
                           placeholder="请选择" size="small" style="width: 100%;">
                  <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训方式:" prop="trainingMode">
                <el-input v-model="trainingPlan.trainingMode" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="举办部门:" prop="holdingDepartment">
                <el-input v-model="trainingPlan.holdingDepartment" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="备注:" prop="remarks">
                <el-input v-model="trainingPlan.remarks" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
                <el-button @click="closeAdd">取 æ¶ˆ</el-button>
        <el-button type="primary" :loading="submitAddLoading" @click="submitAdd">ç¡® å®š</el-button>
            </span>
    </el-dialog>
  </div>
</template>
<script>
import {addOrUpdatePersonTrainingDetailed} from "@/api/cnas/personal/personalTraining";
import {selectUserCondition} from "@/api/system/user";
export default {
  props: {
    currentChangeRow: {
      type: Object,
      default: () => {
        return {}
      }
    },
  },
  name: 'Add',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      addTrainingPlanDia: false,
      submitAddLoading: false,
      trainingPlan: {
        planId: '',
        id: '',
        trainingDate: '',
        classHour: '',
        trainingObjectives: '',
        participants: '',
        trainingContent: '',
        trainingLecturerId: '',
        trainingMode: '',
        holdingDepartment: '',
        remarks: '',
      },
      trainingPlanRules: {
        trainingDate: [{ required: true, message: '请选择培训日期', trigger: 'change' }],
        trainingContent: [{ required: true, message: '请输入培训内容', trigger: 'blur' }],
        trainingLecturerId: [{ required: true, message: '请选择培训讲师', trigger: 'blur' }],
      },
      responsibleOptions: [],
      operationType: ''
    };
  },
  // æ–¹æ³•集合
  methods: {
    showDialog(id, type, row) {
      this.addTrainingPlanDia = true;
      this.operationType = type
      if (this.operationType === 'edit') {
        this.trainingPlan = this.HaveJson(row)
      } else {
        this.trainingPlan = {
          id: '',
          trainingDate: '',
          classHour: '',
          trainingObjectives: '',
          participants: '',
          trainingContent: '',
          trainingLecturerId: '',
          trainingMode: '',
          holdingDepartment: '',
          remarks: '',
        }
      }
      this.trainingPlan.planId = id
      this.getUserList()
    },
    // æäº¤æ–°å¢ž
    submitAdd() {
      this.$refs.trainingPlanForm.validate((valid) => {
        if (valid) {
          this.submitAddLoading = true
          this.trainingPlan.planId = this.currentChangeRow.id
          const personTrainingDetailed = this.trainingPlan
          addOrUpdatePersonTrainingDetailed(personTrainingDetailed).then(res => {
            this.submitAddLoading = false
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.closeAdd();
            }
          }).catch(() => {
            this.submitAddLoading = false
          })
        }
      })
    },
    // å…³é—­å¼¹æ¡†
    closeAdd() {
      this.$refs['trainingPlanForm'].resetFields();
      this.$emit('search')
      this.addTrainingPlanDia = false;
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      selectUserCondition().then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      })
    },
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/components/Edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,453 @@
<template>
  <div>
    <div class="page-header">
      <h4><span class="line"></span><span>培训与考核记录</span></h4>
      <div class="btns">
        <el-button size="small" type="primary" @click="submitForm(3)" v-if="this.currentRow.state !== 1">撤销</el-button>
        <el-button size="small" type="primary" @click="submitForm(0)" v-if="this.currentRow.state !== 1">提交</el-button>
        <el-button size="small" @click="$emit('goBack')">返回</el-button>
      </div>
    </div>
    <div class="form_title">
      <el-row>
        <el-col :span="7">
          <span class="form_label">培训内容:</span>
          <span> {{ trainingForm.trainingContent }} </span>
        </el-col>
        <el-col :span="5">
          <span class="form_label">状态:</span>
          <el-tag v-if="trainingForm.state === 1" type="success">已完成</el-tag>
          <el-tag v-if="trainingForm.state === 2" type="warning">待评价</el-tag>
          <el-tag v-if="trainingForm.state === 3" type="primary">未开始</el-tag>
        </el-col>
        <el-col :span="4">
          <span class="form_label">培训讲师:</span>
          <span> {{ trainingForm.trainingLecturerName }} </span>
        </el-col>
      </el-row>
      <el-row style="margin: 15px 0">
        <el-form>
          <el-row>
          <el-col :span="5">
            <el-form-item label="培训日期:">
              <el-date-picker v-model="trainingForm.openingTime" format="yyyy-MM-dd" :disabled="currentRow.state !== 3"
                              placeholder="选择日期" size="small" value-format="yyyy-MM-dd"
                              type="date" style="width: 60%"></el-date-picker>
            </el-form-item>
          </el-col>
            <el-col :span="7">
              <el-form-item label="培训地点">
                <el-input v-model="trainingForm.placeTraining" :disabled="currentRow.state !== 3" :rows="2" placeholder="请输入"
                          size="small" style="width: 60%" type="text"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="评价人">
                <el-select v-model="trainingForm.assessmentUserId" :disabled="currentRow.state !== 3" placeholder="请选择" size="small" style="width: 50%">
                  <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="考核方式">
                <el-input v-model="trainingForm.assessmentMethod" :disabled="currentRow.state !== 3" :rows="2" placeholder="请输入"
                          size="small" style="width: 79%" type="textarea"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="评价时间">
                <el-date-picker v-model="trainingForm.assessmentDate" :disabled="currentRow.state !== 2 || isDisabled"
                                type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" size="small"
                                placeholder="选择日期">
                </el-date-picker>
              </el-form-item>
            </el-col>
          <el-col :span="12">
            <el-form-item label="本次培训综合评价">
              <el-input v-model="trainingForm.comprehensiveAssessment" :disabled="currentRow.state !== 2 || isDisabled" :rows="2" placeholder="请输入"
                        size="small" style="width: 68%" type="textarea"></el-input>
            </el-form-item>
          </el-col>
          </el-row>
        </el-form>
      </el-row>
    </div>
    <el-divider>人员详情</el-divider>
    <div>
      <div class="items_center">
        <span>姓名</span>
        <el-input v-model="userName" class="search" placeholder="请输入"
                  size="small"></el-input>
        <el-button size="small" type="primary" @click="getInfo">查询</el-button>
      </div>
      <div class="items_btn">
        <el-button :disabled="currentRow.state === 1" size="small" type="primary" @click="addPerson">新增人员</el-button>
        <el-button :disabled="currentRow.state === 1" size="small" @click="batchDelete">批量删除</el-button>
      </div>
      <el-table :data="trainingTableData" height="calc(100vh - 30em)" stripe style="width: 100%"
                @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column label="序号" type="index" width="60"></el-table-column>
        <el-table-column label="姓名" prop="userName"></el-table-column>
        <el-table-column label="工号" prop="account"></el-table-column>
        <el-table-column label="角色" prop="roleName"></el-table-column>
        <el-table-column label="电话号码" prop="phone"></el-table-column>
        <el-table-column label="考核结果" prop="examinationResults">
          <template v-slot="scope">
            <el-input v-model="scope.row.examinationResults" :disabled="currentRow.state === 1" clearable size="small" style="width: 100%" @blur="updatePersonResult(scope.row)"></el-input>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog :visible.sync="selectUserDia" title="选择用户" width="70%">
      <div class="search" style="margin-bottom: 9px;">
        <div class="search_thing">
          <div class="search_label">用户名:</div>
          <div class="search_input">
            <el-input
              v-model="addUserTableInfo.name"
              clearable
              placeholder="请输入"
              size="small"
              @keyup.enter.native="selectUserList"
            ></el-input>
          </div>
        </div>
      </div>
      <div v-if="selectUserDia" class="body" style="height: 60vh;">
        <lims-table :tableData="tableData1" :column="column1"
                    :isSelection="true" :handleSelectionChange="selectMethod"
                    @pagination="pagination1" :height="'calc(100vh - 290px)'"
                    :page="page1" :tableLoading="tableLoading1"></lims-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="selectUserDia = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="selectUser">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import {selectUserCondition} from "@/api/business/inspectionTask";
import {mapGetters} from "vuex";
import {
  newPersonnelAddedToTrainingRecords,
  outOfFocusPreservation, trainingAndAssessmentRecordsAdded, trainingAndAssessmentRecordsEvaluate,
  trainingAndAssessmentRecordsPage
} from "@/api/cnas/personal/personalTraining";
export default {
  name: 'Edit',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {limsTable},
  props: {
    currentRow: {
      type: Object,
      default: () => {
        return {}
      }
    },
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      isSelectedList: [], // ç¦ç”¨çš„多选
      userName: undefined,
      trainingForm: {
        code: '111111',
        date: '2024-10-10',
      },
      trainingColumn: [
        {
          label: '姓名',
          prop: 'userName'
        },
        {
          label: '工号',
          prop: 'account'
        },
        {
          label: '角色',
          prop: 'roleName'
        },
        {
          label: '电话号码',
          prop: 'phone'
        },
        {
          label: '考核结果',
          prop: 'result'
        }
      ],
      trainingTableData: [],
      trainingLoading: false,
      isDisabled: false,
      selectUserDia: false, // æ·»åŠ äººå‘˜å¼¹æ¡†
      tableData1: [],
      tableLoading1: false,
      column1: [
        {label: '姓名', prop: 'name'},
        {label: '账号', prop: 'account'},
        {label: '角色', prop: 'roleName'},
        {
          dataType: 'tag',
          label: '状态',
          prop: 'status',
          formatData: (params) => {
            if (params == 0) {
              return '启用'
            } else {
              return ''
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'success'
            } else {
              return 'danger'
            }
          }
        },
        {label: '电话号码', prop: 'phone'},
      ],
      page1: {
        total:0,
        size:10,
        current:1
      },
      addUserTableInfo: {
        name: null,
        departLimsId: '1',
      },
      multipleSelection: [],
      userList: [],
    };
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  mounted() {
    this.trainingForm = this.currentRow
    this.getInfo()
    this.getUserList()
    this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
  },
  // æ–¹æ³•集合
  methods: {
    // èŽ·å–å½“å‰æ•°æ®
    async getInfo() {
      this.trainingLoading = true
      await trainingAndAssessmentRecordsPage({
        trainingDetailedId: this.currentRow.id,
        userName: this.userName
      }).then(res => {
        if (res.code === 200) {
          this.trainingTableData = res.data
        }
        this.trainingLoading = false
      })
    },
    updatePersonResult(row) {
      outOfFocusPreservation(row).then(res => {
        this.$message.success("操作成功!")
      })
    },
    addPerson() {
      this.isSelectedList = this.trainingTableData.map(item => item.userId)
      this.selectUserDia = true;
    },
    selectUserList () {
      this.tableLoading1 = true
      selectUserCondition({...this.addUserTableInfo}).then(res => {
        this.tableData1 = res.data.records
        this.page1.total = res.data.total
      }).catch(err => {
        this.tableLoading1 = false
      })
    },
    pagination1 (page) {
      this.page1.size = page.limit
      this.selectUserList()
    },
    // è¡¨æ ¼é€‰æ‹©æ–¹æ³•
    selectMethod(val) {
      this.multipleSelection = val
    },
    selectUser() {
      let selects = this.multipleSelection;
      if (selects.length == 0) {
        this.$message.error('未选择数据');
        return;
      }
      let list = []
      selects.forEach(a => {
        const obj = {
          courseId: this.currentRow.id,
          examinationResults: "",
          userId: a.id
        }
        list.push(obj)
      });
      newPersonnelAddedToTrainingRecords(list).then(res => {
        this.isSelectedList = []
        this.selectUserDia = false;
        this.getInfo()
      })
    },
    // æ‰¹é‡åˆ é™¤
    handleSelectionChange(list) {
      this.multipleSelection = list
    },
    batchDelete() {
      if (this.multipleSelection.length > 0) {
        let ids = this.multipleSelection.map(item => item.trainingRecordId)
        this.$confirm('是否确认删除所选择的数据?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          let formData = new FormData()
          formData.append('ids', ids)
          deleteTrainingAndAssessmentRecords(formData).then(res => {
            if (res.code == 200) {
              this.$message.success('删除成功');
              this.getInfo()
            }
          });
        }).catch(() => {
          this.$message.warning('取消删除');
        });
      } else {
        this.$message.warning('请选择需要删除的数据')
      }
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.getInfo();
    },
    handleCurrentChange(val) {
      this.search.current = val;
      this.getInfo();
    },
    /**
     * @desc æäº¤è¡¨å•
     */
    async submitForm(status) {
      let state = this.currentRow.state
      if (this.trainingForm.assessmentUserId) {
        state = 2
      }
      if (this.trainingForm.comprehensiveAssessment) {
        state = 1
      }
      if (status === 3) {
        state = 3
      }
      let data = {
        assessmentMethod: this.trainingForm.assessmentMethod,
        openingTime: this.trainingForm.openingTime,
        placeTraining: this.trainingForm.placeTraining,
        comprehensiveAssessment: this.trainingForm.comprehensiveAssessment,
        trainingDetailedId: this.trainingForm.id,
        assessmentUserId: this.trainingForm.assessmentUserId,
        assessmentDate: this.trainingForm.assessmentDate,
        state: state
      }
      let code = {}
      if (state === 2) {
        code = await trainingAndAssessmentRecordsAdded(data)
      } else {
        code = await trainingAndAssessmentRecordsEvaluate(data)
      }
      this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
      if(code.code === 200) {
        this.currentRow.state = state
        this.$message.success("操作成功")
      }
    },
    getUserList(){
      selectUserCondition({ type: 0 }).then((res) => {
        this.userList = res.data;
      })
    },
  }
};
</script>
<style scoped>
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  margin-bottom: 10px;
}
h4 {
  display: flex;
  align-items: center;
}
h4 .line {
  display: inline-block;
  width: 3px;
  height: 16px;
  background: #3A7BFA;
  margin-right: 4px;
}
.form_title {
  font-size: 14px;
  padding: 0 20px;
  margin-bottom: 10px;
}
.el-divider {
  margin: 0 1em 1em 0;
}
.form__input_label {
  width: 90px;
  margin-right: 6px;
  color: #606266;
}
.form__input_label2 {
  width: 210px;
  margin-right: 6px;
  color: #606266;
}
.search_thing {
  display: flex;
  align-items: center
}
.search_label {
  width: 120px;
}
.pagination {
  display: flex;
  justify-content: space-between
}
.items_center {
  float: left;
  width: 50%;
  text-align: left;
}
.items_btn {
  text-align: right;
  width: 50%;
  float: right;
  margin-bottom: 1em;
}
.search {
  width: 180px;
  padding: 0 16px;
}
</style>
src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="附件上传" width="80%" @closed="closeFilesLook">
      <div style="display: flex;justify-content: space-between;">
        <el-upload ref='upload'
                   :action="fileAction"
                   :auto-upload="true"
                   :before-upload="fileBeforeUpload" :data="{trainingDetailedId: info.id}"
                   :headers="uploadHeader" :on-error="onError"
                   :on-success="handleSuccessUp"
                   :show-file-list="false"
                   accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
          <el-button size="small" style="height: 38px" type="primary">附件上传</el-button>
        </el-upload>
      </div>
      <div>
        <lims-table :tableData="tableData" :column="columnData"
                    :height="'calc(100vh - 47em)'"
                    :highlightCurrentRow="true"
                    :tableLoading="tableLoading"></lims-table>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="lookDialogVisible"
      fullscreen
      title="查看附件" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}"
                   :fileUrl="javaApi+'/word/'+currentInfo.fileUrl" style="height: 90vh;overflow-y: auto;top: 0"/>
    </el-dialog>
  </div>
</template>
<script>
import file from '@/utils/file';
import filePreview from '@/components/Preview/filePreview.vue';
import limsTable from "@/components/Table/lims-table.vue";
import {delTrainingDetailedFileList, getTrainingDetailedFileList} from "@/api/cnas/personal/personalTraining";
export default {
  name: 'ViewRecord',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {limsTable, filePreview },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '预览',
              type: 'text',
              clickFun: (row) => {
                this.handleLook(row)
              }
            },
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delete(row)
              }
            }
          ]
        }
      ],
      tableData: [],
      info: {},
      currentInfo:{},
      lookDialogVisible: false,
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      this.searchTableList()
    },
    // æŸ¥è¯¢é™„件列表
    searchTableList () {
      this.tableLoading = true
      getTrainingDetailedFileList({trainingDetailedId: this.info.id}).then(res => {
        this.tableLoading = false
        this.tableData = res.data
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    closeFilesLook () {
      this.filesDialogVisible = false
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
    // åˆ é™¤
    delete (row) {
      this.tableLoading = true
      delTrainingDetailedFileList({detailedFileId: row.detailedFileId}).then(res => {
        this.tableLoading = false
        this.$message.success('删除成功')
        this.searchTableList()
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    // ä¸Šä¼ éªŒè¯
    fileBeforeUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    onError(err, file, fileList,type) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response, ) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchTableList()
      }
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row){
      this.currentInfo = row
      this.lookDialogVisible = true
    },
  },
  computed: {
    fileAction() {
      return this.javaApi + '/personTraining/delTrainingDetailedFileList'
    }
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,321 @@
<template>
  <div class="main">
    <div class="main_left">
      <el-row>
        <el-col :span="20">
          <el-input
            v-model="search"
            class="div_left_input"
            clearable
            placeholder="输入关键字进行搜索"
            size="small"
            suffix-icon="el-icon-search"
            @blur="searchFilter"
            @clear="searchFilter"
            @keyup.enter.native="searchFilter"
          ></el-input>
        </el-col>
        <el-col :span="4" style="text-align: center;line-height: 30px; margin-top: 14px">
          <el-button circle icon="el-icon-plus" size="mini" type="primary" @click="handleAdd"></el-button>
        </el-col>
      </el-row>
      <el-tree
        ref="tree"
        :data="list"
        :default-expanded-keys="[1]"
        :expand-on-click-node="false"
        :filter-node-method="filterNode"
        :props="{ children: 'children', label: 'name' }"
        highlight-current
        node-key="id"
        style="height:calc(100% - 70px);overflow-y: scroll;scrollbar-width: none;"
        @node-click="handleNodeClick"
        @node-expand="nodeOpen"
        @node-collapse="nodeClose"
      >
        <div slot-scope="{ node, data }" class="custom-tree-node">
          <el-row style="width: 100%;">
            <el-col :span="22" style="text-align: left;">
              <span><i
                :class="`node_i ${data.children != undefined&&data.children.length>0 ? 'el-icon-folder-opened' : 'el-icon-tickets'}`"></i>
                {{ data.name }}</span>
            </el-col>
            <el-col v-if="node.level>1 && data.id !== null" :span="2" style="text-align: right;">
              <el-button size="mini" type="text" @click.stop="remove(node, data)">
                <i class="el-icon-delete"></i>
              </el-button>
            </el-col>
          </el-row>
        </div>
      </el-tree>
    </div>
    <div class="main_right">
      <el-tabs v-model="activeName" :lazy="true" type="border-card">
        <el-tab-pane label="人员基本信息" name="人员基本信息">
          <PersonnelList v-if="activeName === '人员基本信息' && isShowAll" ref="personnelList" :currentCompaniesList="currentCompaniesList"
                         :departId="departId" @refreshTree="refreshTree"
                         @updatePerson="updatePerson"></PersonnelList>
          <personnelInformation v-if="activeName === '人员基本信息' && !isShowAll" :clickNodeVal="clickNodeVal"></personnelInformation>
        </el-tab-pane>
<!--        <el-tab-pane label="培训计划" name="培训计划">-->
<!--          <PersonnelTraining v-if="activeName === '培训计划'" ref="personnelTraining"-->
<!--                             :departId="departId" :isDepartment="isDepartment"></PersonnelTraining>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="岗位职责" name="岗位职责">-->
<!--          <job-responsibilities v-if="activeName === '岗位职责'" ref="jobResponsibilities"-->
<!--                                :departId="departId"-->
<!--                                :isDepartment="isDepartment"></job-responsibilities>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="奖惩记录" name="奖惩记录">-->
<!--          <rewardPunishmentRecord v-if="activeName === '奖惩记录'"-->
<!--                                  :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="培训记录" name="培训记录">-->
<!--          <training-record v-if="activeName === '培训记录'" ref="trainingRecord"-->
<!--                           :departId="departId"-->
<!--                           :isDepartment="isDepartment"></training-record>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="任职授权记录" name="任职授权记录">-->
<!--          <Mandate v-if="activeName === '任职授权记录'" ref="manDateRef" :departId="departId" :isDepartment="isDepartment"></Mandate>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="人员能力" name="人员能力">-->
<!--          <personnel-capacity v-if="activeName === '人员能力'" ref="personnelCapacity"-->
<!--                              :departId="departId"-->
<!--                              :isDepartment="isDepartment"></personnel-capacity>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="沟通记录" name="沟通记录">-->
<!--          <Communicate v-if="activeName === '沟通记录'" ref="communicateRef" :departId="departId" :isDepartment="isDepartment"></Communicate>-->
<!--        </el-tab-pane>-->
      </el-tabs>
    </div>
    <el-dialog :visible.sync="addDia" title="架构新增" width="400px">
      <div class="body">
        <el-row style="line-height: 50px;">
          <el-col :span="6" style="text-align: right;">
            <span class="required-span">* </span>架构名称:
          </el-col>
          <el-col :offset="1" :span="16">
            <el-input v-model="addOb.name" clearable placeholder="请输入架构名称" size="small" @keyup.enter.native="addStandardTree"></el-input>
          </el-col>
        </el-row>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDia = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="addStandardTree">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import PersonnelList from './tabs/personnel-list.vue'
import personnelInformation from './tabs/personnel-information.vue'
import PersonnelTraining from './tabs/personnelTraining';
import JobResponsibilities from './tabs/job-responsibilities.vue';
import rewardPunishmentRecord from "./tabs/reward-punishment-record.vue";
import TrainingRecord from './tabs/training-record.vue';
import Mandate from './tabs/mandate.vue';
import PersonnelCapacity from './tabs/personnel-capacity.vue';
import Communicate from './tabs/communicate.vue'
import {addDepartmentLims, delDepartmentLims, selectCNSAPersonTree} from "@/api/cnas/personal/personalList";
export default {
  components: {
    PersonnelList, personnelInformation, PersonnelTraining, JobResponsibilities, rewardPunishmentRecord, TrainingRecord, Mandate, PersonnelCapacity, Communicate
  },
  data() {
    return {
      isShowAll: true, //  æ˜¯å¦å±•示标签栏
      activeName: '人员基本信息',
      departId: 1,
      list: [],
      addDia: false,
      addOb: {
        name: '',
        fatherId: ''
      },
      search: '',
      clickNodeVal: {},
      addUserForm: {
        name: ''
      },
      currentCompaniesList: [],
      entity: {
        name: '',
        departLimsId: '',
        orderBy: {
          field: 'id',
          order: 'asc'
        }
      },
      overallRecord: '人员列表',
      isDepartment: false,
    };
  },
  mounted() {
    this.geList();
  },
  methods: {
    remove(node, data) {
      this.$confirm("是否删除该层级", "提示", {
        type: "error"
      }).then(() => {
        delDepartmentLims({
          id: data.id
        }).then(res => {
          this.$message.success('已删除')
          this.geList();
        })
      }).catch(e => {})
    },
    addStandardTree() {
      if (this.addOb.name == null || this.addOb.factory == '') {
        this.$message.error('构架名称是必填项')
        return
      }
      addDepartmentLims(this.addOb).then(res => {
        this.$message.success('添加成功')
        this.addDia = false
        this.geList();
        this.addOb.name = ''
        this.addOb.fatherId = ''
      })
    },
    handleAdd() {
      if (this.addOb.fatherId) {
        this.addDia = true;
      } else {
        this.$message.error('请选择一个架构层级')
      }
    },
    // äººå‘˜åˆ—表编辑
    updatePerson(row) {
      const node = this.findNodeById(this.list, row.name);
      if (node) {
        this.handleNodeClick(node);
      } else {
        this.$message.warning('未找到该人员');
      }
    },
    // æ–°å»ºäººå‘˜åŽåˆ·æ–°æ ‘
    refreshTree () {
      this.geList()
    },
    findNodeById(treeData, name) {
      for (let i = 0; i < treeData.length; i++) {
        if (treeData[i].name === name) {
          return treeData[i]; // æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
        }
        if (treeData[i].children && treeData[i].children.length > 0) {
          const foundNode = this.findNodeById(treeData[i].children, name);
          if (foundNode) {
            return foundNode; // åœ¨å­èŠ‚ç‚¹ä¸­æ‰¾åˆ°ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
          }
        }
      }
      return null; // æ²¡æœ‰æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žnull
    },
    searchFilter() {
      this.$refs.tree.filter(this.search);
    },
    // èŽ·å–æ ‘
    geList() {
      selectCNSAPersonTree().then(res => {
        this.list = res.data;
        if(this.list.length > 0) {
          this.isDepartment = true;
        }
      });
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },
    nodeClose(data, node, el) {
      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder');
    },
    nodeOpen(data, node, el) {
      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder-opened');
    },
    handleNodeClick(val, node, el) {
      //树的值
      this.clickNodeVal = val;
      // å­˜å‚¨çˆ¶çº§èŠ‚ç‚¹çº§æ•°
      if (node) {
        this.getNodeParent(node);
        this.clickNodeVal.level = node.level;
        this.clickNodeVal.parent = node.parent.data;
      }
      this.entity.departLimsId = val.id;
      this.addOb.fatherId = val.id;
      // æ˜¯å¦æ˜¾ç¤ºè®¾å¤‡è¯¦æƒ…
      this.isShowAll = val.id !== null;
      if (val.id) {    // å¦‚果是实验室
        this.departId = val.id;
        this.isDepartment = true;
      }
      if (val.userId) { // æ˜¯äººå‘˜
        this.departId = val.userId;
        this.isDepartment = false
      }
    },
    getNodeParent(val) {
      if (val.parent != null) {
        this.currentCompaniesList[val.level - 1] = val.data.id;
        this.selectTree += ' - ' + val.label;
        this.getNodeParent(val.parent);
      }
    }
  }
};
</script>
<style scoped>
.custom-tree-node {
  width: 80%;
  line-height: 32px;
}
.custom-tree-node .el-icon-delete {
  color: #3A7BFA;
  opacity: 0;
  font-size: 15px;
}
.custom-tree-node:hover .el-icon-delete {
  opacity: 1;
}
.main {
  display: flex;
  padding: 15px 0;
}
.main_left {
  background: #ffffff;
  text-align: center;
  height: calc(100vh - 8em);
  width: 270px;
  border-radius: 15px;
}
.main_right {
  width: calc(100% - 288px);
  border-radius: 15px;
}
.div_left_input {
  margin: 15px 0;
  width: 90%;
}
>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item {
  border: 0 none;
}
>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
  color: black;
}
>>> .el-tabs--border-card > .el-tabs__header {
  border-bottom: none;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,249 @@
<template>
    <div class="flex_column">
<!--        <TableCard :showForm="isDepartment" title="沟通记录">-->
<!--            <template v-slot:form >-->
<!--                <div v-if="isDepartment" class="w100 items_center justify_between">-->
<!--                    <div></div>-->
<!--                    <div>-->
<!--                        &lt;!&ndash; <el-button type="primary" size="small">导出</el-button> &ndash;&gt;-->
<!--                        <el-button size="small" type="primary" @click="openDialog">新增</el-button>-->
<!--                    </div>-->
<!--                </div>-->
<!--            </template>-->
<!--            <template v-slot:table>-->
<!--                <ZTTable-->
<!--                    :column="columnData"-->
<!--                    :height="'calc(100vh - 21em)'"-->
<!--                    :table-data="tableData"-->
<!--                    :table-loading="loading"-->
<!--                    style="margin-top: 18px; padding: 0 15px;"-->
<!--                ></ZTTable>-->
<!--                <el-divider></el-divider>-->
<!--                <div class="pagination">-->
<!--                    <div></div>-->
<!--                    <el-pagination-->
<!--                        :page-size="pagination.pageSize"-->
<!--                        :page-sizes="[10, 20, 30, 40]"-->
<!--                        :total="pagination.total"-->
<!--                        layout="total, sizes, prev, pager, next, jumper"-->
<!--                        @current-change=""-->
<!--                        @size-change=""-->
<!--                    >-->
<!--                    </el-pagination>-->
<!--                </div>-->
<!--            </template>-->
<!--        </TableCard>-->
        <Add ref="communicateModal" @submit="getTableData"></Add>
    </div>
</template>
<script>
// import Add from "./Add.vue"
export default {
    components: {
        // Add
    },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
    data() {
        return {
            // departId: 0,
            columnData: [
                {
                    label: '序号',
                    prop: 'id'
                }, {
                    label: '沟通人',
                    prop: 'userName'
                }, {
                    label: '沟通时间',
                    prop: 'communicationTime'
                }, {
                    label: '沟通地点',
                    prop: 'communicationPlace'
                }, {
                    label: '沟通内容',
                    prop: 'communicationContent'
                }, {
                    label: '操作',
                    dataType: 'action',
                    operation: [
                        {
                            name: '编辑',
                            type: 'text',
                            clickFun: (row) => {
                                this.openDialog(row, true)
                            }
                        }, {
                            name: '导出',
                            type: 'text',
                            clickFun: (row) => {
                                this.handleDown(row)
                            }
                        }, {
                            name: '删除',
                            type: 'text',
                            color: '#f56c6c',
                            clickFun: (row) => {
                                this.delPerson(row.id)
                            }
                        }
                    ]
                },
            ],
            tableData: [],
            pagination: {
                current: 1,
                pageSize: 20,
                total: 0
            },
            loading: false
        }
    },
  mounted() {
    // this.getTableData()
  },
  methods: {
        openDialog(row, type=false) {
            this.$refs.communicateModal.openDialog(row, type)
        },
        async getTableData() {
            this.loading = true
          const params = this.isDepartment ? {
            departLimsId: this.departId,
            current: this.pagination.current,
            size: this.pagination.pageSize
          } : {
            userId: this.departId,
            current: this.pagination.current,
            size: this.pagination.pageSize
          }
            const { code, data } = await this.$axios({
                method: 'get',
                url: personPersonCommunicationAbilityPage,
                params: params
            })
            if(code == 200) {
                this.pagination.total = data.total
                this.tableData = data.records
                this.loading = false
            }
        },
        /**
         * @desc èŽ·å–è®¾å¤‡id
         */
        getDepart(id) {
            // this.departId = id
            this.getTableData()
        },
        /**
         * @desc åˆ é™¤æ²Ÿé€šè®°å½•
         */
        delPerson(id) {
            this.$confirm('此操作将永久删除该文件, æ˜¯å¦ç»§ç»­?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(async () => {
                let formData = new FormData()
                formData.append('id', id)
                const { code } = await this.$axios({
                    method: 'delete',
                    url: deletePersonCommunicationAbility,
                    data: formData
                })
                if(code == 200) {
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                    this.getTableData()
                }
            })
        },
        async handleDown(row){
          this.$axios.post(this.$api.personCommunicationAbility.exportPersonCommunicationAbility,{id:row.id},{responseType: "blob"}).then(res => {
            if(res.code == 201){
              this.$message.error(res.message)
              return
            }
            const blob = new Blob([res],{ type: 'application/octet-stream' });
            //将Blob å¯¹è±¡è½¬æ¢æˆå­—符串
            let reader = new FileReader();
            reader.readAsText(blob, 'utf-8');
            reader.onload = () => {
              try {
                let result = JSON.parse(reader.result);
                if (result.message) {
                  this.$message.error(result.message);
                } else {
                  const url = URL.createObjectURL(blob);
                  const link = document.createElement('a');
                  link.href = url;
                  link.download = row.userName+'-沟通记录'+'.docx';
                  link.click();
                  this.$message.success('导出成功')
                }
              } catch (err) {
                console.log(err);
                const url = URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;
                link.download = row.userName+'-沟通记录'+'.docx';
                link.click();
                this.$message.success('导出成功')
              }
            }
          })
        }
    },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (newId) {
          this.getTableData();
        }
      }
    }
  }
}
</script>
<style scoped>
.flex_column {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
.w100 {
    width: 100%;
}
.pagination {
    display: flex;
    justify-content: space-between
}
.items_center {
    display: flex;
    align-items: center;
}
.justify_between {
    justify-content: space-between
}
.date_box {
    margin: 0 5px;
}
.search {
    width: 150px;
    padding: 0 16px;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,393 @@
<!-- å²—位职责 -->
<template>
  <div class="view">
    <div style="text-align: left; margin-bottom: 15px;padding: 0 10px">
      <label>员工:</label>
      <el-input v-model="userName" clearable placeholder="请输入员工" size="small" style="width: 20vh;"></el-input>
      <el-button size="small" type="primary" @click="refreshTable">查询</el-button>
      <div v-if="isDepartment" style="float: right;">
        <el-button size="small" type="primary" @click="addPost">新增</el-button>
        <!--        <el-button size="small" type="primary">导出excel</el-button>-->
      </div>
    </div>
    <div class="table" style="padding: 0 10px">
      <el-table :data="tableData" height="70vh" style="width: 100%">
        <el-table-column label="序号" type="index" width="60"></el-table-column>
        <el-table-column label="员工编号" min-width="120" prop="account"></el-table-column>
        <el-table-column label="岗位名称" min-width="180" prop="postName"></el-table-column>
        <el-table-column label="所属部门" min-width="180" prop="departLimsName"></el-table-column>
        <el-table-column label="工作目标" min-width="180" prop="jobObjective"></el-table-column>
        <el-table-column label="岗位职责" min-width="180" prop="jobResponsibilities"></el-table-column>
        <el-table-column label="任职人" min-width="180" prop="incumbentName"></el-table-column>
        <el-table-column label="任职人审核日期" min-width="180" prop="incumbentDate"></el-table-column>
        <el-table-column label="主管" min-width="180" prop="supervisorName"></el-table-column>
        <el-table-column label="主管审核日期" min-width="180" prop="supervisorDate"></el-table-column>
        <el-table-column fixed="right" label="操作" width="140">
          <template v-slot="scope">
            <el-button v-if="!isDepartment || scope.row.currentState === '关闭'" size="small" type="text"
                       @click="handleViewClick(scope.row, 'view')">查看
            </el-button>
            <el-button v-if="isDepartment && scope.row.currentState !== '关闭'" size="small" type="text"
                       @click="handleViewClick(scope.row, 'edit')">编辑
            </el-button>
            <el-button size="small" type="text" @click="downLoadPost(scope.row)">导出</el-button>
            <el-button v-if="isDepartment" size="small" type="text" @click="deletePost(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]"
                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <!-- æ–°å¢žå²—位职责 -->
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="dialogVisible"
               title="新增岗位职责"
               width="50%" @close="resetForm">
      <el-steps :active="currentStep" align-center finish-status="success">
        <el-step v-for="(v, i) in steps" :key="i" :title="v" style="cursor:pointer"
                 @click.native="choiceStep(i)"></el-step>
      </el-steps>
      <el-form ref="form" :model="form" :rules="rules" label-width="130px">
        <div>
          <el-card style="margin-top: 1em; height: 40vh; overflow-y: scroll;">
            <!-- æ–°å¢žè®¾å¤‡äº‹è®°å½•卡片 -->
            <el-row>
              <el-col :span="12">
                <el-form-item label="岗位名称:" prop="postName">
                  <el-input v-model="form.postName" :disabled="currentStep !== 0 || operationType === 'view'"
                            size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="工作目标:" prop="jobObjective">
                  <el-input v-model="form.jobObjective" :disabled="currentStep !== 0 || operationType === 'view'"
                            size="small"
                            type="textarea"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="岗位职责:" prop="jobResponsibilities">
                  <el-input v-model="form.jobResponsibilities" :disabled="currentStep !== 0 || operationType === 'view'"
                            size="small"
                            type="textarea"></el-input>
                </el-form-item>
              </el-col>
              <el-col v-if="currentStep === 0 || operationType === 'view'" :span="12">
                <el-form-item
                  :rules="[{ required: currentStep === 0, message: '请选择任职人', trigger: 'change' }]"
                  label="任职人:"
                  prop="incumbentId">
                  <el-select v-model="form.incumbentId" :disabled="operationType === 'view'" clearable
                             filterable
                             placeholder="请选择任职人" size="small" style="width: 100%;">
                    <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col v-if="currentStep === 1 || operationType === 'view'" :span="12">
                <el-form-item
                  :rules="[{ required: currentStep === 1, message: '请选择主管', trigger: 'blur' }]"
                  label="主管:"
                  prop="supervisorId">
                  <el-select v-model="form.supervisorId" :disabled="currentStep !== 1 || operationType === 'view'"
                             clearable filterable
                             placeholder="请选择主管" size="small" style="width: 100%;">
                    <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
          </el-card>
          <el-row style="margin-top: 1em;">
            <el-col :span="4">
              æ“ä½œäººï¼š{{ form.submitPerson }}
            </el-col>
            <el-col :span="6">
              æ—¥æœŸï¼š{{ form.submitDate }}
            </el-col>
          </el-row>
        </div>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="currentStep !== 0 && currentStep !== 3" @click="submitForm('3reject')">驳回</el-button>
        <el-button v-if="currentStep === 0" @click="submitForm('2save')">保存</el-button>
        <el-button v-if="currentStep !== 3" type="primary"
                   @click="submitForm('1submit')">{{ currentStep === 0 ? '提交' : '通过' }}</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
// import { dateFormat } from '../../../util/date';
export default {
  data() {
    return {
      userName: '',
      tableData: [],
      responsibleOptions: [],
      search: {
        size: 20,
        current: 1,
        total: 0
      },
      dialogVisible: false,
      currentStep: 0, // æ­¥éª¤æ¡æ˜¾ç¤ºç¬¬å‡ æ­¥
      currentStepClick: 0, // ç‚¹å‡»æ­¥éª¤æ¡å˜åŒ–
      operationType: '',
      steps: ['提交', '任职人确认', '主管确认'],
      form: {
        postName: '', // å²—位名称
        jobObjective: '', // å·¥ä½œç›®æ ‡
        jobResponsibilities: '', // å²—位职责
        incumbentId: '', // ä»»èŒäºº
        supervisorId: '' // ä¸»ç®¡
      },
      rules: {
        postName: [{ required: true, message: '请输入岗位名称', trigger: 'blur' }],
        jobObjective: [{ required: true, message: '请输入工作目标', trigger: 'blur' }],
        jobResponsibilities: [{ required: true, message: '请输入岗位职责', trigger: 'blur' }],
        incumbentId: [{ required: true, message: '请选择任职人', trigger: 'change' }],
        supervisorId: [{ required: true, message: '请选择主管', trigger: 'change' }]
      }
      // departId: 0
    };
  },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  mounted() {
    this.getPostList(this.departId);
  },
  methods: {
    addPost() {
      this.dialogVisible = true;
      this.form = {
        postName: '', // å²—位名称
        jobObjective: '', // å·¥ä½œç›®æ ‡
        jobResponsibilities: '', // å²—位职责
        incumbentId: '', // ä»»èŒäºº
        supervisorId: '', // æ“ä½œäºº
        submitPerson: '', // ä¸»ç®¡
        submitDate: '', // æ—¥æœŸ
        currentStep: 0 // æ—¥æœŸ
      };
      this.currentStep = 0;
      this.getUserList();
    },
    // æŸ¥è¯¢åˆ—表信息
    getPostList(userId) {
      this.search.userId = userId;
      const name = this.isDepartment ? 'departmentId' : 'userId';
      this.$axios.get(this.$api.personnel.personJobResponsibilitiesSelect + '?userName=' + this.userName + `&${name}=` + this.search.userId + '&size=' + this.search.size + '&current=' + this.search.current).then(res => {
        if (res.code === 201) return;
        this.tableData = res.data.records;
        this.search.total = res.data.total;
      });
    },
    //提交表单
    async submitForm(saveState) {
      this.$refs.form.validate((valid) => {
        if (valid === true || saveState !== '1submit') {
          // ç»™å½“前环节设置创建人与时间
          let user = JSON.parse(localStorage.getItem('user'));
          const dateTime = dateFormat(new Date());
          // èŽ·å–å½“å‰çŽ¯èŠ‚æ“ä½œäººä¸Žæ—¥æœŸ
          switch (this.currentStep) {
            case 0:
              this.form.submittingOperator = user.name;
              this.form.submittingDate = dateTime;
              break;
            case 1:
              this.form.incumbentOperator = user.name;
              this.form.incumbentDate = dateTime;
              break;
            case 2:
              this.form.supervisorOperator = user.name;
              this.form.supervisorDate = dateTime;
              break;
            default:
              break;
          }
          // èŽ·å–å½“å‰çŽ¯èŠ‚è´Ÿè´£äºº
          switch (saveState === '3reject' ? this.currentStep - 1 : this.currentStep) {
            case 1:
              this.form.currentResponsible = this.form.submittingOperator;
              break;
            case 2:
              this.form.currentResponsible = this.form.incumbentOperator;
              break;
            default:
              break;
          }
          let currentStepAction;
          // è®¾ç½®è¯¥æ“ä½œåˆ¤æ–­æ˜¯å¦ä¸ºæäº¤ï¼Œä¿å­˜ï¼Œé©³å›žï¼Œé€šè¿‡
          switch (saveState) {
            // æäº¤ï¼Œé€šè¿‡
            case '1submit':
              currentStepAction = this.currentStep + 1;
              break;
            // ä¿å­˜
            case '2save':
              currentStepAction = this.currentStep;
              break;
            // é©³å›ž
            case '3reject':
              currentStepAction = this.currentStep - 1;
              break;
            default:
              break;
          }
          // èŽ·å–å½“å‰çŠ¶æ€
          this.form.currentState = currentStepAction === 3 ? '关闭' : this.steps[currentStepAction];
          this.$axios.post(this.$api.personnel.personJobResponsibilitiesSave, this.form, {
            headers: {
              'Content-Type': 'application/json'
            },
            noQs: true
          }).then(res => {
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.getPostList(this.departId);
              this.dialogVisible = false;
            }
          });
        } else {
          let step = this.steps[this.currentStep];
          this.$message.warning(step + '  æµç¨‹ä¸­æœ‰å¿…填项未填!');
        }
      });
    },
    // ç¼–辑
    handleViewClick(row, type) {
      this.operationType = type;
      this.getUserList();
      row.incumbentId = Number(row.incumbentId);
      this.form = { ...row };
      switch (row.currentState) {
        case '提交':
          this.currentStep = 0;
          break;
        case '任职人确认':
          this.currentStep = 1;
          this.form.submitPerson = row.submittingOperator;
          this.form.submitDate = row.submittingDate;
          break;
        case '主管确认':
          this.currentStep = 2;
          this.form.submitPerson = row.incumbentOperator;
          this.form.submitDate = row.incumbentDate;
          break;
        case '关闭':
          this.currentStep = 3;
          this.form.submitPerson = row.supervisorOperator;
          this.form.submitDate = row.supervisorDate;
          break;
        default:
          break;
      }
      this.form.currentState = this.currentStep;
      this.currentStepClick = this.currentStep === 3 ? 0 : this.currentStep
      console.log('this.form---', this.form);
      this.dialogVisible = true;
    },
    // ä¸‹è½½å²—位职责
    downLoadPost(row) {
      this.$axios.post(this.$api.personPostAuthorizationRecord.exportPersonJobResponsibilities,{id:row.id},{responseType: "blob"}).then(res => {
        const blob = new Blob([res],{ type: 'application/octet-stream' });
        //将Blob å¯¹è±¡è½¬æ¢æˆå­—符串
        let reader = new FileReader();
        reader.readAsText(blob, 'utf-8');
        reader.onload = () => {
          try {
            let result = JSON.parse(reader.result);
            if (result.message) {
              this.$message.error(result.message);
            } else {
              const url = URL.createObjectURL(blob);
              const link = document.createElement('a');
              link.href = url;
              link.download = row.incumbentName+'-岗位职责'+'.docx';
              link.click();
              this.$message.success('导出成功')
            }
          } catch (err) {
            console.log(err);
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = row.incumbentName+'-岗位职责'+'.docx';
            link.click();
            this.$message.success('导出成功')
          }
        }
      })
    },
    // åˆ é™¤å²—位职责
    deletePost(row) {
      this.$confirm('此操作将永久删除此数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$axios.delete(this.$api.personnel.personJobResponsibilitiesDelete + '?id=' + row.id).then(res => {
          if (res.code == 200) {
            this.$message.success('删除成功');
            this.getPostList(this.departId);
          }
        });
      }).catch(() => {
        this.$message.error('删除失败');
      });
    },
    resetForm() {
      this.$refs.form.resetFields();
    },
    refreshTable() {
      this.getPostList(this.departId);
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      this.$axios.get(this.$api.deviceScope.selectUserList).then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data;
        }
      });
    },
    choiceStep(index) {
      this.currentStepClick = index;
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.getPostList(this.departId);
    },
    handleCurrentChange(val) {
      this.search.current = val;
      this.getPostList(this.departId);
    }
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        this.getPostList(newId);
      }
    }
  }
};
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,276 @@
<template>
    <div class="flex_column">
<!--        <TableCard :showForm="isDepartment" title="任职授权记录">-->
<!--            <template v-slot:form>-->
<!--                <div v-if="isDepartment" class="w100 items_center justify_between">-->
<!--                    <div></div>-->
<!--                    <div>-->
<!--                        <el-button size="small" type="primary" @click="openDialog">新增</el-button>-->
<!--                    </div>-->
<!--                </div>-->
<!--            </template>-->
<!--            <template v-slot:table>-->
<!--                <ZTTable-->
<!--                    :column="columnData"-->
<!--                    :height="'calc(100vh - 21em)'"-->
<!--                    :table-data="tableData"-->
<!--                    :table-loading="loading"-->
<!--                    style="margin-top: 18px; padding: 0 15px;"-->
<!--                ></ZTTable>-->
<!--                <el-divider></el-divider>-->
<!--                <div class="pagination">-->
<!--                    <div></div>-->
<!--                    <el-pagination-->
<!--                        :page-size="pagination.pageSize"-->
<!--                        :page-sizes="[10, 20, 30, 40]"-->
<!--                        :total="pagination.total"-->
<!--                        layout="total, sizes, prev, pager, next, jumper"-->
<!--                        @current-change="currentChange"-->
<!--                        @size-change="sizeChange"-->
<!--                    >-->
<!--                    </el-pagination>-->
<!--                </div>-->
<!--            </template>-->
<!--        </TableCard>-->
        <Add ref="mandateModal" @refresh="getTableData"></Add>
    </div>
</template>
<script>
// import Add from "./Add.vue"
export default {
    components: {
        // Add
    },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
    data() {
        return {
            // departId: 0,
            columnData: [
                {
                    label: '序号',
                    prop: 'id'
                }, {
                    label: '证书编号',
                    prop: 'certificateNumber'
                }, {
                    label: '被任职人员',
                    prop: 'userName'
                }, {
                    label: '任职岗位',
                    prop: 'post'
                }, {
                    label: '理论考试成绩',
                    prop: 'num1'
                },{
                    label: '操作技能考试成绩',
                    prop: 'num2'
                },{
                    label: '操作时间',
                    prop: 'updateTime'
                }, {
                    label: '备注',
                    prop: 'remarks',
                    width: 300
                }, {
                    label: '操作',
                    dataType: 'action',
                    width: 160,
                fixed: 'right',
                    operation: [
                        {
                            name: '编辑',
                            type: 'text',
                            clickFun: (row) => {
                                this.openDialog(row, true)
                            }
                        }, {
                            name: '下载',
                            type: 'text',
                            clickFun: (row) => {
                                this.handleDown(row)
                            }
                        }, {
                            name: '删除',
                            type: 'text',
                            color: '#f56c6c',
                            clickFun: (row) => {
                                this.deleteNotify(row.id)
                            }
                        }
                    ]
                },
            ],
            tableData: [],
            pagination: {
                current: 1,
                pageSize: 20,
                total: 0
            },
            loading: false
        }
    },
    mounted() {
      this.getTableData()
        console.log(this.departId)
    },
    methods: {
        openDialog(row, type=false) {
            this.$refs.mandateModal.openDialog(row, type)
        },
        /**
         * @desc æŸ¥è¯¢è¡¨æ ¼æ•°æ®
         */
        async getTableData() {
            this.loading = true
          const params = this.isDepartment ? {
            departLimsId: this.departId,
            current: this.pagination.current,
            size: this.pagination.pageSize
          } : {
            userId: this.departId,
            current: this.pagination.current,
            size: this.pagination.pageSize
          }
            const { code, data } = await this.$axios({
                method: 'get',
                url: getPersonPostAuthorizationRecordPage,
                params: params
            })
            if(code == 200) {
                this.pagination.total = data.total
                this.tableData = data.records
                this.loading = false
            }
        },
        /**
         * @desc å½“前页改变
         */
        currentChange(current) {
            this.pagination.current = current
            this.getTableData()
        },
        /**
         * @desc æ¯é¡µä¸ªæ•°æ”¹å˜
         */
        sizeChange(pageSize) {
            this.pagination.pageSize = pageSize
            this.getTableData()
        },
        /**
         * @desc åˆ é™¤ä»»èŒè®°å½•
         */
        deleteNotify(id) {
            this.$confirm('此操作将永久删除该文件, æ˜¯å¦ç»§ç»­?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.delMandate(id)
            })
        },
        /**
         * @desc api删除
         */
        async delMandate(id) {
            const formData = new FormData()
            formData.append('id', id)
            const { code, data } = await this.$axios({
                method: 'delete',
                url: deletePersonPostAuthorizationRecord,
                data: formData,
                noQs: true
            })
            if(code == 200) {
                this.$message({ message: '删除成功', type: 'success' })
                this.getTableData()
            } else {
                this.$message({ message: '删除失败', type: 'error' })
            }
        },
        /**
         * @desc èŽ·å–è®¾å¤‡id
         */
        getDepart(id) {
            this.departId = id
            this.getTableData()
        },
        handleDown(row){
          this.$axios.post(this.$api.personPostAuthorizationRecord.exportPersonPostAuthorizationRecord,{id:row.id},{responseType: "blob"}).then(res => {
            if(res.code == 201){
              this.$message.error(res.message)
              return
            }
            const blob = new Blob([res],{ type: 'application/octet-stream' });
            //将Blob å¯¹è±¡è½¬æ¢æˆå­—符串
            let reader = new FileReader();
            reader.readAsText(blob, 'utf-8');
            reader.onload = () => {
              try {
                let result = JSON.parse(reader.result);
                if (result.message) {
                  this.$message.error(result.message);
                } else {
                  const url = URL.createObjectURL(blob);
                  const link = document.createElement('a');
                  link.href = url;
                  link.download = '任职授权-'+row.certificateNumber+'-'+row.post + '.docx';
                  link.click();
                  this.$message.success('导出成功')
                }
              } catch (err) {
                console.log(err);
                const url = URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;
                link.download = '任职授权-'+row.certificateNumber+'-'+row.post + '.docx';
                link.click();
                this.$message.success('导出成功')
              }
            }
          })
        }
    },
//   watch: {
//     departId: {
//       handler(newId, oldId) {
//         if (newId) {
//           this.getTableData();
//         }
//       }
//     }
//   }
}
</script>
<style scoped>
.flex_column {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}
.w100 {
    width: 100%;
}
.pagination {
    display: flex;
    justify-content: space-between
}
.items_center {
    display: flex;
    align-items: center;
}
.justify_between {
    justify-content: space-between
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,621 @@
<!-- äººå‘˜èƒ½åŠ› -->
<template>
  <div>
    <div style="text-align: left; margin-bottom: 15px;padding: 0 16px">
      <label>姓名</label>
      <el-input v-model="userName" placeholder="请输入姓名" size="small" style="width: 20vh;"></el-input>
      <el-button size="small" type="primary" @click="refreshTable">查询</el-button>
      <div v-if="!isDepartment" style="float: right;">
        <el-button size="small" type="primary" @click="addAppointPost('add')">新增</el-button>
      </div>
    </div>
    <div class="table">
      <TableCard :showForm="false" :showTitle="false">
        <template v-slot:table>
          <ZTTable
            :column="yearColumnData"
            :height="'calc(100vh - 20em)'"
            :table-data="tableData"
            :table-loading="yearLoading"
            style="padding: 0 15px;margin-bottom: 16px"
          >
            <div slot="jobResponsibilities" slot-scope="scope">
              <div v-html="changeLine(scope.row.responsibilities)"></div>
            </div>
            <div slot="placeWorkSlot" slot-scope="scope">
              <div v-html="changeLine(scope.row.placeWork)"></div>
            </div>
          </ZTTable>
        </template>
      </TableCard>
      <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]"
                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <!--新增能力认定弹框-->
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :title="title"
               :visible.sync="dialogVisible"
               width="80%" @close="resetForm">
      <el-form v-if="dialogVisible" ref="infoForm" :model="form" :rules="rules">
        <el-col :span="12">
          <el-form-item label="人员:" label-width="110px" prop="userId">
            <el-select v-model="form.userId" disabled clearable
                       filterable size="small" style="width: 100%;">
              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
<!--        <el-col :span="12">-->
<!--          <el-form-item label="职称:" label-width="110px" prop="technicalPost">-->
<!--            <el-input v-model="form.technicalPost" :disabled="operationType === 'view'" clearable size="small" style="width: 100%;"/>-->
<!--          </el-form-item>-->
<!--        </el-col>-->
        <el-col :span="24">
          <div style="display: flex;justify-content: space-evenly;font-weight: 600">
            <span>查核结果</span>
            <span>符合与否</span>
            <span>备注</span>
          </div>
        </el-col>
        <el-col :span="8">
          <el-form-item label="学历:" label-width="110px" prop="academicDegree">
            <el-input v-model="form.academicDegree" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="academicConformNot" style="text-align: center">
            <el-radio-group v-model="form.academicConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="academicRemarks">
            <el-input v-model="form.academicRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="相关年限:" label-width="110px" prop="relatedYears">
            <el-input v-model="form.relatedYears" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="relatedYearsConformNot" style="text-align: center">
            <el-radio-group v-model="form.relatedYearsConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="relatedYearsRemarks    ">
            <el-input v-model="form.relatedYearsRemarks    " :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="相关培训:" label-width="110px" prop="relatedTraining">
            <el-input v-model="form.relatedTraining" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="relatedTrainingConformNot" style="text-align: center">
            <el-radio-group v-model="form.relatedTrainingConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="relatedTrainingRemarks">
            <el-input v-model="form.relatedTrainingRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
                      size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="相关经验:" label-width="110px" prop="relevantExperience">
            <el-input v-model="form.relevantExperience" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="relevantExperienceConformNot" style="text-align: center">
            <el-radio-group v-model="form.relevantExperienceConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="relevantExperienceRemarks">
            <el-input v-model="form.relevantExperienceRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
                      size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="上岗证:" label-width="110px" prop="workLicense">
            <el-input v-model="form.workLicense" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"
                      style="width: 100%">
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="workLicenseConformNot" style="text-align: center">
            <el-radio-group v-model="form.workLicenseConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="workLicenseRemarks">
            <el-input v-model="form.workLicenseRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="岗位职责:" label-width="110px" prop="jobResponsibilitiesTem" style="height: 450px">
            <el-checkbox-group v-model="form.jobResponsibilitiesTem" :disabled="operationType === 'view' || operationType === 'confirm'"
                               @change="selectResponsibilities">
              <el-checkbox v-for="city in responsibilities" :key="city.value" :label="city.label"
                           :value="city.value"></el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="jobResponsibilitiesConformNot"
                        style="text-align: center;height: 420px">
            <el-radio-group v-model="form.jobResponsibilitiesConformNot" :disabled="operationType === 'view' || operationType === 'confirm'">
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="jobResponsibilitiesRemarks" style="height: 420px">
            <el-input v-model="form.jobResponsibilitiesRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
                      size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <span style="padding-left: 110px;font-size: 14px">备注:岗位职责达到5项及5项以上为符合</span>
        </el-col>
        <el-col :span="16">
          <el-form-item label="综合评价:" label-width="110px" prop="comprehensiveAssessment">
            <el-radio-group v-model="form.comprehensiveAssessment" :disabled="operationType === 'view' || operationType === 'confirm'">
              <el-radio label="Qualified this position">可胜任该岗位</el-radio>
              <el-radio label="You can work while training">可边培训边上岗</el-radio>
              <el-radio label="Iconpetent for the position">不胜任该岗位</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item prop="confirmOperatingPersonnelId" label="确认人:">
            <el-select v-model="form.confirmOperatingPersonnelId" clearable :disabled="operationType === 'view' || operationType === 'confirm'"
                       filterable size="small" style="width: 50%;">
              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="operationType !== 'view'" @click="resetForm">取消</el-button>
        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm">保存</el-button>
        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm1">提交并通知</el-button>
        <el-button v-if="operationType === 'confirm'" type="primary" @click="verifyGet">确认</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  components: {
  },
  data() {
    return {
      userName: '',
      tableData: [],
      search: {
        size: 20,
        current: 1,
        total: 0
      },
      title: '新增能力认定',
      operationType: '',
      yearColumnData: [
        {
          label: '岗位',
          prop: 'postName',
          minWidth: '100'
        }, {
          label: '姓名',
          prop: 'userName',
          minWidth: '100'
        }, {
          label: '学历',
          prop: 'academicDegree',
          minWidth: '100'
        }, {
          label: '专业',
          prop: 'major',
          minWidth: '100'
        }, {
          label: '职称',
          prop: 'professionalTitle',
          minWidth: '100'
        }, {
          dataType: 'slot',
          label: '岗位职责',
          prop: 'jobResponsibilities',
          minWidth: '200px',
          slot: 'jobResponsibilities'
        }, {
          dataType: 'tag',
          label: '综合评价',
          minWidth: '140px',
          prop: 'comprehensiveAssessment',
          formatData: (params) => {
            if (params == 'Qualified this position') {
              return '可胜任该岗位';
            } else if (params == 'You can work while training') {
              return '可边培训边上岗';
            } else {
              return '不胜任该岗位';
            }
          },
          formatType: (params) => {
            if (params == 'Qualified this position') {
              return 'success';
            } else if (params == 'You can work while training') {
              return 'warning';
            } else {
              return 'danger';
            }
          }
        }, {
          label: '确认人',
          prop: 'confirmOperatingPersonnelName',
          minWidth: '100'
        }, {
          label: '确认日期',
          prop: 'confirmDate',
          minWidth: '160'
        }, {
          dataType: 'action',
          minWidth: '220',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.handleViewClick('edit', row);
              },
              disabled: (row) => {
                if (row.confirmDate) {
                  return true
                } else {
                  return false
                }
              },
            },
            {
              name: '查看',
              type: 'text',
              clickFun: (row) => {
                this.handleViewClick('view', row);
              }
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              }
            },
            {
              name: '确认',
              type: 'text',
              clickFun: (row) => {
                this.handleViewClick('confirm', row);
              },
              disabled: (row) => {
                if (row.confirmDate || JSON.parse(localStorage.getItem("user")).userId != row.confirmOperatingPersonnelId) {
                  return true
                } else {
                  return false
                }
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deletePost(row.id);
              },
              disabled: (row) => {
                if (row.confirmDate) {
                  return true
                } else {
                  return false
                }
              }
            }
          ]
        }],
      yearLoading: false,
      dialogVisible: false,
      verifyGetId: '',
      form: {
        jobResponsibilitiesTem: []
      },
      responsibleOptions: [],
      rules: {
        confirmOperatingPersonnelId: [{ required: true, message: '请选择确认人', trigger: 'change' }],
        userId: [{ required: true, message: '请选择人员', trigger: 'change' }],
        academicDegree: [{ required: true, message: '请输入学历查核结果', trigger: 'blur' }],
        academicConformNot: [{ required: true, message: '请选择学历符合与否', trigger: 'change' }],
        relatedYears: [{ required: true, message: '请输入相关年限查核结果', trigger: 'blur' }],
        relatedYearsConformNot: [{ required: true, message: '请选择相关年限符合与否', trigger: 'change' }],
        relatedTraining: [{ required: true, message: '请输入相培训限查核结果', trigger: 'blur' }],
        relatedTrainingConformNot: [{ required: true, message: '请选择相关培训符合与否', trigger: 'change' }],
        relevantExperience: [{ required: true, message: '请输入相关经验查核结果', trigger: 'blur' }],
        relevantExperienceConformNot: [{ required: true, message: '请选择相关经验符合与否', trigger: 'change' }],
        workLicense: [{ required: true, message: '请输入上岗证查核结果', trigger: 'blur' }],
        workLicenseConformNot: [{ required: true, message: '请选择上岗证符合与否', trigger: 'change' }],
        jobResponsibilitiesTem: [{ required: true, message: '请选择岗位职责查核结果', trigger: 'change' }],
        jobResponsibilitiesConformNot: [{ required: true, message: '请选择岗位职责符合与否', trigger: 'change' }],
        comprehensiveAssessment: [{ required: true, message: '请选择综合评价', trigger: 'change' }]
      },
      responsibilities: []
    };
  },
  mounted() {
    this.getList(this.departId);
  },
  methods: {
    // ä¸‹è½½
    downLoadPost(row) {
      this.$axios.get(this.$api.personnel.exportPersonnelCapacity + '?id=' + row.id,{responseType: "blob"}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        //将Blob å¯¹è±¡è½¬æ¢æˆå­—符串
        let reader = new FileReader();
        reader.readAsText(blob, 'utf-8');
        reader.onload = () => {
          try {
            let result = JSON.parse(reader.result);
            if (result.message) {
              this.$message.error(result.message);
            } else {
              const url = URL.createObjectURL(blob);
              const link = document.createElement('a');
              link.href = url;
              link.download = "人员能力导出" + '.docx';
              link.click();
              this.$message.success('导出成功')
            }
          } catch (err) {
            console.log(err);
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = "人员能力导出" + '.docx';
            link.click();
            this.$message.success('导出成功')
          }
        }
      })
    },
    // æŸ¥è¯¢
    refreshTable() {
      this.getList(this.departId);
    },
    // èŽ·å–äººå‘˜èƒ½åŠ›åˆ—è¡¨ä¿¡æ¯
    getList(userId) {
      this.search.userId = userId;
      const name = this.isDepartment ? 'departmentId' : 'userId';
      this.yearLoading = true
      this.$axios.get(this.$api.personnel.personPersonnelCapacityPage + '?userName=' + this.userName + `&${name}=` + this.search.userId + '&size=' + this.search.size + '&current=' + this.search.current).then(res => {
        this.yearLoading = false
        if (res.code === 201) return;
        this.tableData = res.data.records;
        this.search.total = res.data.total;
      }).catch(err => {
        console.log(err);
        this.yearLoading = false
      })
    },
    selectResponsibilities(arr) {
      let arrTem = [];
      arr.map(val => {
        const index = this.responsibilities.findIndex(item => item.label === val);
        if (index > -1) {
          arrTem.push(this.responsibilities[index].value);
        }
      });
      this.form.jobResponsibilities = arrTem.join(',');
    },
    getResponsibilities() {
      this.$axios.post(this.$api.enums.selectEnumByCategory, {
        category: '岗位职责'
      }).then(res => {
        this.responsibilities = res.data;
      });
    },
    changeLine (val) {
      if(val) {
        return val.replace(/,/g, '<br>')
      } else {
        return
      }
    },
    // æ–°å¢ž
    addAppointPost(type) {
      this.operationType = type;
      this.title = '新增能力认定'
      this.dialogVisible = true;
      console.log('this.departId---', this.departId)
      this.form = {
        jobResponsibilitiesTem: []
      }
      this.form.userId = this.departId
      this.getUserList();
      this.getResponsibilities();
    },
    // ç¼–辑/查看
    handleViewClick(type, row) {
      this.operationType = type;
      this.verifyGetId = row.id
      this.title = this.operationType === 'edit' ? '修改能力认定' : '查看能力认定'
      this.dialogVisible = true;
      this.form = {...row}
      if(this.form.responsibilities) {
        this.$set(this.form, 'jobResponsibilitiesTem', this.form.responsibilities.split(","))
      } else {
        this.$set(this.form, 'jobResponsibilitiesTem', [])
      }
      this.getUserList();
      this.getResponsibilities();
    },
    // ä¿å­˜
    submitForm() {
      this.$refs.infoForm.validate((valid) => {
        if (valid) {
          this.$axios.post(this.$api.personnel.addOrUpdatePersonPersonnelCapacity, this.form, {
            headers: {
              'Content-Type': 'application/json'
            }
          }).then(res => {
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.getList(this.departId);
              this.dialogVisible = false;
            }
          });
        }
      });
    },
    // æäº¤å¹¶é€šçŸ¥
    submitForm1() {
      this.$refs.infoForm.validate((valid) => {
        if (valid) {
          this.$axios.post(this.$api.personnel.submitConfirmPersonnelCapability, this.form, {
            headers: {
              'Content-Type': 'application/json'
            }
          }).then(res => {
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.getList(this.departId);
              this.dialogVisible = false;
            }
          });
        }
      });
    },
    verifyGet () {
      this.$axios.get(this.$api.personnel.confirmPersonnelCapability + '?id=' + this.verifyGetId).then(res => {
        if (res.code == 200) {
          this.$message.success('确认成功');
          this.resetForm()
          this.getList(this.departId);
        }
      });
    },
    // åˆ é™¤å²—位职责
    deletePost(id) {
      this.$confirm('此操作将永久删除此数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$axios.delete(this.$api.personnel.deletePersonPersonnelCapacity + '?id=' + id).then(res => {
          if (res.code == 200) {
            this.$message.success('删除成功');
            this.getList(this.departId);
          }
        });
      }).catch(() => {
        this.$message.error('删除失败');
      });
    },
    resetForm() {
      this.$refs.infoForm.resetFields();
      this.dialogVisible = false;
    },
    getUserList(){
      this.$axios.get(this.$api.user.selectDepartmentLimsUserList).then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      })
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.getList(this.departId);
    },
    handleCurrentChange(val) {
      this.search.current = val;
      this.getList(this.departId);
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    departId: {
      handler(newId, oldId) {
        this.getList(newId);
      }
    },
    // ç›‘听点击el-tree的数据,进行数据刷新
    isDepartment: {
      handler(newId, oldId) {
        this.getList(this.departId);
      }
    },
  }
};
</script>
<style scoped>
>>>.el-dialog {
  margin: 6vh auto 50px !important;
}
>>> .el-dialog__body {
  max-height: 70vh;
  overflow-y: auto;
}
.radio-group >>> .el-form-item__error {
  padding-left: 38px;
}
>>>.el-checkbox__label {
  width: 212px;
  white-space: pre-wrap;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1067 @@
<template>
  <div>
    <div style="text-align: right;margin-bottom: 10px">
<!--       <el-button size="small" @click="$emit('goBackList')">返回</el-button>-->
      <el-button size="small" type="primary" @click="downPerson">下载档案</el-button>
      <el-button size="small" type="primary" @click="dialogVisible = true">人员分类</el-button>
      <el-button :loading="saveLoading" size="small" type="primary" @click="save">保存</el-button>
    </div>
    <div>
      <div style="display: flex;flex-direction: row;">
        <div style="width: 12em">
          <el-image :src="javaApi + '/img/' + form.pictureUrl" fit="fill"
                    style="width:100%;height: 300px;border: 1px solid #000;border-radius: 10px;margin-left: 6px;margin-top: 10px;">
            <div slot="error" class="image-slot">
              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
            </div>
          </el-image>
          <el-image :src="javaApi + '/img/' + form.signatureUrl" fit="fill"
                    style="width:80%;height: 50px;border: 1px solid #000;border-radius: 10px;margin-left: 22px;margin-top: 20px;">
            <div slot="error" class="image-slot">
              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
            </div>
          </el-image>
        </div>
        <div style="height: calc(100vh - 14em);overflow-y: auto">
          <el-form ref="form" :model="form" label-width="110px">
            <el-row>
              <el-col :span="8">
                <el-form-item label="姓名">
                  <el-input disabled v-model="form.name" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="工号">
                  <el-input disabled v-model="form.account" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="当前状态">
                  <el-radio-group v-model="form.currentState">
                    <el-radio label="1formal" size="mini">正式</el-radio>
                    <el-radio label="2intern" size="mini">实习</el-radio>
                    <el-radio label="3leaveOffice" size="mini">离职</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="性别">
                  <el-radio-group v-model="form.sex">
                    <el-radio label="1" size="mini">男</el-radio>
                    <el-radio label="0" size="mini">女</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="公司名称">
                  <el-input v-model="form.corporateName" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="所属部门">
                  <el-cascader v-model="form.departLimsId" :options="department" :props="{ label: 'name', value: 'id',checkStrictly: true }"  filterable style="width: 100%;"></el-cascader>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="岗位名称">
                  <el-input v-model="form.postName" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="入集团时间">
                  <el-date-picker v-model="form.groupTime" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="劳动关系">
                  <el-radio-group v-model="form.laborRelations">
                    <el-radio :label=0 size="mini">合同工</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="公司邮箱">
                  <el-input v-model="form.email" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="工作时间">
                  <el-date-picker v-model="form.workingTime" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="合同到期时间">
                  <el-date-picker v-model="form.contractLifeTime" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="职称">
                  <el-input v-model="form.professionalTitle" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="16" style="text-align: left;">
                <el-form-item label="人员分类">
                  <span style="color: #000;">{{ form.personnelClassification }}</span>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="出生日期">
                  <el-date-picker v-model="form.dateBirth" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  @change="getAge"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="籍贯">
                  <el-input v-model="form.nativePlace" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="民族">
                  <el-input v-model="form.nation" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="身份证号">
                  <el-input v-model="form.identityCard" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="年龄">
                  <el-input-number v-model="form.age" :max="130" :min="1"
                                   controls-position="right" size="small" style="width: 99%;"></el-input-number>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="婚姻状况">
                  <el-radio-group v-model="form.maritalStatus">
                    <el-radio :label=0 size="mini">已婚</el-radio>
                    <el-radio :label=1 size="mini">未婚</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="证件有效期">
                  <el-date-picker v-model="form.validityPeriod" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="证件地址">
                  <el-input v-model="form.idAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="证件详细地址">
                  <el-input v-model="form.idDetailAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="政治面貌">
                  <el-input v-model="form.politicalStatus" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="入党/团时间">
                  <el-date-picker v-model="form.dumplingTime" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="手机号">
                  <el-input v-model="form.telephone" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="最高学历">
                  <el-input v-model="form.officialAcademicRedentials" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="最高学位">
                  <el-input v-model="form.highestDegree" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="毕业院校1">
                  <el-input v-model="form.graduatedInstitutions1" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="专业1">
                  <el-input v-model="form.major1" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="毕业时间1">
                  <el-date-picker v-model="form.graduationTime1" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="毕业院校2">
                  <el-input v-model="form.graduatedInstitutions2" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="专业2">
                  <el-input v-model="form.major2" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="毕业时间2">
                  <el-date-picker v-model="form.graduationTime2" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="登记时间">
                  <el-date-picker v-model="form.lastUpdateTime" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="备注">
                  <el-input type="textarea" v-model="form.remarks" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="18">
                <el-form-item label="个人照片">
                  <el-input v-model="form.pictureUrl" disabled size="small">
                    <el-button v-if="form.pictureUrl" slot="append" icon="el-icon-delete-solid"
                               @click="deleteFile(form.pictureUrl, 'pictureUrl')"></el-button>
                  </el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-upload ref="upload" :action="action" :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'pictureUrl')"
                           :show-file-list="false"
                           style="float: left; margin: 0 10px 0 10px;">
                  <el-button slot="trigger" class="uploadFile" size="mini" type="primary">上传</el-button>
                </el-upload>
                <el-button v-if="form.pictureUrl" class="uploadFile" size="mini"
                           type="primary" @click="downloadFile(form.pictureUrl)">下载</el-button>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="18">
                <el-form-item label="电子签名">
                  <el-input v-model="form.signatureUrl" disabled size="small">
                    <el-button v-if="form.signatureUrl" slot="append" icon="el-icon-delete-solid"
                               @click="deleteFile(form.signatureUrl, 'signatureUrl')"></el-button>
                  </el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-upload ref="upload" :action="action" :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'signatureUrl')"
                           :show-file-list="false"
                           style="float: left; margin: 0 10px 0 10px;">
                  <el-button slot="trigger" class="uploadFile" size="small" type="primary">上传</el-button>
                </el-upload>
                <el-button v-if="form.signatureUrl" class="uploadFile" size="small"
                           type="primary" @click="downloadFile(form.signatureUrl)">下载</el-button>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="20">
                <el-form-item label="证书资料" >
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd(0)">新增</el-button>
              </el-col>
            </el-row>
            <el-table :data="annexList" border height="200" style="width: 96%;float: right;">
              <el-table-column label="序号" type="index" width="80px">
              </el-table-column>
              <el-table-column label="证件号" prop="idNumber" width="150px">
              </el-table-column>
              <el-table-column label="发证单位" prop="issueUnit" width="150px">
              </el-table-column>
              <el-table-column label="文件名称" prop="fileName" show-overflow-tooltip width="200px">
              </el-table-column>
              <el-table-column label="级别" prop="level" width="150px">
              </el-table-column>
              <el-table-column label="有效期" prop="periodValidity" width="150px">
              </el-table-column>
              <el-table-column label="添加时间" prop="createTime" width="150px">
              </el-table-column>
              <el-table-column fixed="right" label="操作" width="150px">
                <template slot-scope="scope">
                  <el-button size="mini" type="text" @click="downloadFile(scope.row.fileName)">下载</el-button>
                  <el-button size="mini" type="text" @click="annexAdd(1,scope.row)">编辑</el-button>
                  <el-button size="mini" type="text" @click="deleteAnnex(scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
            <el-row>
              <el-col :span="20">
                <el-form-item label="附件资料" >
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-upload ref='upload'
                           :action="fileAction"
                           :auto-upload="true" :data="{userId: clickNodeVal.userId}"
                           :before-upload="fileBeforeUpload"
                           :headers="uploadHeader" :on-error="onError"
                           :on-success="handleSuccessUp"
                           :show-file-list="false"
                           accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
                  <el-button size="small" style="margin-top: 10px" type="primary">附件上传</el-button>
                </el-upload>
              </el-col>
            </el-row>
            <lims-table :tableData="tableData" :column="columnData" style="width: 96%;float: right;"
                        height="200" :tableLoading="tableLoading"></lims-table>
            <el-row>
              <el-col :span="20">
                <el-form-item label="工作经历" >
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd1('add')">新增</el-button>
              </el-col>
            </el-row>
            <el-table :data="tableData1" border height="200" style="width: 96%;float: right;" v-loading="tableLoading1">
              <el-table-column label="序号" type="index" width="80px" align="center">
              </el-table-column>
              <el-table-column label="工作经历" prop="workExperience">
              </el-table-column>
              <el-table-column align="center" label="操作">
                <template slot-scope="scope">
                  <el-button type="text" @click="annexAdd1('edit',scope.row)">编辑</el-button>
                  <el-button type="text" @click="deleteAnnex1(scope.row)" style="color: #f56c6c">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-form>
        </div>
      </div>
    </div>
    <!-- äººå‘˜åˆ†ç±»å¼¹æ¡† -->
    <el-dialog :visible.sync="dialogVisible" title="提示" width="40%" @open="getComparisonList">
      <div style="height: 30vh;">
        <el-row>
          <el-col :span="4">
            äººå‘˜åˆ†ç±»ï¼š
          </el-col>
          <el-col :span="20" style="text-align: left;">
            <el-checkbox-group v-model="checkList">
              <el-checkbox v-for="v in dict.type.personnl_type" :key="v.value"
                           :label="v.value"></el-checkbox>
            </el-checkbox-group>
          </el-col>
        </el-row>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="clickPersonnelClassificationSure">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <!-- æ–°å¢žé™„件资料 -->
    <el-dialog :before-close="handleClose" :title="title" :visible.sync="dialogVisible1" width="40%" @open="getComparisonList">
      <el-form ref="annex" :model="annex" :rules="rules" label-width="100px">
        <el-row>
          <el-col :span="16">
            <el-form-item label="证件号" prop="idNumber">
              <el-input v-model="annex.idNumber" clearable size="small" style="width: 100%;"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="发证单位" prop="issueUnit">
              <el-input v-model="annex.issueUnit" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="级别">
              <el-input v-model="annex.level" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="有效期" prop="periodValidity">
              <el-input v-model="annex.periodValidity" clearable size="small"></el-input>
<!--              <el-date-picker v-model="annex.periodValidity" format="yyyy-MM-dd" placeholder="选择日期" size="small"-->
<!--                              style="width: 99%;" type="date" value-format="yyyy-MM-dd">-->
<!--              </el-date-picker>-->
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="复印件">
              <el-input v-model="annex.copy" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="原件">
              <el-input v-model="annex.original" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="文件">
              <el-upload
                :action="action"
                :before-upload="beforeAvatarUpload"
                :on-success="(response,file,fileList) => onSuccess(response, file, fileList, 'fileName')"
                :show-file-list="false">
                <span v-if="annex.fileName">{{annex.fileName}}</span>
<!--                <img v-if="imageUrl" :src="imageUrl" class="avatar">-->
                <i v-else class="el-icon-upload avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancellation">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitForm">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <!-- æ–°å¢žå·¥ä½œç»åކ -->
    <el-dialog @close="handleClose2" title="添加工作经历" :visible.sync="dialogVisible2" width="40%">
      <el-form ref="annex2" :model="annex2" label-width="100px">
        <el-row>
          <el-col :span="16">
            <el-form-item label="工作经历" prop="idNumber">
              <el-input type="textarea" v-model="annex2.workExperience" clearable size="small" style="width: 100%;"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleClose2">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitForm2">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import fileDownload from '@/utils/file'
import {
  addAnnex,
  addBasicInfoWork,
  delBasicInfoFileList,
  delBasicInfoWorkList,
  deleteAnnex, deleteCNASFile,
  exportPersonBasicInfoById,
  getAnnex,
  getAnnexByUserId,
  getBasicInfoFileList,
  getBasicInfoWorkList,
  getCNASPersonnelInfo,
  saveCNASPersonnelInfo,
  updateAnnex,
  updateBasicInfoWorkList
} from "@/api/cnas/personal/personalList";
import limsTable from "@/components/Table/lims-table.vue";
export default {
  props: {
    clickNodeVal: {
      type: Object,
      default: () => { return {} }
    },
  },
  dicts: ['personnl_type'],
  data() {
    return {
      operationType: '',
      basicInfoWorkId: '',
      dialogVisible2: false,
      annex2: {
        workExperience: ''
      },
      tableLoading: false,
      tableData: [],
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delete(row)
              }
            }
          ]
        }
      ],
      tableLoading1: false,
      tableData1: [],
      addOrupdate: null,
      title: '',
      annexList: [],
      imageUrl: '',
      annex: {
        userId: '',
        idNumber: '',
        issueUnit: '',
        level: '',
        periodValidity: '',
        copy: '',
        original: '',
        fileName: ''
      },
      rules: {
        idNumber: [
          { required: true, message: '请输入证件号', trigger: 'blur' }
        ],
        issueUnit: [
          { required: true, message: '请输入发证单位', trigger: 'blur' }
        ],
        periodValidity: [
          { required: false, message: '请选择有效期', trigger: 'blur' }
        ]
      },
      dialogVisible1: false,
      form: {
        userId: '',
        name: '',
        account: '',
        currentState: '',
        sex: '',
        corporateName: '',
        department: '',
        departLimsId: [],
        postName: '',
        groupTime: '',
        laborRelations: '',
        workingTime: '',
        contractLifeTime: '',
        personnelClassification: '',
        dateBirth: '',
        nativePlace: '',
        nation: '',
        identityCard: '',
        age: '',
        validityPeriod: '',
        maritalStatus: '',
        idAddress: '',
        idDetailAddress: '',
        politicalStatus: '',
        dumplingTime: '',
        telephone: '',
        email: '',
        officialAcademicRedentials: '',
        highestDegree: '',
        graduatedInstitutions1: '',
        major1: '',
        graduationTime1: '',
        graduatedInstitutions2: '',
        major2: '',
        graduationTime2: '',
        lastUpdateTime: '',
        pictureUrl: '',
        signatureUrl: '',
        professionalTitle: '',
        remarks: '',
      },
      department: [],
      saveLoading: false,
      dialogVisible: false,
      checkList: [],
      successFileList: [], // é˜²æ­¢åŽç«¯å‡ºçŽ°è„æ•°æ®
      isSave: false,
    }
  },
  components: {limsTable, fileDownload},
  created() {
    this.init()
    this.searchTableList()
    this.searchTableList2()
  },
  computed: {
    action() {
      return this.javaApi + '/personBasicInfo/saveCNASFile'
    },
    fileAction() {
      return this.javaApi + '/personBasicInfo/uploadBasicInfoFile'
    },
  },
  methods: {
    // ä¸‹è½½æ¡£æ¡ˆ
    downPerson(){
      exportPersonBasicInfoById({id: this.clickNodeVal.userId}).then(res => {
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '人员档案.docx');
        this.$message.success('导出成功')
      })
    },
    // ä¸Šä¼ éªŒè¯
    fileBeforeUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    onError(err, file, fileList,type) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response, ) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchTableList()
      } else {
        this.$message.error(response.message);
      }
    },
    // æŸ¥è¯¢é™„件列表
    searchTableList () {
      this.tableLoading = true
      getBasicInfoFileList({userId: this.clickNodeVal.userId}).then(res => {
        this.tableLoading = false
        this.tableData = res.data
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        fileDownload.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
    // åˆ é™¤
    delete (row) {
      this.$confirm('此操作将删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        delBasicInfoFileList({basicInfoFileId: row.basicInfoFileId}).then(res => {
          this.tableLoading = false
          this.$message.success('删除成功')
          this.searchTableList();
        }).catch(err => {
          this.tableLoading = false
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      })
    },
    // æ‰“开工作经历探况
    annexAdd1 (type, row) {
      this.operationType = type
      if (type === 'edit') {
        this.basicInfoWorkId = row.basicInfoWorkId
        this.annex2.workExperience = row.workExperience
      } else {
        this.basicInfoWorkId = ''
        this.annex2.workExperience = ''
      }
      this.dialogVisible2 = true
    },
    // æäº¤å·¥ä½œç»åކ
    submitForm2 () {
      const params = {
        workExperience: this.annex2.workExperience,
        userId: this.clickNodeVal.userId,
        basicInfoWorkId: this.basicInfoWorkId
      }
      this.tableLoading1 = true
      if (this.operationType === 'add') {
        addBasicInfoWork(params).then(res => {
          this.tableLoading1 = false
          if (res.code == 200) {
            this.dialogVisible2 = false
            this.$message.success('新增成功')
            this.searchTableList2();
          }
        }).catch(err => {
          this.tableLoading1 = false
        })
      } else {
        updateBasicInfoWorkList(params).then(res => {
          this.tableLoading1 = false
          this.dialogVisible2 = false
          this.$message.success('修改成功')
          this.searchTableList2();
        }).catch(err => {
          this.tableLoading1 = false
        })
      }
    },
    // å…³é—­å·¥ä½œç»åŽ†å¼¹æ¡†
    handleClose2 () {
      this.dialogVisible2 = false
      this.annex2.workExperience = ''
    },
    // åˆ é™¤å·¥ä½œç»åކ
    deleteAnnex1 (row) {
      this.$confirm('此操作将删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading1 = true
        delBasicInfoWorkList({basicInfoWorkId: row.basicInfoWorkId}).then(res => {
          this.tableLoading1 = false
          this.$message.success('删除成功')
          this.searchTableList2();
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // æŸ¥è¯¢å·¥ä½œç»åŽ†åˆ—è¡¨
    searchTableList2 () {
      this.tableLoading1 = true
      getBasicInfoWorkList({userId: this.clickNodeVal.userId}).then(res => {
        this.tableLoading1 = false
        this.tableData1 = res.data
      }).catch(err => {
        this.tableLoading1 = false
        console.log('err---', err);
      })
    },
    annexAdd(type,row) {
      if(type === 1) {
        this.title = '编辑附件资料'
        this.addOrupdate = 1
        getAnnex({id: row.id}).then(res => {
          this.annex = res.data
          this.imageUrl = this.javaApi + '/img/' + res.data.fileName
        })
      }else {
        this.title = '新增附件资料'
        this.addOrupdate = 2
      }
      this.dialogVisible1 = true
    },
    submitForm() {
      this.$refs['annex'].validate((valid) => {
        if (valid) {
          this.addAnnex()
        } else {
          return false
        }
      })
    },
    addAnnex() {
      if(this.annex.fileName == "" || this.annex.fileName == null || this.annex.fileName == undefined) {
        this.$message.error("请上传文件")
        return
      }
      this.annex.userId = this.clickNodeVal.userId
      if(this.addOrupdate === 1) {
        updateAnnex(this.annex).then(res => {
          if(res.code == 200) {
            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
              this.imageUrl = ''
              this.resetForm('annex')
              this.annexList = res.data
              this.dialogVisible1 = false
              this.$message.success('更新成功!')
            })
          }
        })
      }else {
        this.annex.id = null
        addAnnex(this.annex).then(res => {
          if(res.code == 200) {
            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
              this.imageUrl = ''
              this.resetForm('annex')
              this.annexList = res.data
              this.dialogVisible1 = false
              this.$message.success('保存成功')
            })
          }
        })
      }
    },
    deleteAnnex(row) {
      this.$confirm('此操作将永久删除该文件, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteAnnex({id: row.id}).then(res => {
          this.$message.success('删除成功!')
          this.annexList = this.annexList.filter(item => item.id != row.id)
        })
      })
    },
    beforeAvatarUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    downloadFile(fileName) {
      let state = /\.(jpg|jpeg|png|gif)$/i.test(fileName)
      if (state) {
        let url = this.javaApi + '/img/' + fileName;
        fileDownload.downloadIamge(url, fileName)
      } else {
        const url = this.javaApi + '/word/' + fileName
        const link = document.createElement('a');
        link.href = url;
        link.download = fileName;
        link.click();
        this.$message.success('下载成功')
      }
    },
    async onSuccess(response, file, fileList, entityVal) {
      if(entityVal == 'fileName') {
        this.annex.fileName = response.data
      }
      // åœ¨ä¿å­˜èµ‹å€¼æ–°æ–‡ä»¶
      this.successFileList.push(response.data)
      this.$set(this.form, entityVal, response.data)
    },
    // åˆå§‹åŒ–调用
    init() {
      if (!this.clickNodeVal.userId) {
        let user = JSON.parse(localStorage.getItem('user'))
        this.getUserBasisInfo(user.userId)
        this.clickNodeVal.userId = user.userId
      } else {
        this.getUserBasisInfo(this.clickNodeVal.userId)
      }
    },
    getUserBasisInfo(userId) {
      getCNASPersonnelInfo({userId: userId}).then(res => {
        this.form = res.data.PersonBasicInfoDto
        this.department = res.data.department
        this.annexList = res.data.annexList
        this.form.departLimsId = res.data.PersonBasicInfoDto.departLimsId.split(',').filter(a => a != "").map(Number)
      })
    },
    async save() {
      this.saveLoading = true
      this.form.userId = this.clickNodeVal.userId
      if(Array.isArray(this.form.departLimsId)) {
        if(this.form.departLimsId.length > 0) {
          this.form.departLimsId = this.form.departLimsId.join(',').trim() + ','
        }else {
          this.form.departLimsId = ''
        }
      }
      saveCNASPersonnelInfo(this.form).then(res => {
        this.saveLoading = false
        this.isSave = true
        this.getUserBasisInfo(this.clickNodeVal.userId)
        this.$message.success('保存成功!')
      })
    },
    // å–人员分类的字典
    getComparisonList() {
      if (this.checkList.length > 0) {
        this.form.personnelClassification = this.checkList.split(',')
      }
    },
    clickPersonnelClassificationSure() {
      this.dialogVisible = false
      this.form.personnelClassification = this.checkList.filter(m=>m).join(',')
    },
    async deleteFile(fileName, entityVal) {
      await deleteCNASFile({fileName: fileName}).then(res => {
        this.$message.success('删除成功!')
        this.$set(this.form, entityVal, null)
        let index = this.successFileList.indexOf(fileName)
        if (index != -1) {
          this.successFileList.splice(index, 1)
        }
      })
    },
    cancellation() {
      this.dialogVisible1 = false
      this.imageUrl = ''
      this.resetForm('annex')
    },
    handleClose(done) {
      this.imageUrl = ''
      this.annex = {
        userId: '',
        idNumber: '',
        issueUnit: '',
        level: '',
        periodValidity: '',
        copy: '',
        original: '',
        fileName: ''
      }
      done();
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    getAge (val) {
      this.form.age = this.calculateAge(val)
    },
    calculateAge(birthDateString) {
      // è§£æžå‡ºç”Ÿæ—¥æœŸå­—符串为日期对象
      const birthDate = new Date(birthDateString);
      // èŽ·å–å½“å‰æ—¥æœŸ
      const currentDate = new Date();
      // è®¡ç®—年份差
      let age = currentDate.getFullYear() - birthDate.getFullYear();
      // æ£€æŸ¥æ˜¯å¦å·²ç»è¿‡äº†ä»Šå¹´çš„生日
      const currentMonth = currentDate.getMonth();
      const currentDay = currentDate.getDate();
      const birthMonth = birthDate.getMonth();
      const birthDay = birthDate.getDate();
      if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
        // å¦‚果还没到今年的生日,年龄减1
        age--;
      }
      return age;
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    clickNodeVal: {
      handler(newVal, oldVal) {
        if (newVal.userId) {
          this.getUserBasisInfo(newVal.userId)
          this.searchTableList()
          this.searchTableList2()
        }
      },
    }
  }
}
</script>
<style scoped>
>>>.el-form-item {
    margin-bottom: 3px;
}
.el-input {
    border-radius: 15px;
}
.el-icon-picture-outline {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}
.uploadFile {
    margin-top: 2px;
    float: left;
}
  .avatar-uploader-icon {
    font-size: 28px;
    color: #0f8bf1;
    width: 178px;
    height: 50px;
    text-align: center;
    border: 1px solid #d9d9d9;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,321 @@
<template>
  <div>
    <div style="display: flex;justify-content: space-between;">
      <el-form :model="entity" ref="entity" size="small" :inline="true">
        <el-form-item label="人员名称">
          <el-input v-model="entity.name" clearable></el-input>
        </el-form-item>
        <el-form-item>
          <el-button size="small" style="margin-left: 10px" @click="refresh()">重 ç½®</el-button>
          <el-button size="small" type="primary" @click="refreshTable()">查 è¯¢</el-button>
        </el-form-item>
      </el-form>
      <div>
        <el-button
          :loading="outLoading"
          size="small"
          type="primary"
          @click="handleDown">导出</el-button>
        <el-button size="small" type="primary" @click="openSelectUserDia">新建</el-button>
      </div>
    </div>
    <div class="search-table">
      <el-table v-loading="tableLoading" :data="tableData" border height="calc(100vh - 21em)" style="width: 100%;">
        <el-table-column align="center" label="序号" type="index" width="60"></el-table-column>
        <el-table-column label="员工编号" prop="account" width="150"></el-table-column>
        <el-table-column label="姓名" prop="name" width="120"></el-table-column>
        <el-table-column label="籍贯" prop="nativePlace" width="120"></el-table-column>
        <el-table-column label="证件地址" prop="idAddress" show-overflow-tooltip width="100"></el-table-column>
        <el-table-column label="手机号" prop="telephone" show-overflow-tooltip width="100"></el-table-column>
        <el-table-column label="毕业院校" prop="graduatedInstitutions1" width="100"></el-table-column>
        <el-table-column label="所学专业" prop="major1" width="100"></el-table-column>
        <el-table-column label="毕业时间" prop="graduationTime1" width="100"></el-table-column>
        <el-table-column label="最高学历" prop="officialAcademicRedentials" width="100"></el-table-column>
        <el-table-column label="最高学位" prop="highestDegree" width="100"></el-table-column>
        <el-table-column label="职称" prop="professionalTitle" width="100"></el-table-column>
        <el-table-column fixed="right" label="操作" width="120" align="center">
          <template slot-scope="scope">
            <el-button size="small" type="text" @click="$emit('updatePerson', scope.row)">编辑</el-button>
            <el-button size="small" type="text" @click="deletePerson(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        :current-page="1"
        :current-page.sync="page.current"
        :page-size="page.size"
        :page-sizes="[10, 20, 30, 50, 100]"
        :total="page.total"
        background
        layout="->,total, sizes, prev, pager, next, jumper"
        style="margin-top: 16px"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>
    <el-dialog :visible.sync="selectUserDia" title="选择用户" width="70%">
      <div class="search" style="margin-bottom: 9px;">
        <div class="search_thing">
          <div class="search_label">用户名:</div>
          <div class="search_input">
            <el-input
              v-model="addUserTableInfo.name"
              clearable
              placeholder="请输入"
              size="small"
              @change="selectUserList"
            ></el-input>
          </div>
          <el-button size="small" style="margin-left: 10px" type="primary" @click="selectUserList">查询</el-button>
        </div>
      </div>
      <div v-if="selectUserDia" class="body" style="height: 60vh;">
        <lims-table :tableData="tableData1" :column="column1"
                    :isSelection="true" :handleSelectionChange="selectMethod"
                    :height="'calc(100vh - 290px)'"
                    :tableLoading="tableLoading1"></lims-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="selectUserDia = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="selectUser">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {selectUserCondition} from "@/api/business/inspectionTask";
import limsTable from "@/components/Table/lims-table.vue";
import {
  basicInformationOfPersonnelSelectPage,
  delUserDepardLimsId,
  exportPersonBasicInfo,
  upUserDepardLimsId
} from "@/api/cnas/personal/personalList";
import store from "@/store";
import {Message} from "element-ui";
export default {
  name: 'PersonnelList',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {limsTable},
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    },
    currentCompaniesList: {
      type: Array,
      default: []
    }
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      page: {
        size: 20,
        current: 1,
      },
      outLoading: false,
      tableLoading: false,
      tableData: [], // äººå‘˜æ€»åˆ—表数据
      tableData1: [],
      tableLoading1: false,
      column1: [
        {label: '姓名', prop: 'name'},
        {label: '账号', prop: 'account'},
        {label: '角色', prop: 'roleName'},
        {
          dataType: 'tag',
          label: '状态',
          prop: 'status',
          formatData: (params) => {
            if (params == 0) {
              return '启用'
            } else {
              return ''
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'success'
            } else {
              return 'danger'
            }
          }
        },
        {label: '电话号码', prop: 'phone'},
      ],
      page1: {
        total:0,
        size:10,
        current:1
      },
      selectUserDia: false, // æ·»åŠ äººå‘˜å¼¹æ¡†
      entity: {
        name: '',
        orderBy: {
          field: 'id',
          order: 'asc'
        }
      },
      addUserTableInfo: {
        name: null,
        isCustom: 0,
      },
      multipleSelection: []
    };
  },
  mounted() {
    this.refreshTable();
  },
  // æ–¹æ³•集合
  methods: {
    /**
     * @desc èŽ·å–è®¾å¤‡id
     */
    // é‡ç½®
    refresh() {
      this.page = {
        size: 20,
        current: 1,
      };
      this.entity.name = ''
      this.refreshTable();
    },
    // æŸ¥è¯¢äººå‘˜åˆ—表数据
    refreshTable() {
      this.tableLoading = true;
      this.entity.departLimsId = this.departId;
      const params = {
        size: this.page.size,
        current: this.page.current,
        departmentId: this.entity.departLimsId,
        name: this.entity.name,
      }
      basicInformationOfPersonnelSelectPage(params).then(res => {
        this.tableLoading = false;
        this.page.total = res.data.total;
        this.tableData = res.data.records;
      }).catch(err => {
        this.tableLoading = false;
      })
    },
    // åˆ é™¤äººå‘˜
    deletePerson(row) {
      this.$confirm('是否删除当前数据?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delUserDepardLimsId({id: row.userId}).then(res => {
          this.$message.success('删除成功');
          this.refreshTable();
          this.$emit('refreshTree')
        }).catch(e => {
          this.$message.error('删除失败');
        });
      }).catch(() => {
      });
    },
    handleSizeChange(val) {
      this.page.size = val;
      this.refreshTable();
    },
    handleCurrentChange(val) {
      this.page.current = val;
      this.refreshTable();
    },
    // æ‰“开新增人员弹框
    openSelectUserDia () {
      this.selectUserDia = true;
      this.selectUserList()
    },
    // æŸ¥è¯¢æ–°å¢žå¼¹æ¡†çš„人员列表
    selectUserList () {
      this.tableLoading1 = true
      selectUserCondition().then(res => {
        this.tableLoading1 = false
        this.tableData1 = res.data
      }).catch(err => {
        this.tableLoading1 = false
      })
    },
    // è¡¨æ ¼é€‰æ‹©æ–¹æ³•
    selectMethod(val) {
      this.multipleSelection = val
    },
    // æäº¤éœ€è¦æ·»åŠ çš„äººå‘˜
    selectUser() {
      if (!this.currentCompaniesList.length > 0) {
        this.$message.warning("请选择部门!")
        return;
      }
      let selects = this.HaveJson(this.multipleSelection)
      if (selects.length === 0) {
        this.$message.error('未选择数据');
        return;
      }
      let ids = [];
      selects.forEach(a => {
        ids.push(a.id);
      });
      let str = '';
      this.currentCompaniesList.forEach(a => {
        if (a) {
          str += a + ',';
        }
      });
      upUserDepardLimsId({
        ids: JSON.stringify(ids),
        id: str
      }).then(res => {
        this.selectUserDia = false;
        this.$message.success('添加成功');
        this.refreshTable();
        this.$emit('refreshTree')
      });
    },
    // å¯¼å‡ºäººå‘˜ä¿¡æ¯
    handleDown() {
      this.outLoading = true;
      let entity = this.HaveJson(this.entity)
      delete entity.orderBy;
      exportPersonBasicInfo({...entity}).then(res => {
        this.outLoading = false;
        const blob = new Blob([res], {type: 'application/octet-stream'});
        this.$download.saveAs(blob, '人员信息.xlsx')
        this.$message.success('导出成功')
      })
    },
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (newId) {
          this.page.current = 1
          this.refreshTable();
        }
      }
    }
  }
};
</script>
<style scoped>
.search-table {
  padding: 0 16px;
}
.search_thing {
  display: flex;
  align-items: center;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,783 @@
<!-- äººå‘˜åŸ¹è®­ -->
<template>
  <div class="flex_column">
    <div v-if="!editPlanShow && isDepartment">
      <div style="display: flex;justify-content: space-between;">
        <el-form :model="page" ref="page" size="small" :inline="true">
          <el-form-item label="编制人">
            <el-input v-model="page.compilerName" clearable></el-input>
          </el-form-item>
          <el-form-item>
            <el-button size="small" type="primary" @click="getYearPlanList(departId)">查 è¯¢</el-button>
          </el-form-item>
        </el-form>
        <div>
          <el-button size="small" type="primary" @click="uploadDia = true, getUserList()">导入</el-button>
        </div>
      </div>
      <lims-table :tableData="yearPlanTableData" :column="yearPlanColumn"
                  :currentChange="currentChange"
                  @pagination="pagination" :height="'calc(100vh - 290px)'"
                  :page="page" :tableLoading="yearLoading"></lims-table>
    </div>
    <div v-if="!editPlanShow" class="table">
      <div v-if="!editPlanShow && isDepartment">
        <div style="display: flex;justify-content: space-between;">
          <el-form :model="inDetailForm" ref="inDetailForm" size="small" :inline="true">
            <el-form-item label="培训讲师">
              <el-input v-model="inDetailForm.trainingLecturerName" class="search" clearable placeholder="请输入" size="small"></el-input>
            </el-form-item>
            <el-form-item label="培训日期">
              <el-date-picker v-model="inDetailForm.trainingDate" clearable
                              format="yyyy-MM-dd" placeholder="选择日期" size="small"
                              type="date" value-format="yyyy-MM-dd"></el-date-picker>
            </el-form-item>
            <el-form-item>
              <el-button size="small" type="primary" @click="searchTable">查 è¯¢</el-button>
            </el-form-item>
          </el-form>
          <div>
            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" @click="batchDelete">批量删除</el-button>
            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" type="primary" @click="addTrainingPlan('add')">新增</el-button>
          </div>
        </div>
        <lims-table :tableData="inDetailPlanTableData" :column="inDetailPlanColumn"
                    :currentChange="currentChange" :height="isDepartment ? '45vh' : '68vh' "
                    :isSelection="true" :handleSelectionChange="handleSelectionChange"
                    @pagination="pagination1"
                    :page="inDetailPagination" :tableLoading="yearLoading"></lims-table>
      </div>
    </div>
    <Add ref="addPlan" :currentChangeRow="currentChangeRow" @search="getInDetailPlan(currentRowId, departId)"></Add>
    <Edit
      v-if="editPlanShow"
      ref="editPlan"
      :currentRow="currentRow"
      @del="getInDetailPlan(currentRowId, departId)"
      @goBack="goBack"
    ></Edit>
    <el-dialog :visible.sync="reviewDialog" title="审核" width="30%" @close="auditRemarks = ''">
      <span>
        å®¡æ ¸å¤‡æ³¨ï¼š
        <el-input v-model="auditRemarks" type="textarea"></el-input>
      </span>
      <span style="margin-top: 10px;display: inline-block">
        æ‰¹å‡†äººï¼š
        <el-select v-model="approverId" clearable
                   filterable size="small" style="width: 70%;">
          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button :loading="reviewLoading" @click="handleReview(2)">不通过</el-button>
        <el-button :loading="reviewLoading" type="primary" @click="handleReview(1)">通 è¿‡</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="approvalDialog" title="批准" width="30%" @close="approvalRemarks = ''">
      <span>
        æ‰¹å‡†å¤‡æ³¨ï¼š
        <el-input v-model="approvalRemarks" type="textarea"></el-input>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button :loading="approvalLoading" @click="handleApproval(2)">不批准</el-button>
        <el-button :loading="reviewLoading" type="primary" @click="handleApproval(1)">批 å‡†</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="uploadDia" title="数据导入" width="500px">
      <div style="display: flex;align-items: center;">
        <div style="width: 70px">年份:</div>
        <el-date-picker
          v-model="planYear"
          type="year"
          value-format="yyyy"
          clearable
          size="small"
          format="yyyy"
          placeholder="选择年">
        </el-date-picker>
      </div>
      <div style="display: flex;align-items: center;margin: 10px 0">
        <div style="width: 70px">审核人:</div>
        <el-select v-model="reviewerId" clearable
                   filterable size="small" style="width: 50%;">
          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </div>
      <div style="margin: 0 auto;">
        <el-upload ref="upload" :action="javaApi + '/personTraining/personTrainingImport' + '?planYear=' + planYear + '&reviewerId=' + reviewerId"
                   :auto-upload="false" :before-upload="beforeUpload" :file-list="fileList" :headers="uploadHeader"
                   :limit="1" :on-error="onError" :on-success="onSuccess" accept=".xlsx" drag
                   name="file">
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        </el-upload>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="uploadDia = false">取 æ¶ˆ</el-button>
        <el-button :loading="uploading" type="primary" @click="submitUpload()">上 ä¼ </el-button>
      </span>
    </el-dialog >
    <view-record v-if="ViewRecord" ref="ViewRecord"></view-record>
  </div>
</template>
<script>
import Add from '../components/AddInDetail.vue';
import Edit from '../components/Edit.vue';
import ViewRecord from "../components/ViewRecord.vue";
import limsTable from "@/components/Table/lims-table.vue";
import {mapGetters} from "vuex";
import {
  approveAnnualPersonnelTraining, deleteAnnualPlanDetailTable, exportPersonTraining, exportPersonTrainingRecord,
  personTraining,
  personTrainingDelete,
  queryTheAnnualPlanDetailsTable, reviewAnnualPersonnelTraining
} from "@/api/cnas/personal/personalTraining";
import {selectUserCondition} from "@/api/system/user";
export default {
  name: 'PersonnelTraining',
  components: {limsTable, ViewRecord, Add, Edit },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  data() {
    return {
      planYear: '',
      reviewerId: '',
      responsibleOptions: [],
      search: {},
      superviseForm: {},
      inDetailForm: {
        trainingLecturerName: '',
        trainingDate: '',
      },
      yearLoading: false,
      yearPlanTableData: [], // å¹´åº¦è®¡åˆ’表数据
      yearPlanColumn: [
        {
          label: '文件名称',
          width: '160px',
          prop: 'fileName'
        }, {
          label: '创建时间',
          width: '160px',
          prop: 'createTime'
        },{
          label: '编制人',
          prop: 'compilerName'
        }, {
          label: '编制日期',
          width: '160px',
          prop: 'compilationDate'
        }, {
          label: '审核人',
          prop: 'reviewerName',
          minWidth: '100px',
        }, {
          dataType: 'tag',
          label: '审核状态',
          prop: 'reviewerStatus',
          width: '100px',
          formatData: (params) => {
            if (params == 1) {
              return '通过';
            } else if (params == 2) {
              return '不通过';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 1) {
              return 'success';
            } else if (params == 2) {
              return 'danger';
            } else {
              return null
            }
          }
        }, {
          label: '审核备注',
          prop: 'auditRemarks',
          minWidth: '100px',
        }, {
          label: '审核日期',
          width: '160px',
          prop: 'auditDate'
        }, {
          label: '批准人',
          prop: 'approverName',
          minWidth: '100px',
        }, {
          label: '批准备注',
          prop: 'approvalRemarks',
          minWidth: '100px',
        }, {
          dataType: 'tag',
          label: '批准状态',
          minWidth: '100px',
          prop: 'approvalStatus',
          formatData: (params) => {
            if (params == 1) {
              return '批准';
            } else if (params == 2) {
              return '不批准';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 1) {
              return 'success';
            } else if (params == 2)  {
              return 'danger';
            } else {
              return null
            }
          }
        }, {
          label: '批准日期',
          width: '160px',
          prop: 'approvalDate'
        }, {
          dataType: 'action',
          width: '180px',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '导出',
              type: 'text',
              disabled: (row) => {
                if(row.approvalStatus === 1 && row.reviewerStatus === 1) {
                  return false;
                } else {
                  return true;
                }
              },
              clickFun: (row) => {
                this.downLoadPost(row);
              }
            },
            {
              name: '审核',
              type: 'text',
              disabled: (row) => {
                if(row.reviewerStatus === 1 || this.userId != row.reviewerId) {
                  return true;
                } else {
                  return false;
                }
              },
              clickFun: (row) => {
                this.handleCheck(row.id);
              }
            },
            {
              name: '批准',
              type: 'text',
              disabled: (row) => {
                if(row.approvalStatus === 1 || this.userId != row.approverId) {
                  return true;
                } else {
                  return false;
                }
              },
              clickFun: (row) => {
                this.handleApprove(row.id);
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteFun(row.id);
              },
              disabled: (row) => {
                if(row.reviewerStatus === 1) {
                  return true;
                } else {
                  return false;
                }
              },
            }
          ]
        }],
      inDetailPlanTableData: [], // å¹´åº¦è®¡åˆ’明细表表数据
      inDetailPlanColumn: [
       {
          label: '培训目标',
          prop: 'trainingObjectives',
          width: '100px',
        }, {
          label: '培训内容',
          prop: 'trainingContent',
          width: '100px',
        }, {
          label: '培训方式',
          prop: 'trainingMode',
          width: '100px',
        }, {
          dataType: 'tag',
          label: '课程状态',
          width: '100px',
          prop: 'state',
          formatData: (params) => {
            if (params == 1) {
              return '已完成';
            } else if (params == 2) {
              return '待评价';
            } else if (params == 3) {
              return '未开始';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 1) {
              return 'success';
            } else if (params == 2) {
              return 'warning';
            } else if (params == 3) {
              return 'primary';
            } else if (params == 4) {
              return 'info';
            } else {
              return null
            }
          }
        }, {
          label: '参加对象',
          prop: 'participants',
          width: '100px',
        }, {
          label: '举办部门',
          prop: 'holdingDepartment',
          width: '100px',
        }, {
          label: '培训讲师',
          prop: 'trainingLecturerName',
          width: '100px',
        }, {
          label: '培训日期',
          prop: 'trainingDate',
          width: '100px',
        }, {
          label: '开始时间',
          prop: 'openingTime',
          width: '100px',
        }, {
          label: '课时',
          prop: 'classHour',
          width: '100px',
        }, {
          label: '备注',
          prop: 'remarks',
          width: '100px',
        }, {
          dataType: 'action',
          width: '200',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.addTrainingPlan('edit', row);
              },
            },
            {
              name: '结果明细',
              type: 'text',
              clickFun: (row) => {
                this.editInDetail(row);
              },
              showHide: () => {
                if (this.isDepartment) {
                  return true;
                } else {
                  return false;
                }
              }
            },
            {
              name: '附件',
              type: 'text',
              clickFun: (row) => {
                this.viewRecord(row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadInDetail(row);
              }
            },
          ]
        }],
      page: {
        total:0,
        size:10,
        current:1,
        compilerName: ""
      },
      inDetailPagination: {
        total:0,
        size:10,
        current:1,
      },
      editPlanShow: false,
      currentRow: {},
      currentRowId: null, // å½“前选中数据的id
      auditRemarks: '', // å®¡æ ¸å¤‡æ³¨
      reviewDialog: false, // å®¡æ ¸å¼¹æ¡†
      reviewLoading: false, // å®¡æ ¸æäº¤æŒ‰é’®
      approvalRemarks: '', // å®¡æ ¸å¤‡æ³¨
      approvalDialog: false, // å®¡æ ¸å¼¹æ¡†
      approvalLoading: false, // å®¡æ ¸æäº¤æŒ‰é’®
      multipleSelection: [], // å¹´åº¦æ˜Žç»†è¡¨é€‰ä¸­çš„æ•°æ®
      uploadDia: false,
      uploading: false,
      isOperation: false,
      ViewRecord: false,
      fileList: [],
      currentChangeRow: {},
      approverId: ''
    };
  },
  mounted() {
    if (this.isDepartment) {
      this.getYearPlanList(this.departId)
    } else {
      this.getInDetailPlan('', this.departId)
    }
  },
  methods: {
    searchTable () {
      this.getInDetailPlan(this.currentRowId)
    },
    // æŸ¥è¯¢-年度计划表
    getYearPlanList(userId) {
      const params = this.isDepartment ?
      {
        departmentId: userId,
        size: this.page.size,
        current: this.page.current,
        compilerName: this.page.compilerName,
      }: {
          userId: userId,
          size: this.page.size,
          current: this.page.current,
          compilerName: this.page.compilerName,
        }
      personTraining(params).then(res => {
        this.yearPlanTableData = res.data.records;
        this.pagination.total = res.data.total;
        if (this.yearPlanTableData.length > 0) {
          this.currentRowId = this.yearPlanTableData[0].id
          this.currentChange(this.yearPlanTableData[0])
        }
      });
    },
    pagination (page) {
      this.page.size = page.limit
      this.getYearPlanList()
    },
    currentChange (row) {
      const now = new Date();
      const currentYear = now.getFullYear();
      if (row) {
        this.currentChangeRow = row
        this.currentRowId = row.id
        if (row.createTime.slice(0,4) == currentYear) {
          this.isOperation = true;
        } else {
          this.isOperation = false;
        }
        this.getInDetailPlan(row.id)
      }
    },
    getInDetailPlan (id) {
      if (this.inDetailForm.trainingDate === null) {
        this.inDetailForm.trainingDate = ''
      }
      const userId = this.isDepartment ? '' : this.departId
      const params =
        {
          userId: userId,
          size: this.inDetailPagination.pageSize,
          current: this.inDetailPagination.current,
          id: id,
          trainingLecturerName: this.inDetailForm.trainingLecturerName,
          trainingDate: this.inDetailForm.trainingDate,
        }
      queryTheAnnualPlanDetailsTable(params).then(res => {
        this.inDetailPlanTableData = res.data.records;
        this.inDetailPagination.total = res.data.total;
      });
    },
    pagination1 (page) {
      this.inDetailPagination.size = page.limit
      this.getInDetailPlan(this.currentRowId)
    },
    // æ–°å¢žå¹´åº¦è®¡åˆ’明细表
    addTrainingPlan(type, row) {
      if (!this.currentRowId) {
        this.$message.warning('请选择一条计划进行新增')
        return
      }
      this.$refs.addPlan.showDialog(this.currentRowId, type, row);
    },
    // å¹´åº¦è®¡åˆ’表-删除
    deleteFun(id) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        personTrainingDelete({id: id}).then(res => {
          this.$message.success('删除成功!');
          this.getYearPlanList(this.departId);
        });
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // å¹´åº¦è®¡åˆ’表-审核
    handleCheck(id) {
      this.currentRowId = id
      this.reviewDialog = true
      this.getUserList()
    },
    // æäº¤å®¡æ ¸
    handleReview (status) {
      const personTrainingUpdateDto = {
        id: this.currentRowId,
        auditRemarks: this.auditRemarks,
        reviewerStatus: status,
        approverId: this.approverId
      }
      this.reviewLoading = true
      reviewAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
        if (res.code === 200) {
          this.$message.success('提交成功!');
          this.reviewDialog = false
          this.getYearPlanList(this.departId);
        }
        this.reviewLoading = false
      }).catch(() => {
        this.reviewLoading = false
      })
    },
    // å¹´åº¦è®¡åˆ’表-批准
    handleApprove(id) {
      this.currentRowId = id
      this.approvalDialog = true
    },
    // æäº¤æ‰¹å‡†
    handleApproval (status) {
      const personTrainingUpdateDto = {
        id: this.currentRowId,
        approvalRemarks: this.approvalRemarks,
        approvalStatus: status
      }
      this.approvalLoading = true
      approveAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
        if (res.code === 200) {
          this.$message.success('提交成功!');
          this.approvalDialog = false
          this.getYearPlanList(this.departId);
        }
        this.approvalLoading = false
      }).catch(() => {
        this.approvalLoading = false
      })
    },
    // å¹´åº¦è®¡åˆ’表-下载
    downLoadPost(row) {
      exportPersonTraining({id: row.id}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, row.fileName + '.docx')
        this.$message.success('导出成功')
      })
    },
    // å¹´åº¦è®¡åˆ’-导入
    submitUpload() {
      if (this.$refs.upload.uploadFiles.length == 0) {
        this.$message.error('未选择文件')
        return
      }
      this.uploading = true
      this.$refs.upload.submit();
      this.uploading = false
    },
    onSuccess(response, file, fileList) {
      this.$refs.upload.clearFiles()
      this.uploadDia = false
      this.uploading = false
      if (response.code != 200) {
        this.$message.error(response.message)
        return
      }
      this.$message.success('上传成功')
      this.standardList = []
      this.productList = []
      this.getYearPlanList(this.departId)
    },
    onError(err, file, fileList) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
      this.uploading = false
    },
    beforeUpload(file, fileList) {
      if (file.type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
        this.$message.error('上传文件格式不正确');
        this.$refs.upload.clearFiles()
        return false;
      }
    },
    // å¹´åº¦è®¡åˆ’明细表-编辑
    editInDetail(row) {
      this.editPlanShow = true;
      this.currentRow = row
    },
    //
    goBack() {
      this.editPlanShow = false;
      this.getInDetailPlan(this.currentRowId)
    },
    viewRecord (row) {
      this.ViewRecord = true
      this.$nextTick(() => {
        this.$refs.ViewRecord.openDia(row)
      })
    },
    // å¹´åº¦è®¡åˆ’明细表-下载
    downLoadInDetail(row) {
      exportPersonTrainingRecord({id: row.id}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '人员培训与考核记录.docx')
        this.$message.success('导出成功')
      })
    },
    // å¹´åº¦è®¡åˆ’明细表-多选
    handleSelectionChange(list) {
      this.multipleSelection = list
    },
    // å¹´åº¦æ˜Žç»†è¡¨-删除
    batchDelete () {
      if (this.multipleSelection.length > 0) {
        let ids = []
        this.multipleSelection.forEach(item => {
          ids.push(item.id)
        })
        this.$confirm('是否确认删除所选择的数据?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          deleteAnnualPlanDetailTable({ids: ids.join(',')}).then(res => {
            if (res.code == 200) {
              this.$message.success('删除成功');
              this.getInDetailPlan(this.currentRowId);
            }
          });
        }).catch(() => {
          this.$message.warning('取消删除');
        });
      } else {
        this.$message.warning('请选择需要删除的数据')
      }
    },
    handleSizeChange(val) {
      this.inDetailPagination.size = val;
      this.getInDetailPlan(this.currentChangeRow.id)
    },
    handleCurrentChange(val) {
      this.inDetailPagination.current = val;
      this.getInDetailPlan(this.currentChangeRow.id)
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      selectUserCondition().then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      });
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    departId: {
      handler(newId, oldId) {
        if (this.isDepartment) {
          this.getYearPlanList(newId);
        } else {
          this.getInDetailPlan('')
        }
      }
    },
    currentRowId: {
      handler(newId, oldId) {
        if (newId) {
          console.log('newId', newId);
          this.inDetailPagination.current = 1
          this.getInDetailPlan(this.currentChangeRow.id)
        }
      }
    }
  }
}
</script>
<style scoped>
.flex_column {
  display: flex;
  height: 80vh;
  flex-direction: column;
  overflow: auto;
  justify-content: space-between;
}
.pagination {
  display: flex;
  justify-content: space-between
}
.items_center {
  display: flex;
  align-items: center;
}
.date_box {
  margin: 0 5px;
}
.search {
  width: 150px;
  margin: 0 16px;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,358 @@
<!-- å¥–惩记录 -->
<template>
  <div>
    <div style="text-align: left; margin-bottom: 15px;">
      <label>姓名</label>
      <el-input v-model="search.userName" clearable placeholder="请输入关键字" size="small" style="width: 20vh;"></el-input>
      <label style="margin-left: 1em">奖惩日期</label>
      <el-date-picker
        v-model="search.searchTimeList"
        :picker-options="pickerOptions"
        align="right"
        clearable
        end-placeholder="结束日期"
        format="yyyy-MM-dd"
        range-separator="至"
        size="small"
        start-placeholder="开始日期"
        style="width: 20%"
        type="daterange"
        unlink-panels
        value-format="yyyy-MM-dd 00:00:00">
      </el-date-picker>
      <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">查询</el-button>
      <div style="float: right;">
        <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">导出</el-button>
        <el-button size="small" type="primary" @click="addRow">新增</el-button>
      </div>
    </div>
    <div class="table">
      <el-table :data="tableData" height="70vh" style="width: 100%">
        <el-table-column label="序号" type="index" width="120">
          <template v-slot="scope">
            <span>{{ (search.current - 1) * search.size + scope.$index + 1 }}</span>
          </template>
        </el-table-column>
        <el-table-column label="员工编号" min-width="180" prop="account">
        </el-table-column>
        <el-table-column label="姓名" min-width="180" prop="userName">
        </el-table-column>
        <el-table-column label="奖惩级别" min-width="180" prop="rewardPunishLevel">
        </el-table-column>
        <el-table-column label="奖惩时间" min-width="180" prop="rewardPunishTime">
        </el-table-column>
        <el-table-column label="奖惩名称" min-width="180" prop="rewardPunishName">
        </el-table-column>
        <el-table-column label="奖惩具体内容" min-width="120" prop="rewardPunishContent">
        </el-table-column>
        <el-table-column label="奖惩单位" min-width="180" prop="rewardPunishWorkUnit">
        </el-table-column>
        <el-table-column label="创建人" min-width="180" prop="createUserName">
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="100">
          <template v-slot="scope">
            <el-button size="small" type="text" @click="editForm(scope.row)">编辑</el-button>
            <el-button size="small" type="text" @click="deleteRow(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]"
                     :total="search.total" layout="->,total, sizes, prev, pager, next, jumper"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <el-dialog
      :visible.sync="dialogVisible"
      title="提示"
      width="50%"
      @open="getUserList">
      <div style="height: 40vh">
        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
          <el-col :span="12">
            <el-form-item label="员工编号">
              <el-input v-model="form.account" disabled size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="员工姓名" prop="userId">
              <el-select v-model="form.userId" placeholder="请选择" size="small" style="width: 100%" value-key="id"
                         @change="selectUserChange" :disabled="!isDepartment">
                <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩级别" prop="rewardPunishLevel">
              <el-input v-model="form.rewardPunishLevel" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩名称" prop="rewardPunishName">
              <el-input v-model="form.rewardPunishName" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩时间" prop="rewardPunishTime">
              <el-date-picker
                v-model="form.rewardPunishTime"
                format="yyyy-MM-dd HH:mm:ss"
                placeholder="选择日期"
                size="small"
                style="width: 100%"
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss">
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩单位" prop="rewardPunishWorkUnit">
              <el-input v-model="form.rewardPunishWorkUnit" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="奖惩内容">
              <el-input v-model="form.rewardPunishContent" :rows="2" size="small" type="textarea"></el-input>
            </el-form-item>
          </el-col>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
    <el-button type="primary" @click="saveOrUpdate">ç¡® å®š</el-button>
  </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      tableData: [],
      search: {
        size: 20,
        current: 1,
        total: 0,
        userName: '',
        searchTimeList: []
      },
      form: {},
      dialogVisible: false,
      outLoading: false,
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
            picker.$emit('pick', [start, end]);
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
            picker.$emit('pick', [start, end]);
          }
        }, {
          text: '最近三个月',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
            picker.$emit('pick', [start, end]);
          }
        }]
      },
      rules: {
        userId: [{
          required: true, message: '请选择员工', trigger: 'change'
        }],
        rewardPunishLevel: [{
          required: true, message: '请输入奖惩级别', trigger: 'blur'
        }],
        rewardPunishName: [{
          required: true, message: '请输入奖惩名称', trigger: 'blur'
        }],
        rewardPunishTime: [{
          required: true, message: '请输入奖惩时间', trigger: 'blur'
        }],
        rewardPunishWorkUnit: [{
          required: true, message: '请输入奖惩单位', trigger: 'blur'
        }]
      },
      responsibleOptions: []
    };
  },
  mounted() {
    this.getPersonnelTraining(this.departId);
  },
  methods: {
    handleSizeChange(val) {
      this.search.size = val
      this.getPersonnelTraining(this.departId);
    },
    handleCurrentChange(val) {
      this.search.current = val
      this.getPersonnelTraining(this.departId);
    },
    async getPersonnelTraining() {
      const {code, data} = await this.$axios({
        method: 'get',
        url: rewardPunishmentPageApi,
        params: {
          userId: this.isDepartment ? '' : this.departId,
          departmentId: this.isDepartment ? this.departId : '',
          current: this.search.curent,
          size: this.search.size,
          userName: this.search.userName,
          startTime: this.search.searchTimeList && this.search.searchTimeList[0],
          endTime: this.search.searchTimeList && this.search.searchTimeList[1],
        }
      })
      if (code == 200) {
        this.tableData = data.records
        this.search.total = data.total
      }
    },
    addRow () {
      this.dialogVisible = true
      if (!this.isDepartment) {
        this.form.userId = this.departId
        this.selectUserChange(this.form.userId)
      }
    },
    handleDown(){
      this.outLoading = true
      this.$axios.post(this.$api.deviceCheck.rewardPunishmentExport,{
        userId: this.isDepartment ? '' : this.departId,
        departmentId: this.isDepartment ? this.departId : '',
        userName: this.search.userName,
        startTime: this.search.searchTimeList && this.search.searchTimeList[0],
        endTime: this.search.searchTimeList && this.search.searchTimeList[1]
      },{responseType: 'blob'}).then(res => {
        this.outLoading = false
        const blob = new Blob([res], {
          type: 'application/force-download'
        })
        //将Blob å¯¹è±¡è½¬æ¢æˆå­—符串
        let reader = new FileReader();
        reader.readAsText(blob, 'utf-8');
        reader.onload = () => {
          try {
            let result = JSON.parse(reader.result);
            if (result.message) {
              this.$message.error(result.message);
            } else {
              // åˆ›å»ºä¸€ä¸ªè¶…链接,将文件流赋进去,然后实现这个超链接的单击事件
              const elink = document.createElement('a')
              elink.download = decodeURI('奖惩记录'+'.xlsx')
              elink.style.display = 'none'
              elink.href = URL.createObjectURL(blob)
              document.body.appendChild(elink)
              elink.click();
              URL.revokeObjectURL(elink.href) // é‡Šæ”¾URL å¯¹è±¡
              document.body.removeChild(elink)
              this.$message.success('导出成功')
            }
          } catch (err) {
            console.log(err);
            // åˆ›å»ºä¸€ä¸ªè¶…链接,将文件流赋进去,然后实现这个超链接的单击事件
            const elink = document.createElement('a')
            elink.download = decodeURI('奖惩记录'+'.xlsx')
            elink.style.display = 'none'
            elink.href = URL.createObjectURL(blob)
            document.body.appendChild(elink)
            elink.click();
            URL.revokeObjectURL(elink.href) // é‡Šæ”¾URL å¯¹è±¡
            document.body.removeChild(elink)
            this.$message.success('导出成功')
          }
        }
      })
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      this.$axios.get(this.$api.deviceScope.selectUserList).then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      })
    },
    selectUserChange(val) {
      const index = this.responsibleOptions.findIndex(item => item.id === val)
      if (index > -1) {
        this.form.userName = this.responsibleOptions[index].name
        this.form.account = this.responsibleOptions[index].account
      }
    },
    editForm(row) {
      this.dialogVisible = true
      this.form = {...row};
    },
    saveOrUpdate() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          this.dialogVisible = false
          const {code, data} = await this.$axios({
            method: 'post',
            url: addOrUpdateRewardPunishmentApi,
            data: this.form,
            headers: {
              'Content-Type': 'application/json'
            },
            noQs: true
          })
          if (code == 200) {
            this.$message.success("操作成功!")
            this.getPersonnelTraining(this.departId);
          }
        }
      })
    },
    async deleteRow(row) {
      const {code, data} = await this.$axios({
        method: 'delete',
        url: deleteRewardPunishmentApi,
        params: {
          id: row.id
        }
      })
      if (code == 200) {
        this.$message.success("操作成功!")
        this.getPersonnelTraining(this.departId);
      }
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    departId: {
      handler(newId, oldId) {
        this.getPersonnelTraining(newId);
      }
    },
    dialogVisible(newVal) {
      if (newVal === false) {
        this.form = {}
        this.$refs['form'].resetFields()
      }
    }
  }
};
</script>
src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,336 @@
<!-- åŸ¹è®­è®°å½• -->
<template>
  <div>
    <div class="flex_table">
      <div v-if="isDepartment" style="width: 50%">
<!--        <TableCard :showTitle="false">-->
<!--          <template v-slot:form>-->
<!--            <div class="items_center">-->
<!--              <span>姓名</span>-->
<!--              <el-input v-model="trainingPagination.userName" class="search" clearable placeholder="请输入" size="small"></el-input>-->
<!--              <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">查询</el-button>-->
<!--            </div>-->
<!--            <div>-->
<!--&lt;!&ndash;              <el-button :loading="outLoading" size="small" type="primary" @click="exportExcel">导出</el-button>&ndash;&gt;-->
<!--            </div>-->
<!--          </template>-->
<!--          <template v-slot:table>-->
<!--            <ZTTable-->
<!--              :column="trainingColumn"-->
<!--              :currentChange="currentChange"-->
<!--              :height="'calc(100vh - 18em)'"-->
<!--              :highlightCurrentRow="true"-->
<!--              :table-data="trainingTableData"-->
<!--              :table-loading="trainingLoading"-->
<!--              style="padding: 0 15px;">-->
<!--            </ZTTable>-->
<!--            <div class="pagination">-->
<!--              <div></div>-->
<!--              <el-pagination-->
<!--                :page-size="trainingPagination.size"-->
<!--                :page-sizes="[10, 20, 30, 40]"-->
<!--                :total="trainingPagination.total"-->
<!--                layout="total, sizes, prev, pager, next, jumper"-->
<!--                @current-change="handleYearCurrentTraining"-->
<!--                @size-change="handleYearSizeChangeTraining">-->
<!--              </el-pagination>-->
<!--            </div>-->
<!--          </template>-->
<!--        </TableCard>-->
<!--      </div>-->
<!--      <div :style="`width: ${isDepartment ? '50%' : '100%'};`">-->
<!--        <TableCard :showTitle="false">-->
<!--          <template v-slot:form>-->
<!--            <div class="items_center">-->
<!--              <span>年份</span>-->
<!--              <el-date-picker-->
<!--                v-model="searchForm.trainingDate"-->
<!--                clearable-->
<!--                format="yyyy"-->
<!--                placeholder="选择年"-->
<!--                size="small"-->
<!--                style="margin: 0 10px"-->
<!--                type="year"-->
<!--                value-format="yyyy">-->
<!--              </el-date-picker>-->
<!--              <el-button size="small" type="primary" @click="queryPersonnelDetailsPage(currentChangeRow.userId)">查询</el-button>-->
<!--              <el-button size="small" type="primary" @click="openDownloadDia(currentChangeRow)">导出</el-button>-->
<!--            </div>-->
<!--          </template>-->
<!--          <template v-slot:table>-->
<!--            <ZTTable-->
<!--              :column="trainingPersonColumn"-->
<!--              :height="'calc(100vh - 18em)'"-->
<!--              :table-data="trainingPersonTableData"-->
<!--              :table-loading="trainingPersonLoading"-->
<!--              style="padding: 0 15px;">-->
<!--            </ZTTable>-->
<!--            <div class="pagination">-->
<!--              <div></div>-->
<!--              <el-pagination-->
<!--                :page-size="trainingPersonPagination.size"-->
<!--                :page-sizes="[10, 20, 30, 40]"-->
<!--                :total="trainingPersonPagination.total"-->
<!--                layout="total, sizes, prev, pager, next, jumper"-->
<!--                @current-change="handleYearCurrentPagination"-->
<!--                @size-change="handleYearSizeChangePagination">-->
<!--              </el-pagination>-->
<!--            </div>-->
<!--          </template>-->
<!--        </TableCard>-->
      </div>
    </div>
  </div>
</template>
<script>
export default {
  components: {},
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      outLoading: false,
      trainingForm: {},
      trainingColumn: [
        {
          label: '员工编号',
          prop: 'account',
          width: '100'
        }, {
          label: '姓名',
          prop: 'name'
        }, {
          label: '所在部门',
          prop: 'departLimsName',
          width: '150'
        }, {
          label: '职称',
          prop: 'professionalTitle'
        }, {
          label: '最高学历',
          prop: 'officialAcademicRedentials',
          width: '100'
        }, {
          label: '入单位时间',
          prop: 'unitTime',
          width: '150'
        },
        // {
        //   fixed: 'right',
        //   dataType: 'action',
        //   width: 80,
        //   label: '操作',
        //   operation: [
        //     {
        //       name: '导出',
        //       type: 'text',
        //       clickFun: (row) => {
        //         this.openDownloadDia(row)
        //       }
        //     }
        //   ]
        // }
      ],
      trainingTableData: [],
      trainingLoading: false,
      trainingPagination: {
        size: 20,
        total: 0,
        current: 1,
        userName: null
      },
      searchForm: {
        trainingDate: ''
      },
      trainingPersonColumn: [
        {
          label: '培训日期',
          prop: 'trainingDate'
        }, {
          label: '培训内容',
          prop: 'trainingContent'
        }, {
          label: '培训课时',
          prop: 'educationBackground'
        }, {
          label: '课时',
          prop: 'classHour'
        }, {
          label: '培训结果',
          prop: 'examinationResults',
        }, {
          label: '备注',
          prop: 'remarks'
        }
      ],
      trainingPersonTableData: [],
      trainingPersonLoading: false,
      trainingPersonPagination: {
        size: 20,
        current: 1,
        total: 0
      },
      currentChangeRow: '',
    };
  },
  mounted() {
    this.getPersonnelTraining(this.departId);
  },
  methods: {
    // exportExcel() {
    //   this.outLoading = true;
    //   const name = this.isDepartment ? 'departmentId' : 'userId';
    //   this.$axios.get(this.$api.personal.personTrackRecordExport + `&${name}=` + this.departId, { responseType: 'blob' }).then(res => {
    //     this.outLoading = false;
    //     this.$message.success('导出成功');
    //     const blob = new Blob([res], { type: 'application/octet-stream' });
    //     const url = URL.createObjectURL(blob);
    //     const link = document.createElement('a');
    //     link.href = url;
    //     link.download = '培训记录.xlsx';
    //     link.click();
    //   }).catch(err => {
    //     this.outLoading = false;
    //   })
    // },
    // æŸ¥è¯¢
    refreshTable() {
      this.getPersonnelTraining(this.departId);
    },
    // åŸ¹è®­è®°å½•导出
    openDownloadDia (row) {
      let date = this.searchForm.trainingDate
      if (!date) {
        date = this.$moment().format('YYYY')
      }
      console.log('date----', date);
      this.$axios.get( this.$api.personnel.exportTrainingRecord+ '?userId=' + row.userId + '&trainingDate=' + date,{responseType: "blob"}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        //将Blob å¯¹è±¡è½¬æ¢æˆå­—符串
        let reader = new FileReader();
        reader.readAsText(blob, 'utf-8');
        reader.onload = () => {
          try {
            let result = JSON.parse(reader.result);
            if (result.message) {
              this.$message.error(result.message);
            } else {
              const url = URL.createObjectURL(blob);
              const link = document.createElement('a');
              link.href = url;
              link.download = '培训记录导出' + '.docx';
              link.click();
              this.$message.success('导出成功')
            }
          } catch (err) {
            console.log(err);
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = '培训记录导出' + '.docx';
            link.click();
            this.$message.success('导出成功')
          }
        }
      })
    },
    // èŽ·å–å®žéªŒå®¤-培训计划列表信息
    getPersonnelTraining(departId) {
      // const name = this.isDepartment ? 'departmentId' : 'userId';
      this.$axios.get(`${this.$api.personnel.trainingSelectTrainingRecord}?departmentId=${departId}&size=${this.trainingPagination.size}&current=${this.trainingPagination.current}&userName=${this.trainingPagination.userName}`).then(res => {
        this.trainingTableData = res.data.records;
        this.trainingPagination.total = res.data.total;
        if (this.trainingTableData.length > 0) {
          this.currentChange(this.trainingTableData[0]);
        }
      });
    },
    // èŽ·å–ä¸ªäºº-培训计划列表信息
    currentChange(row) {
      this.currentChangeRow = row
      if (row === null) {
        row = this.trainingTableData[0]
      }
      this.queryPersonnelDetailsPage(row.userId)
    },
    queryPersonnelDetailsPage(userId) {
      if (this.searchForm.trainingDate === null) {
        this.searchForm.trainingDate = ''
      }
      this.$axios.get(`${this.$api.personnel.queryPersonnelDetails}?userId=${userId}&size=${this.trainingPersonPagination.size}&current=${this.trainingPersonPagination.current}&trainingDate=${this.searchForm.trainingDate}`).then(res => {
        this.trainingPersonTableData = res.data.records;
        this.trainingPersonPagination.total = res.data.total;
      });
    },
    // åˆ†é¡µ
    handleYearCurrentTraining(page) {
      this.trainingPagination.curent = page;
      this.getPersonnelTraining(this.departId);
    },
    handleYearSizeChangeTraining(size) {
      this.trainingPagination.size = size;
      this.getPersonnelTraining(this.departId);
    },
    // åˆ†é¡µ
    handleYearCurrentPagination(page) {
      this.trainingPersonPagination.curent = page;
      this.queryPersonnelDetailsPage(this.currentChangeRow.userId);
    },
    handleYearSizeChangePagination(size) {
      this.trainingPersonPagination.size = size;
      this.queryPersonnelDetailsPage(this.currentChangeRow.userId);
    }
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (this.isDepartment) {
          this.getPersonnelTraining(newId);
        } else {
          this.queryPersonnelDetailsPage(newId)
        }
      }
    }
  }
};
</script>
<style scoped>
>>> .el-form-item {
  margin-bottom: 13px;
}
.flex_table {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
.pagination {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
}
.items_center {
  display: flex;
  align-items: center;
}
.search {
  width: 150px;
  padding: 0 6px;
}
</style>