licp
2024-12-23 f18c78c262089284bf6099b3fc37c61cdfb4cfaf
完成人员迁移
已修改6个文件
已添加12个文件
5324 ■■■■■ 文件已修改
src/assets/api/controller.js 150 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel-collect/personnel-list.vue 388 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel-training/AddInDetail.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel-training/Edit.vue 448 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel-training/index.vue 794 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel/job-responsibilities.vue 374 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel/personnel-capacity.vue 579 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel/personnel-information.vue 948 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel/personnel-supervision.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel/reward-punishment-record.vue 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel/track-record.vue 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a6-personnel/training-record.vue 319 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/do/a8-file-handling/FileChangeRequest.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/view/a6-personnel.vue 324 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/view/a7-Ensure-results-validity.vue 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/view/a7-changes-standard-methods.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/view/a7-method-verification.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/api/controller.js
@@ -70,6 +70,8 @@
    feCalibrationSchedule,
    feStandardSubstance,
    feStandardSubstanceRecord,
    personPostAuthorizationRecord,
    deviceCheck,
  }
}
@@ -179,28 +181,31 @@
}
const deviceScope = {
  selectDeviceParameter: "/deviceScope/selectDeviceParameter", //查询设备详情列表
  addDeviceParameter: "/deviceScope/addDeviceParameter", //添加设备详情参数
  delDeviceParameter: "/deviceScope/delDeviceParameter", //删除设备详情参数
  upDeviceParameter: "/deviceScope/upDeviceParameter", //修改设备详情参数
  selectDeviceByCategory: "/deviceScope/selectDeviceByCategory", //通过设备分类获取设备列表
  authorizedPerson: "/user/getDeviceManager", //获取授权人
  selectEquipmentOverview: "/deviceScope/selectEquipmentOverview", //获取设备总览
  uploadFile: "/deviceScope/uploadFile", //上传图片
  selectDevicePrincipal: "/user/getDeviceManager", //获取设备负责人
  selectDeviceByCode: "/deviceScope/selectDeviceByCode", //通过设备编号获取设备列表
  getNumberCollect: "/deviceScope/getNumberCollect", //查询数采配置
  numberCollect: "/deviceScope/numberCollect", //维护数采配置
  saveDataAcquisitionConfiguration: "/deviceScope/saveDataAcquisitionConfiguration", // ç»´æŠ¤æ•°é‡‡é…ç½®
  queryDataAcquisitionConfiguration: "/deviceScope/queryDataAcquisitionConfiguration", // æŸ¥è¯¢æ•°é‡‡é…ç½®
  deleteDataAcquisitionConfiguration: "/deviceScope/deleteDataAcquisitionConfiguration", // åˆ é™¤æ•°é‡‡é…ç½®
  determineWhetherToCollectData: "/deviceScope/determineWhetherToCollectData", // åˆ¤æ–­è¯¥è®¾å¤‡æ˜¯å¦å¯ä»¥æ•°é‡‡
  dataCollection: "/deviceScope/dataCollection", // æ•°é‡‡-数据采集
  treeDevice: "/deviceScope/treeDevice", // è®¾å¤‡æ ‘å½¢
  temDataAcquisition: "/deviceScope/temDataAcquisition", // PK8000数采
  temDataAcquisition2: "/deviceScope/temDataAcquisition2", // PK8000数采--多条
  formulaCalculation: "/deviceScope/formulaCalculation", // æ•°é‡‡-公式计算
  selectUserList: '/deviceScope/selectUserList', //获取用户列表
  selectDeviceParameter: '/deviceScope/selectDeviceParameter', //查询设备详情列表
  addDeviceParameter: '/deviceScope/addDeviceParameter', //添加设备详情参数
  delDeviceParameter: '/deviceScope/delDeviceParameter', //删除设备详情参数
  upDeviceParameter: '/deviceScope/upDeviceParameter', //修改设备详情参数
  selectDeviceByCategory: '/deviceScope/selectDeviceByCategory', //通过设备分类获取设备列表
  deviceScopeSearch: "/deviceScope/search", //通过设备分类获取设备列表
  authorizedPerson: '/user/getDeviceManager', //获取授权人
  selectEquipmentOverview: '/deviceScope/selectEquipmentOverview', //获取设备总览
  uploadFile: '/deviceScope/uploadFile', //上传图片
  selectDevicePrincipal: '/user/getDeviceManager', //获取设备负责人
  selectDeviceByCode: '/deviceScope/selectDeviceByCode', //通过设备编号获取设备列表
  getNumberCollect: '/deviceScope/getNumberCollect', //查询数采配置
  numberCollect: '/deviceScope/numberCollect', //维护数采配置
  saveDataAcquisitionConfiguration: '/deviceScope/saveDataAcquisitionConfiguration', // ç»´æŠ¤æ•°é‡‡é…ç½®
  queryDataAcquisitionConfiguration: '/deviceScope/queryDataAcquisitionConfiguration', // æŸ¥è¯¢æ•°é‡‡é…ç½®
  deleteDataAcquisitionConfiguration: '/deviceScope/deleteDataAcquisitionConfiguration', // åˆ é™¤æ•°é‡‡é…ç½®
  determineWhetherToCollectData: '/deviceScope/determineWhetherToCollectData', // åˆ¤æ–­è¯¥è®¾å¤‡æ˜¯å¦å¯ä»¥æ•°é‡‡
  dataCollection: '/deviceScope/dataCollection', // æ•°é‡‡-数据采集
  treeDevice: '/deviceScope/treeDevice', // è®¾å¤‡æ ‘å½¢
  temDataAcquisition: '/deviceScope/temDataAcquisition', // PK8000数采
  temDataAcquisition2: '/deviceScope/temDataAcquisition2', // PK8000数采--多条
  formulaCalculation: '/deviceScope/formulaCalculation', // æ•°é‡‡-公式计算
  formulaCalculation2: '/deviceScope/export', //导出
  selectListBylargeCategory: '/deviceScope/largeCategory'
}
const insOrder = {
@@ -578,7 +583,55 @@
// 6.2 äººå‘˜
const personnel = {
  selectCNSAPersonTree: '/personBasicInfo/selectCNSAPersonTree', // æŸ¥è¯¢CNAS人员侧边栏
  getAnnex: '/personBasicInfo/getAnnex', // èŽ·å–é™„ä»¶
  basicInformationOfPersonnelSelectPage: 'personBasicInfo/basicInformationOfPersonnelSelectPage', // èŽ·å–äººå‘˜åˆ—è¡¨
  getAnnexByUserId: '/personBasicInfo/getAnnexByUserId',
  addAnnex: '/personBasicInfo/addAnnex', // æ·»åР附件
  deleteAnnex: '/personBasicInfo/deleteAnnex', // åˆ é™¤é™„ä»¶
  updateAnnex: '/personBasicInfo/updateAnnex', // æ›´æ–°é™„ä»¶
  getCNASFile: '/personBasicInfo/getCNASFile', // èŽ·å–å›¾ç‰‡
  getCNASInformation: '/personBasicInfo/getCNASInformation', // æŸ¥è¯¢CNAS人员信息
  updateCNASInformation: '/personBasicInfo/updateCNASInformation', // æ›´æ–°CNAS人员信息
  getCNASPersonnelInfo: '/personBasicInfo/getCNASPersonnelInfo', // äººå‘˜åŸºæœ¬ä¿¡æ¯æŸ¥è¯¢
  saveCNASPersonnelInfo: '/personBasicInfo/saveCNASPersonnelInfo', // äººå‘˜åŸºæœ¬ä¿¡æ¯ä¿å­˜
  saveCNASFile: '/personBasicInfo/saveCNASFile', // å…¬å…±æ–‡ä»¶ä¿å­˜æŽ¥å£
  deleteCNASFile: '/personBasicInfo/deleteCNASFile', // åˆ é™¤æ–‡ä»¶
  personTrainingSelect: '/personTraining/personTrainingSelect', // æŸ¥è¯¢äººå‘˜åŸ¹è®­
  personTrainingDelete: '/personTraining/personTrainingDelete', // åˆ é™¤äººå‘˜åŸ¹è®­ä¿¡æ¯
  approveAnnualPersonnelTraining: '/personTraining/approveAnnualPersonnelTraining', // æ‰¹å‡† å¹´åº¦äººå‘˜åŸ¹è®­
  reviewAnnualPersonnelTraining: '/personTraining/reviewAnnualPersonnelTraining', // å®¡æ ¸ å¹´åº¦äººå‘˜åŸ¹è®­
  personTrainingImport: '/personTraining/personTrainingImport', // å¯¼å…¥ äººå‘˜åŸ¹è®­
  exportPersonTraining: "/personTraining/exportPersonTraining", // å¯¼å‡º/人员培训
  queryTheAnnualPlanDetailsTable: '/personTraining/queryTheAnnualPlanDetailsTable', // æŸ¥è¯¢åŸ¹è®­è®¡åˆ’年度计划明细表
  addOrUpdatePersonTrainingDetailed: '/personTraining/addOrUpdatePersonTrainingDetailed', // æ–°å¢žåŸ¹è®­è®¡åˆ’年度计划明细表
  deleteAnnualPlanDetailTable: '/personTraining/deleteAnnualPlanDetailTable', // æ‰¹é‡åˆ é™¤ å¹´åº¦è®¡åˆ’明细表
  trainingAndAssessmentRecordsPage: '/personTraining/trainingAndAssessmentRecordsPage', // åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æŸ¥è¯¢
  deleteTrainingAndAssessmentRecords: '/personTraining/deleteTrainingAndAssessmentRecords', // åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æ‰¹é‡åˆ é™¤
  trainingAndAssessmentRecordsAdded: '/personTraining/trainingAndAssessmentRecordsAdded', // åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æäº¤
  personJobResponsibilitiesSave: '/personJobResponsibilities/personJobResponsibilitiesSave', // æ–°å¢žå²—位职责
  personJobResponsibilitiesDelete: '/personJobResponsibilities/personJobResponsibilitiesDelete', // åˆ é™¤å²—位职责
  personJobResponsibilitiesUpdate: '/personJobResponsibilities/personJobResponsibilitiesUpdate', // æ›´æ–°å²—位职责
  personJobResponsibilitiesSelect: '/personJobResponsibilities/personJobResponsibilitiesSelect', // åˆ†é¡µæŸ¥è¯¢å²—位职责
  personJobResponsibilitiesExport: '/personJobResponsibilities/personJobResponsibilitiesExport', // å¯¼å‡ºå²—位职责
  personTrackRecordSave: '/personTrackRecord/personTrackRecordSave', // æ–°å¢žå·¥ä½œå±¥åކ
  personTrackRecordDelete: '/personTrackRecord/personTrackRecordDelete', // åˆ é™¤å·¥ä½œå±¥åކ
  personTrackRecordUpdate: '/personTrackRecord/personTrackRecordUpdate', // æ›´æ–°å·¥ä½œå±¥åކ
  personTrackRecordSelect: '/personTrackRecord/personTrackRecordSelect', // æŸ¥è¯¢å·¥ä½œå±¥åކ
  personTrackRecordExport: '/personTrackRecord/personTrackRecordExport', // å¯¼å‡ºå·¥ä½œå±¥åކ
  personTrainingRecordSelect: '/personTrainingRecord/personTrainingRecordSelect', // æŸ¥è¯¢åŸ¹è®­è®°å½•
  personTrainingRecordExport: '/personTrainingRecord/personTrainingRecordExport', // å·¥ä½œåŸ¹è®­è®°å½•
  personPersonnelCapacityPage: '/personPersonnelCapacity/personPersonnelCapacityPage', // æŸ¥è¯¢äººå‘˜èƒ½åŠ›
  deletePersonPersonnelCapacity: '/personPersonnelCapacity/deletePersonPersonnelCapacity', // åˆ é™¤äººå‘˜èƒ½åŠ›
  addOrUpdatePersonPersonnelCapacity: '/personPersonnelCapacity/addOrUpdatePersonPersonnelCapacity', // æ–°å¢žç¼–辑人员能力
  exportPersonnelCapacity: '/personPersonnelCapacity/exportPersonnelCapacity', // å¯¼å‡ºäººå‘˜èƒ½åŠ›
  newPersonnelAddedToTrainingRecords: "/personTraining/newPersonnelAddedToTrainingRecords", // åŸ¹è®­ä¸Žè€ƒæ ¸ æ–°å¢žäººå‘˜
  outOfFocusPreservation: "/personTraining/outOfFocusPreservation", // åŸ¹è®­ä¸Žè€ƒæ ¸ å¤±ç„¦æ›´æ–°
  trainingSelectTrainingRecord: "/personTrainingRecord/trainingSelectTrainingRecord", // æŸ¥è¯¢äººå‘˜ åŸ¹è®­è®°å½•
  queryPersonnelDetails: "/personTrainingRecord/queryPersonnelDetails", // æŸ¥è¯¢äººå‘˜æ˜Žç»† åŸ¹è®­è®°å½•
  claimOfTrainingAndAssessmentRecords: "/personTraining/claimOfTrainingAndAssessmentRecords", // è®¤é¢†/取消认领
  exportPersonTrainingRecord: "/personTraining/exportPersonTrainingRecord", // å¯¼å‡ºäººå‘˜åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½•
  exportTrainingRecord: "/personTrainingRecord/exportTrainingRecord", // å¯¼å‡ºåŸ¹è®­è®°å½•
  confirmPersonnelCapability: "/personPersonnelCapacity/confirmPersonnelCapability", // ç¡®è®¤äººå‘˜èƒ½åŠ›
}
// 8.3 å®¢æˆ·æ»¡æ„åº¦è°ƒæŸ¥
@@ -739,6 +792,7 @@
  getVerifyMethodFileList:'/processMethodVerify/getVerifyMethodFileList', // åŽŸå§‹è®°å½•åˆ—è¡¨
  delVerifyMethodFileList:'/processMethodVerify/delVerifyMethodFileList', // åˆ é™¤éªŒè¯åŽŸå§‹è®°å½•åˆ—è¡¨
  delMethodVerify:'/processMethodVerify/delMethodVerify', // åˆ é™¤æ ‡å‡†æ–¹æ³•更新验证
  exportMethodVerify:'/processMethodVerify/exportMethodVerify', // å¯¼å‡ºæ ‡å‡†æ–¹æ³•更新验证
}
// 7.4检测或校准物品的处置-样品接收
@@ -796,7 +850,9 @@
  ratifyQualityMonitor:'/qualityMonitor/ratifyQualityMonitor', // ç›‘控计划批准
  delQualitySupervise:'/qualityMonitor/delQualitySupervise', // ç›‘控计划批准
  importQualityMonitor:'/qualityMonitor/importQualityMonitor', // å¯¼å…¥ç›‘控计划
  exportQualityMonitorDetail:'/qualityMonitor/exportQualityMonitorDetail', // å¯¼å‡ºç›‘控计划
  exportQualityMonitorDetail:'/qualityMonitor/exportQualityMonitorDetail',
  exportQualityMonitorRatify:'/qualityMonitor/exportQualityMonitorRatify', // è´¨é‡ç›‘控实施计划导出
  exportQualityMonitorEvaluate:'/qualityMonitor/exportQualityMonitorEvaluate', // è´¨é‡ç›‘控评价导出
}
// 8.5 åº”对风险和机遇的措施
@@ -921,3 +977,53 @@
  returnSubstance:'/feStandardSubstanceRecord/returnSubstance',//标准物质清单归还
  getPageSubstanceRecord: '/feStandardSubstanceRecord/getPageSubstanceRecord', // åˆ†é¡µæŸ¥è¯¢
}
const personPostAuthorizationRecord = {
  exportPersonPostAuthorizationRecord:'/personPostAuthorizationRecord/exportPersonPostAuthorizationRecord',//传参id  äººå‘˜çš„任职授权导出
  exportPersonBasicInfo:'/personBasicInfo/exportPersonBasicInfo',//本信息导出,传参类似分页
  exportPersonBasicInfoById:'/personBasicInfo/exportPersonBasicInfoById',//本信息导出,传参类似分页
  exportPersonJobResponsibilities:'/personJobResponsibilities/exportPersonJobResponsibilities',//导出人员职责,传参id
}
//设备接口
const deviceCheck = {
  list: '/device-alt',
  edit: '/device-alt/edit',
  saveIncidentReportData: '/incident-report/saveIncidentReportData', // è®¾å¤‡éªŒæ”¶ ä¿å­˜ï¼Œæäº¤ï¼Œé©³å›žï¼Œé€šè¿‡æŽ¥å£
  incidentReportPage: '/incident-report/incidentReportPage', // æ‰“开新增弹框,获取设备的基础信息
  deleteIncidentReport: '/incident-report/deleteIncidentReport', // åˆ é™¤è®¾å¤‡éªŒæ”¶æ•°æ®
  getShowIncidentReport: '/incident-report/getShowIncidentReport', // è®¾å¤‡éªŒæ”¶ ç‚¹å‡»æŸ¥çœ‹èŽ·å–æ•°æ®
  deleteIncidentReportAll: '/incident-report/deleteIncidentReportAll', // è®¾å¤‡éªŒæ”¶ä¸­å››ä¸ªtable表格的删除功能
  incidentReportExport: '/incident-report/incidentReportExport', // è®¾å¤‡éªŒæ”¶å¯¼å‡º
  deviceRecordPage: '/deviceRecord/deviceRecordPage', // cnas设备使用记录分页查询
  saveDeviceRecord: '/deviceRecord/saveDeviceRecord', // è®¾å¤‡ä½¿ç”¨è®°å½•保存
  deleteDeviceRecord: '/deviceRecord/deleteDeviceRecord', // åˆ é™¤è®¾å¤‡ä½¿ç”¨è®°å½•
  deviceRecordExport: '/deviceRecord/deviceRecordExport', // è®¾å¤‡ä½¿ç”¨è®°å½•删除
  getDeviceMaintenancePage: '/device-maintain/getDeviceMaintenancePage', // è®¾å¤‡ç»´æŠ¤åˆ†é¡µæŸ¥è¯¢
  deviceMaintenanceExport: '/device-maintain/deviceMaintenanceExport', // è®¾å¤‡ç»´æŠ¤å¯¼å‡º
  deviceMaintenanceDelete: '/device-maintain/delete', // è®¾å¤‡ç»´æŠ¤åˆ é™¤
  deviceMaintainAdd: '/device-maintain', // è®¾å¤‡ç»´æŠ¤æ–°å¢ž
  saveDeviceState: '/deviceState/saveDeviceState', // è®¾å¤‡å¯ç”¨/停用 ä¿å­˜ï¼Œæäº¤ï¼Œé©³å›žï¼Œé€šè¿‡æŽ¥å£
  getDeviceStatePage: '/deviceState/getDeviceStatePage', // è®¾å¤‡å¯ç”¨/停用 åˆ†é¡µ
  deleteDeviceState: '/deviceState/deleteDeviceState', // è®¾å¤‡å¯ç”¨/停用 åˆ é™¤
  deviceFaultOnePage: '/deviceFaultOne/deviceFaultOnePage', // è®¾å¤‡æ•…障表 åˆ†é¡µæŸ¥è¯¢
  addOrUpdateDeviceFaultOne: '/deviceFaultOne/addOrUpdateDeviceFaultOne',
  deleteDeviceFaultOne: '/deviceFaultOne/deleteDeviceFaultOne', // åˆ é™¤ è®¾å¤‡æ•…éšœ
  deviceMetricRecordPage: '/deviceMetricRecord/deviceMetricRecordPage', // è®¾å¤‡æ ¡å‡† åˆ†é¡µæŸ¥è¯¢
  addOrUpdateDeviceMetricRecord: '/deviceMetricRecord/addOrUpdateDeviceMetricRecord', // è®¾å¤‡æ ¡å‡† æ–°å¢ž æ›´æ–°
  deleteDeviceMetricRecord: '/deviceMetricRecord/deleteDeviceMetricRecord', // è®¾å¤‡æ ¡å‡† åˆ é™¤
  showDeviceMetricsCopy: '/deviceMetricRecord/showDeviceMetricsCopy', // è®¾å¤‡æ ¡å‡† æŸ¥è¯¢æ ¡å‡†æ¡ç›®
  selectDeviceMetric: '/deviceMetrics/selectDeviceMetric', // è®¾å¤‡æ ¡å‡† è®¾å¤‡ç»´æŠ¤è¡¨ æŸ¥è¯¢
  saveOrUpdateDeviceMetric: '/deviceMetrics/saveOrUpdateDeviceMetric', // è®¾å¤‡æ ¡å‡† æ–°å¢ž æ›´æ–°
  deleteDeviceMetrics: '/deviceMetrics/deleteDeviceMetrics', // è®¾å¤‡æ ¡å‡† åˆ é™¤
  rewardPunishmentExport: '/personRewardPunishmentRecord/rewardPunishmentExport', // å¥–惩记录 å¯¼å‡º
  exportRewardAndPunishmentRecords: '/deviceFaultOne/exportRewardAndPunishmentRecords', // å¥–惩记录导出
  deviceStateExport: "/deviceState/deviceStateExport", // è®¾å¤‡çŠ¶æ€
  newHomeworkGuidebookAdded: "/instruction/newHomeworkGuidebookAdded", // ä½œä¸šæŒ‡å¯¼ä¹¦æ–°å¢ž
  pageByPageQueryOfHomeworkInstructions: "/instruction/pageByPageQueryOfHomeworkInstructions", // ä½œä¸šæŒ‡å¯¼ä¹¦ æŸ¥è¯¢
  homeworkGuidebookEditor: "/instruction/homeworkGuidebookEditor", // ä½œä¸šæŒ‡å¯¼ä¹¦ ç¼–辑查询
  deleteHomeworkGuidebook: "/instruction/deleteHomeworkGuidebook", // ä½œä¸šæŒ‡å¯¼ä¹¦å—控文件删除
  homeworkGuidebook: "/instruction/homeworkGuidebook", // ä½œä¸šæŒ‡å¯¼ä¹¦ åˆ é™¤
  approvalOfHomeworkInstructionManual: "/instruction/approvalOfHomeworkInstructionManual", // ä½œä¸šæŒ‡å¯¼ä¹¦ å®¡æ‰¹
  deviceMetricRecordExport: '/deviceMetricRecord/deviceMetricRecordExport', // è®¾å¤‡æ ¡å‡† å¯¼å‡º
};
src/components/do/a6-personnel-collect/personnel-list.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,388 @@
<template>
  <div>
    <div class="search-list">
      <span class="search-input">
        <span class="search-label">
          <span style="width: 120px;font-size: 14px;line-height: 32px"
          >人员名称:</span
          >
          <el-input
            v-model="entity.name"
            clearable
            placeholder="请输入"
            size="small"
            style="width: 100%;"
            @keyup.enter.native="refreshTable()"
          >
          </el-input>
        </span>
        <el-button size="small" style="margin-left: 10px" @click="refresh()"
        >重 ç½®</el-button
        >
        <el-button size="small" type="primary" @click="refreshTable()"
        >查 è¯¢</el-button
        >
      </span>
      <span>
        <el-button
          :loading="outLoading"
          size="small"
          type="primary"
          @click="handleDown"
        >导出</el-button
        >
        <el-button size="small" type="primary" @click="selectUserDia = true"
        >新建</el-button
        >
      </span>
    </div>
    <div class="search-table">
      <el-table
        v-loading="tableLoading"
        :data="tableData"
        border
        height="calc(100vh - 20em)"
        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="groupTime" width="120"></el-table-column>
        <el-table-column label="籍贯" prop="nativePlace" width="120"></el-table-column>
        <el-table-column label="证件号码" prop="identityCard" show-overflow-tooltip width="300"></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 label="紧急联系人" prop="emergencyContact" width="120"></el-table-column>
        <el-table-column label="紧急联系电话" prop="emergencyContactPhone" width="120"></el-table-column>
        <el-table-column fixed="right" label="操作" width="140">
          <template slot-scope="scope">
            <el-button size="small" type="text" @click="downPerson(scope.row)">下载</el-button>
            <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"
        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.entity.name"
              clearable
              placeholder="请输入"
              size="small"
              @keyup.enter.native="$refs.ValueTable.selectList()"
            ></el-input>
          </div>
        </div>
      </div>
      <div v-if="selectUserDia" class="body" style="height: 60vh;">
        <ValueTable
          ref="ValueTable"
          :componentData="addUserTableInfo"
          :url="$api.user.selectUserList"
        />
      </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 ValueTable from '../../tool/value-table.vue';
export default {
  name: 'PersonnelList',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { ValueTable },
  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: [], // äººå‘˜æ€»åˆ—表数据
      selectUserDia: false, // æ·»åŠ äººå‘˜å¼¹æ¡†
      entity: {
        name: '',
        orderBy: {
          field: 'id',
          order: 'asc'
        }
      },
      addUserTableInfo: {
        name: null,
        entity: {
          isCustom: 0,
          orderBy: {
            field: 'id',
            order: 'asc'
          }
        },
        isIndex: true,
        showSelect: true,
        select: true,
        do: [],
        tagField: {
          state: {
            select: [
              {
                value: 1,
                type: 'success',
                label: '启用'
              },
              {
                value: 0,
                type: 'danger',
                label: '停用'
              }
            ]
          }
        },
        selectField: {},
        upUserDepardLimsIdPower: true
      },
    };
  },
  mounted() {
    this.refreshTable();
  },
  // æ–¹æ³•集合
  methods: {
    /**
     * @desc èŽ·å–è®¾å¤‡id
     */
    // é‡ç½®
    refresh() {
      this.page = {
        size: 20,
        current: 1,
      };
      this.entity.name = ''
      this.refreshTable();
    },
    // æŸ¥è¯¢äººå‘˜åˆ—表数据
    refreshTable(entity, type) {
      try {
        this.tableLoading = true;
        this.entity.departLimsId = this.departId;
        this.$axios.get(
          this.$api.personnel.basicInformationOfPersonnelSelectPage
          + '?size=' + this.page.size
          + '&current=' + this.page.current
          + '&departmentId=' + this.entity.departLimsId
          + '&name=' + this.entity.name
        )
          .then(res => {
            this.tableLoading = false;
            if (res.code === 201) {
              return;
            }
            this.page.total = res.data.total;
            this.tableData = res.data.records;
          });
      } catch (e) {
        this.tableLoading = false;
      }
    },
    // åˆ é™¤äººå‘˜
    deletePerson(row) {
      this.$confirm('是否删除当前数据?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.$axios
            .post(this.$api.user.delUserDepardLimsId + '?id=' + row.id)
            .then(res => {
              if (res.code === 201) {
                return;
              }
              this.$message.success('删除成功');
              this.refreshTable();
            })
            .catch(e => {
              this.$message.error('删除失败');
            });
        })
        .catch(() => {
        });
    },
    handleSizeChange(val) {
      this.page.size = val;
      this.refreshTable();
    },
    handleCurrentChange(val) {
      this.page.current = val;
      this.refreshTable();
    },
    selectUser() {
      if (!this.currentCompaniesList.length > 0) {
        this.$message.warning("请选择部门!")
        return;
      }
      let selects = this.$refs.ValueTable.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 + ',';
        }
      });
      this.selectUserDia = false;
      this.$axios.post(this.$api.user.upUserDepardLimsId, {
        ids: JSON.stringify(ids),
        id: str
      }).then(res => {
        if (res.code === 201) {
          return;
        }
        this.$message.success('添加成功');
        this.refreshTable();
      });
      this.$emit('refreshTree')
    },
    handleDown() {
      this.outLoading = true;
      let entity = this.HaveJson(this.entity)
      delete entity.orderBy;
      this.$axios.post(
          this.$api.personPostAuthorizationRecord.exportPersonBasicInfo,
          {
            entity: entity
          },
          {
            headers: {
              'Content-Type': 'application/json'
            },
            responseType: "blob"
          }
        )
        .then(res => {
          this.outLoading = false;
          if (res.code === 201) {
            return;
          }
          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();
        });
    },
    downPerson(row){
      this.$axios.post(
          this.$api.personPostAuthorizationRecord.exportPersonBasicInfoById+'?id=' + row.userId,
          {
            id: row.userId
          }
        )
        .then(res => {
          if (res.code === 201) {
            return;
          }
          this.$message.success('下载成功')
          try {
            let url = res.message;
            const link = document.createElement('a');
            link.href = this.javaApi + '/word/'+ url;
            // link.target = '_blank';
            document.body.appendChild(link);
            link.click();
          } catch (error) {
          }
        });
    }
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (newId) {
          this.page.current = 1
          this.refreshTable();
        }
      }
    }
  }
};
</script>
<style scoped>
.search-list {
  padding: 0 16px 16px;
  display: flex;
  justify-content: space-between;
}
.search-table {
  padding: 0 16px;
}
.search-input {
  display: flex;
}
.search-label {
  display: flex;
}
</style>
src/components/do/a6-personnel-training/AddInDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,173 @@
<template>
  <div>
    <el-dialog :visible.sync="addTrainingPlanDia" title="新增培训计划" width="50%">
      <div class="body">
        <el-form ref="trainingPlan" :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-dd"
                                placeholder="选择日期" size="small" value-format="yyyy-MM-dd"
                                type="date" style="width: 100%"></el-date-picker>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="课时:">
                <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="openingTime">
                <el-time-picker v-model="trainingPlan.openingTime" placeholder="选择时间"
                                size="small" style="width: 100%" value-format="HH:mm:ss"></el-time-picker>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="结束时间:" prop="endTime">
                <el-time-picker v-model="trainingPlan.endTime" placeholder="选择时间" size="small"
                                style="width: 100%" value-format="HH:mm:ss"></el-time-picker>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训目标:">
                <el-input v-model="trainingPlan.trainingObjectives" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="参加对象:">
                <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="课题学分:">
                <el-input type="number" v-model="trainingPlan.projectCredits" label="描述文字" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训地点:">
                <el-input v-model="trainingPlan.placeTraining" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训方式:">
                <el-input v-model="trainingPlan.trainingMode" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="举办部门:">
                <el-input v-model="trainingPlan.holdingDepartment" 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" @click="submitAdd">ç¡® å®š</el-button>
            </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  props: {
    currentChangeRow: {
      type: Object,
      default: () => {
        return {}
      }
    },
  },
  name: 'Add',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      addTrainingPlanDia: false,
      trainingPlan: {
        planId: '',
      },
      trainingPlanRules: {
        trainingDate: [{ required: true, message: '请选择培训日期', trigger: 'change' }],
        openingTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
        endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
        trainingContent: [{ required: true, message: '请输入培训内容', trigger: 'change' }],
        trainingLecturerId: [{ required: true, message: '请选择培训讲师', trigger: 'change' }],
      },
      responsibleOptions: [],
    };
  },
  // æ–¹æ³•集合
  methods: {
    showDialog(id) {
      this.addTrainingPlanDia = true;
      this.trainingPlan.planId = id
      this.getUserList()
    },
    // æäº¤æ–°å¢ž
    submitAdd() {
      this.$refs.trainingPlan.validate((valid) => {
        if (valid) {
          this.trainingPlan.planId = this.currentChangeRow.id
          const personTrainingDetailed = this.trainingPlan
          this.$axios.post(this.$api.personnel.addOrUpdatePersonTrainingDetailed, personTrainingDetailed, {
            headers: {
              'Content-Type': 'application/json'
            },
            noQs: true
          }).then(res => {
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.closeAdd();
              this.dialogVisible = false;
            }
          });
        }
      })
    },
    // å…³é—­å¼¹æ¡†
    closeAdd() {
      this.$refs.trainingPlan.resetFields();
      this.$emit('search')
      this.addTrainingPlanDia = false;
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      this.$axios.get(this.$api.deviceScope.selectUserList).then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data;
        }
      });
    },
  },
  watch: {
    addTrainingPlanDia(newVal) {
      if (newVal) {
        this.trainingPlan = {
          planId: '',
        }
      }
    }
  }
};
</script>
<style scoped>
</style>
src/components/do/a6-personnel-training/Edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,448 @@
<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">{{ currentRow.state === 4 ? '提交' : '撤销' }}</el-button>
        <el-button size="small" @click="$emit('goBack')">返回</el-button>
      </div>
    </div>
    <div class="form_title">
      <el-row>
        <el-col :span="5">
          <span class="form_label">课程编号:</span>
          <span> {{ trainingForm.courseCode }} </span>
        </el-col>
        <el-col :span="6">
          <span class="form_label">培训内容:</span>
          <span> {{ trainingForm.trainingContent }} </span>
        </el-col>
        <el-col :span="4">
          <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-tag v-if="trainingForm.state === 4" type="info">已结束</el-tag>
        </el-col>
        <el-col :span="4">
          <span class="form_label">培训讲师:</span>
          <span> {{ trainingForm.trainingLecturerName }} </span>
        </el-col>
        <el-col :span="4">
          <span class="form_label">培训日期:</span>
          <span> {{ trainingForm.trainingDate }} </span>
        </el-col>
      </el-row>
      <el-row style="margin: 15px 0">
        <el-form>
          <el-col :span="12">
            <el-form-item label="考核方式">
              <el-input v-model="trainingForm.assessmentMethod" :disabled="currentRow.state === 1" :rows="2" placeholder="请输入"
                        size="small" style="width: 79%" type="textarea"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="本次培训综合评价">
              <el-input v-model="trainingForm.comprehensiveAssessment" :disabled="currentRow.state === 1" :rows="2" placeholder="请输入"
                        size="small" style="width: 68%" type="textarea"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评价人">
              <el-select v-model="trainingForm.assessmentUserId" :disabled="currentRow.state === 1" placeholder="请选择" size="small" style="width: 68%">
                <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-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.entity.name"
              clearable
              placeholder="请输入"
              size="small"
              @keyup.enter.native="$refs.ValueTable.selectList()"
            ></el-input>
          </div>
        </div>
      </div>
      <div v-if="selectUserDia" class="body" style="height: 60vh;">
        <ValueTable
          ref="ValueTable"
          :componentData="addUserTableInfo"
          :isSelectedList="isSelectedList"
          :url="$api.user.selectUserList"
        />
      </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 TableCard from '../../caorui/TableCard/index.vue';
import ZTTable from '../../caorui/ZTTable/index.vue';
import ValueTable from '../../tool/value-table.vue';
export default {
  name: 'Edit',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {ValueTable, ZTTable, TableCard},
  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,
      selectUserDia: false, // æ·»åŠ äººå‘˜å¼¹æ¡†
      addUserTableInfo: {
        name: null,
        entity: {
          departLimsId: '1',
          orderBy: {
            field: 'id',
            order: 'asc'
          }
        },
        isIndex: true,
        showSelect: true,
        select: true,
        do: [],
        tagField: {
          state: {
            select: [
              {
                value: 1,
                type: 'success',
                label: '启用'
              },
              {
                value: 0,
                type: 'danger',
                label: '停用'
              }
            ]
          }
        },
        selectField: {},
        upUserDepardLimsIdPower: true
      },
      multipleSelection: [],
      userList: [],
    };
  },
  mounted() {
    this.trainingForm = this.currentRow
    this.getInfo()
    this.getUserList()
  },
  // æ–¹æ³•集合
  methods: {
    // èŽ·å–å½“å‰æ•°æ®
    async getInfo() {
      this.trainingLoading = true
      await this.$axios({
        method: 'get',
        url: this.$api.personnel.trainingAndAssessmentRecordsPage,
        params: {
          trainingDetailedId: this.currentRow.id,
          userName: this.userName
        },
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        noQs: true
      })
        .then(res => {
          if (res.code === 200) {
            this.trainingTableData = res.data
          }
          this.trainingLoading = false
        })
    },
    async updatePersonResult(row) {
      const { code } = await this.$axios({
        method: 'post',
        url: this.$api.personnel.outOfFocusPreservation,
        data: row,
        headers: {
          'Content-Type': 'application/json'
        }
      })
      if (code === 200) {
        this.$message.success("操作成功!")
      }
    },
    addPerson() {
      this.isSelectedList = this.trainingTableData.map(item => item.userId)
      this.selectUserDia = true;
    },
    selectUser() {
      let selects = this.$refs.ValueTable.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)
        // this.trainingTableData.push(obj);
      });
      this.$axios({
        method: 'post',
        url: this.$api.personnel.newPersonnelAddedToTrainingRecords,
        data: list,
        headers: {
          'Content-Type': 'application/json'
        },
        noQs: true
      })
        .then(res => {
          this.isSelectedList = []
          this.selectUserDia = false;
          this.getInfo()
        })
    },
    // æ‰¹é‡åˆ é™¤
    handleSelectionChange(list) {
      this.multipleSelection = list
    },
    batchDelete() {
      console.log('批量删除', this.multipleSelection)
      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)
          this.$axios({
            method: 'post',
            url: this.$api.personnel.deleteTrainingAndAssessmentRecords,
            data: formData,
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded'
            },
            noQs: true
          })
            .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() {
      if (this.currentRow.state !== 4 && this.currentRow.state !== 1) {
        this.$message.warning("当前状态无法提交/撤销!")
        return
      }
      // å¦‚果等于4 è¡¨ç¤ºè¯¥çŠ¶æ€ä¸ºå·²ç»“æŸï¼Œ1 è¡¨ç¤ºå·²å®Œæˆ
      let state = this.currentRow.state === 4 ? 1 : 4
      let data = {
        assessmentMethod: this.trainingForm.assessmentMethod,
        comprehensiveAssessment: this.trainingForm.comprehensiveAssessment,
        trainingDetailedId: this.trainingForm.id,
        assessmentUserId: this.trainingForm.assessmentUserId,
        state: state
      }
      const {code} = await this.$axios({
        method: 'post',
        url: this.$api.personnel.trainingAndAssessmentRecordsAdded,
        data: data,
        headers: {
          'Content-Type': 'application/json;'
        },
        noQs: true
      })
      if(code === 200) {
        this.currentRow.state = state
        this.$message.success("操作成功")
      }
    },
    getUserList(){
      this.$axios.post(this.$api.user.selectUserList, {
        page: {current: -1, size: -1,},
        entity: {name: null, isCustom: 0}
      }, {
        headers: {
          'Content-Type': 'application/json'
        }
      }).then(res => {
        if (res.code === 201) {
          return
        }
        this.userList = res.data.body.records
      })
    },
  }
};
</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/components/do/a6-personnel-training/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,794 @@
<!-- äººå‘˜åŸ¹è®­ -->
<template>
  <div class="flex_column">
    <div v-if="!editPlanShow && isDepartment">
      <TableCard title="年度计划表">
        <template v-slot:form>
          <div class="items_center">
            <span>创建人</span>
            <el-input v-model="pagination.compilerName" class="search" placeholder="请输入" size="small"></el-input>
            <el-button size="small" type="primary" @click="getYearPlanList(departId)">查询</el-button>
          </div>
          <div>
            <el-button size="small" type="primary" @click="uploadDia = true">导入</el-button>
          </div>
        </template>
        <template v-slot:table>
          <ZTTable
            :column="yearPlanColumn"
            :currentChange="currentChange"
            :height="'320'"
            :table-data="yearPlanTableData"
            :table-loading="yearLoading"
            highlightCurrentRow
            style="padding: 0 15px;">
          </ZTTable>
          <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="handleYearCurrent"
              @size-change="handleYearSizeChange">
            </el-pagination>
          </div>
        </template>
      </TableCard>
    </div>
    <div v-if="!editPlanShow" class="table">
      <TableCard title="年度计划明细表">
        <template v-slot:form>
          <div class="items_center">
            <span>培训讲师</span>
            <el-input v-model="inDetailForm.trainingLecturerName" class="search" clearable placeholder="请输入" size="small"></el-input>
            <span>课程编号</span>
            <el-input v-model="inDetailForm.courseCode" class="search" clearable placeholder="请输入" size="small"></el-input>
            <span style="margin-right: 16px">培训日期</span>
            <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-button size="small" style="margin-left: 16px" type="primary" @click="searchTable">查询</el-button>
          </div>
          <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">新增</el-button>
          </div>
        </template>
        <template v-slot:table>
          <ZTTable
            :column="inDetailPlanColumn"
            :handleSelectionChange="handleSelectionChange"
            :height="isDepartment ? '45vh' : '68vh' "
            :isSelection="true"
            :table-data="inDetailPlanTableData"
            :table-loading="yearLoading"
            style="padding: 0 15px;">
          </ZTTable>
          <div class="pagination">
            <div></div>
            <el-pagination
              :page-size="inDetailPagination.pageSize"
              :page-sizes="[10, 20, 30, 40]"
              :total="inDetailPagination.total"
              layout="total, sizes, prev, pager, next, jumper"
              @current-change="handleCurrentChange"
              @size-change="handleSizeChange">
            </el-pagination>
          </div>
        </template>
      </TableCard>
    </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="reviewRemarks = ''">
      <span>
        å®¡æ ¸å¤‡æ³¨ï¼š
        <el-input v-model="reviewRemarks" type="textarea"></el-input>
      </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="margin: 0 auto;">
        <el-upload ref="upload" :action="javaApi + $api.personnel.personTrainingImport" :auto-upload="false" :before-upload="beforeUpload" :file-list="fileList" :headers="token"
                   :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 >
  </div>
</template>
<script>
import ValueTable from '../../tool/value-table.vue';
import TableCard from '../../caorui/TableCard/index.vue';
import ZTTable from '../../caorui/ZTTable/index.vue';
import Add from './AddInDetail.vue';
import Edit from './Edit.vue';
export default {
  name: 'PersonnelTraining',
  components: { Add, ZTTable, TableCard, ValueTable, Edit },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      search: {},
      superviseForm: {},
      inDetailForm: {
        trainingLecturerName: '',
        courseCode: '',
        trainingDate: '',
      },
      yearLoading: false,
      yearPlanTableData: [], // å¹´åº¦è®¡åˆ’表数据
      yearPlanColumn: [
        {
          label: '文件名称',
          width: '160px',
          prop: 'fileName'
        }, {
          label: '创建时间',
          width: '160px',
          prop: 'createTime'
        }, {
          label: '创建人',
          prop: 'createUserName'
        }, {
          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) {
                  return true;
                } else {
                  return false;
                }
              },
              clickFun: (row) => {
                this.handleCheck(row.id);
              }
            },
            {
              name: '批准',
              type: 'text',
              disabled: (row) => {
                if(row.approvalStatus === 1) {
                  return true;
                } else {
                  return false;
                }
              },
              clickFun: (row) => {
                this.handleApprove(row.id);
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteFun(row.id);
              }
            }
          ]
        }],
      inDetailPlanTableData: [], // å¹´åº¦è®¡åˆ’明细表表数据
      inDetailPlanColumn: [
        {
          label: '课程编号',
          prop: 'courseCode',
          width: '130px',
        }, {
          dataType: 'tag',
          label: '认领状态',
          width: '100px',
          prop: 'whetherClaim',
          formatData: (params) => {
            if (params === true) {
              return '已认领';
            } else {
              return '未认领';
            }
          },
          formatType: (params) => {
            if (params === true) {
              return 'success';
            } else {
              return 'info'
            }
          }
        }, {
          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 if (params == 4) {
              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: 'placeTraining',
          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: '180',
          label: '操作',
          fixed: 'right',
          operation: [
            // è¶…过会议开始时间就不能认领了
            {
              name: '认领',
              type: 'text',
              clickFun: (row) => {
                this.handleClaim(row);
              },
              disabled: (row) => {
                if(row.whetherClaim === true || row.trainingDate < this.$moment().format('YYYY-MM-DD')) {
                  return true;
                } else {
                  return false;
                }
              },
            },
            {
              name: '结果明细',
              type: 'text',
              clickFun: (row) => {
                this.editInDetail(row);
              },
              showHide: () => {
                if (this.isDepartment) {
                  return true;
                } else {
                  return false;
                }
              }
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadInDetail(row);
              }
            }
          ]
        }],
      pagination: {
        pageSize: 20,
        current: 1,
        total: 0,
        compilerName: ""
      },
      inDetailPagination: {
        pageSize: 20,
        current: 1,
        total: 0
      },
      editPlanShow: false,
      currentRow: {},
      currentRowId: null, // å½“前选中数据的id
      reviewRemarks: '', // å®¡æ ¸å¤‡æ³¨
      reviewDialog: false, // å®¡æ ¸å¼¹æ¡†
      reviewLoading: false, // å®¡æ ¸æäº¤æŒ‰é’®
      approvalRemarks: '', // å®¡æ ¸å¤‡æ³¨
      approvalDialog: false, // å®¡æ ¸å¼¹æ¡†
      approvalLoading: false, // å®¡æ ¸æäº¤æŒ‰é’®
      multipleSelection: [], // å¹´åº¦æ˜Žç»†è¡¨é€‰ä¸­çš„æ•°æ®
      uploadDia: false,
      uploading: false,
      isOperation: false,
      token: null,
      fileList: [],
      currentChangeRow: {},
    };
  },
  mounted() {
    this.token = {
      'token': sessionStorage.getItem('token')
    }
    if (this.isDepartment) {
      this.getYearPlanList(this.departId)
    } else {
      this.getInDetailPlan('', this.departId)
    }
  },
  methods: {
    searchTable () {
      this.getInDetailPlan(this.currentRowId)
    },
    // æŸ¥è¯¢-年度计划表
    getYearPlanList(userId) {
      const name = this.isDepartment ? 'departmentId' : 'userId';
      this.$axios.get(this.$api.personnel.personTrainingSelect + `?${name}=` + userId + '&size=' + this.pagination.pageSize + '&current=' + this.pagination.current + '&compilerName=' + this.pagination.compilerName).then(res => {
        if (res.code === 201) return
        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])
        }
      });
    },
    currentChange (row) {
      const now = new Date();
      const currentYear = now.getFullYear();
      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
      this.$axios.get(this.$api.personnel.queryTheAnnualPlanDetailsTable + '?userId=' + userId + '&size=' + this.inDetailPagination.pageSize +
        '&current=' + this.inDetailPagination.current + '&id=' + id +
      '&trainingLecturerName=' + this.inDetailForm.trainingLecturerName+
      '&trainingDate=' + this.inDetailForm.trainingDate+
      '&courseCode=' + this.inDetailForm.courseCode).then(res => {
        if (res.code === 201) return
        this.inDetailPlanTableData = res.data.records;
        this.inDetailPagination.total = res.data.total;
      });
    },
    // æ–°å¢žå¹´åº¦è®¡åˆ’明细表
    addTrainingPlan() {
      if (!this.currentRowId) {
        this.$message.warning('请选择一条计划进行新增')
        return
      }
      this.$refs.addPlan.showDialog(this.currentRowId);
    },
    // å¹´åº¦è®¡åˆ’表-删除
    deleteFun(id) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$axios.delete(this.$api.personnel.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
    },
    handleReview (status) {
      const personTrainingUpdateDto = {
        id: this.currentRowId,
        remarks: this.reviewRemarks,
        status: status
      }
      this.reviewLoading = true
      this.$axios.post(this.$api.personnel.reviewAnnualPersonnelTraining, personTrainingUpdateDto, {
        headers: {
          'Content-Type': 'application/json'
        },
        noQs: true
      }).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,
        remarks: this.approvalRemarks,
        status: status
      }
      this.approvalLoading = true
      this.$axios.post(this.$api.personnel.approveAnnualPersonnelTraining, personTrainingUpdateDto, {
        headers: {
          'Content-Type': 'application/json'
        },
        noQs: true
      }).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) {
      this.$axios.get(this.$api.personnel.exportPersonTraining + '?id=' + row.id,{responseType: "blob"}).then(res => {
        this.outLoading = false
        this.$message.success('导出成功')
        const blob = new Blob([res],{ type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName + '.docx';
        link.click();
      })
    },
    // å¹´åº¦è®¡åˆ’-导入
    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 == 201) {
        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;
      }
    },
    // å¹´åº¦è®¡åˆ’分页
    handleYearCurrent(page) {
      this.pagination.current = page;
      this.getYearPlanList(this.departId);
    },
    handleYearSizeChange(size) {
      this.pagination.pageSize = size;
      this.getYearPlanList(this.departId);
    },
    // å¹´åº¦è®¡åˆ’明细表-认领、取消认领
    handleClaim(row) {
      this.$confirm('是否确认认领该课程?', '提示', {
        confirmButtonText: '认领',
        cancelButtonText: '取消认领',
        type: 'warning'
      }).then(() => {
        this.handleClaimFun(true, row.id)
      }).catch(() => {
        this.handleClaimFun(false, row.id)
      });
    },
    handleClaimFun(claimAndClaim, rowId) {
      this.$axios.post(this.$api.personnel.claimOfTrainingAndAssessmentRecords + `?claimAndClaim=${claimAndClaim}&courseId=${rowId}`).then(res => {
        this.getInDetailPlan(this.currentChangeRow.id)
      });
    },
    // å¹´åº¦è®¡åˆ’明细表-编辑
    editInDetail(row) {
      this.editPlanShow = true;
      this.currentRow = row
    },
    //
    goBack() {
      this.editPlanShow = false;
      this.getInDetailPlan(this.currentRowId)
    },
    // å¹´åº¦è®¡åˆ’明细表-下载
    downLoadInDetail(row) {
      this.$axios.get(this.$api.personnel.exportPersonTrainingRecord + '?id=' + row.id,{responseType: "blob"}).then(res => {
        this.outLoading = false
        this.$message.success('导出成功')
        const blob = new Blob([res],{ type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = row.courseCode + '人员培训与考核记录' + '.docx';
        link.click();
      })
    },
    // å¹´åº¦è®¡åˆ’明细表-多选
    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(() => {
          this.$axios.post(this.$api.personnel.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.getYearPlanList(this.departId);
    },
    handleCurrentChange(val) {
      this.inDetailPagination.current = val;
      this.getYearPlanList(this.departId);
    },
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    departId: {
      handler(newId, oldId) {
        if (this.isDepartment) {
          this.getYearPlanList(newId);
        } else {
          this.getInDetailPlan('')
        }
      }
    }
  }
};
</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/components/do/a6-personnel/job-responsibilities.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,374 @@
<!-- å²—位职责 -->
<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';
import { deletePersonCommunicationAbility } from '../../../assets/api/api';
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 => {
            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 = row.incumbentName+'-岗位职责'+'.docx';
            link.click();
          })
    },
    // åˆ é™¤å²—位职责
    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/components/do/a6-personnel/personnel-capacity.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,579 @@
<!-- äººå‘˜èƒ½åŠ› -->
<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="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 :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'" 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'">
              <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'" 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'" 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'">
              <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'" 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'" 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'">
              <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'"
                      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'" 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'">
              <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'"
                      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'" 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'">
              <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'" 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'"
                               @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'">
              <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'"
                      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'">
              <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-form>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="operationType !== 'view'" @click="resetForm">取消</el-button>
        <el-button v-if="operationType !== 'view'" type="primary" @click="submitForm">保存</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import ZTTable from '../../caorui/ZTTable/index.vue';
import TableCard from '../../caorui/TableCard/index.vue';
import {exportSuperVisePlanApi} from "../../../assets/api/api";
export default {
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  components: {
    ZTTable,
    TableCard
  },
  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: 'technicalPost',
          minWidth: '100'
        }, {
          dataType: 'slot',
          label: '工作经历',
          prop: 'placeWork',
          minWidth: '100',
          slot: 'placeWorkSlot'
        }, {
          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: 'confirmOperatingPersonnelId',
          minWidth: '100'
        }, {
          label: '确认日期',
          prop: 'confirmDate',
          minWidth: '160'
        }, {
          dataType: 'action',
          minWidth: '220',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.handleViewClick('edit', row);
              },
              showHide: (row) => {
                if (this.isDepartment) {
                  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.verifyGet(row.id);
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deletePost(row.id);
              },
              showHide: (row) => {
                if (this.isDepartment) {
                  return true;
                } else {
                  return false;
                }
              }
            }
          ]
        }],
      yearLoading: false,
      dialogVisible: false,
      form: {
        jobResponsibilitiesTem: []
      },
      responsibleOptions: [],
      rules: {
        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
        this.$message.success('导出成功')
        const blob = new Blob([res],{ type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = "人员能力导出" + '.docx';
        link.click();
      })
    },
    // æŸ¥è¯¢
    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;
      this.form = {
        jobResponsibilitiesTem: []
      }
      this.getUserList();
      this.getResponsibilities();
    },
    // ç¼–辑/查看
    handleViewClick(type, row) {
      this.operationType = type;
      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;
            }
          });
        }
      });
    },
    verifyGet (id) {
      this.$confirm('是否确认本条信息?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$axios.get(this.$api.personnel.confirmPersonnelCapability + '?id=' + id).then(res => {
          if (res.code == 200) {
            this.$message.success('确认成功');
            this.getList(this.departId);
          }
        });
      }).catch((err) => {
        console.log('err---', err);
        this.$message.info('已取消')
      });
    },
    // åˆ é™¤å²—位职责
    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.deviceScope.selectUserList).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/components/do/a6-personnel/personnel-information.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,948 @@
<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="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 v-model="form.name" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="登录账号">
                  <el-input 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-input v-model="form.jobNumber" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="员工子编号">
                  <el-input v-model="form.subordinateNumber" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <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-date-picker v-model="form.entryTime" type="date" placeholder="选择日期" size="small"
                                      style="width: 99%;" format="yyyy-MM-dd" 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.currentPosition" size="small" clearable></el-input>
                              </el-form-item>
                          </el-col> -->
            </el-row>
            <el-row>
              <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-input v-model="form.department" 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.postType" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="岗位编号">
                  <el-input v-model="form.postCode" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <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-row>
            <el-row>
              <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-date-picker v-model="form.unitTime" 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.reportingTo" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <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 :label=1 size="mini">正式工</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="试用开始时间">
                  <el-date-picker v-model="form.trialStartTime" 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.trialEndTime" 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="24" 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"
                                  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.idType" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <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-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-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-col :span="8">
                <el-form-item label="证件地址">
                  <el-input v-model="form.idAddress" 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.idDetailAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="现居地址">
                  <el-input v-model="form.currentAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="现居详细地址">
                  <el-input v-model="form.currentDetailAddress" 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.serviceAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="送达详细地址">
                  <el-input v-model="form.serviceDetailAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="是否退伍军人">
                  <el-radio-group v-model="form.retiredSoldiers">
                    <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-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.cornet" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="办公电话">
                  <el-input v-model="form.officePhone" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <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-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="计算机等级">
                  <el-input v-model="form.ncre" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <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-radio-group v-model="form.fullTime">
                    <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-radio-group v-model="form.enroll">
                    <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="XX届大学生">
                  <el-input v-model="form.collegeStudents" 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.emergencyContact" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="紧急联系电话">
                  <el-input v-model="form.emergencyContactPhone" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <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-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-input v-model="form.attachmentInformation" size="small" disabled>
                                      <el-button v-if="form.attachmentInformation" slot="append"
                                          icon="el-icon-delete-solid"
                                          @click="deleteFile(form.attachmentInformation, 'attachmentInformation')"></el-button>
                                  </el-input>
                              </el-form-item>
                          </el-col>
                          <el-col :span="4">
                              <el-upload ref="upload" style="float: left; margin: 0 20px;" :action="action"
                                  :show-file-list="false"
                                  :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'attachmentInformation')">
                                  <el-button class="uploadFile" slot="trigger" size="mini" type="primary">浏览</el-button>
                              </el-upload>
                              <el-button class="uploadFile" size="mini" type="primary" @click="downloadFile(form.attachmentInformation)">下载</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-form>
          <el-row>
          </el-row>
        </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 personnelClassification" :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-date-picker v-model="annex.periodValidity" 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 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">
                <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('annex')">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import fileDownload from '../../../util/file'
export default {
  props: {
    clickNodeVal: {
      type: Object,
      default: () => { return {} }
    },
  },
  data() {
    return {
      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: true, message: '请选择有效期', trigger: 'blur' }
        ]
      },
      dialogVisible1: false,
      form: {
        userId: '',
        name: '',
        account: '',
        currentState: '',
        jobNumber: '',
        subordinateNumber: '',
        sex: '',
        corporateName: '',
        department: '',
        departLimsId: [],
        postType: '',
        postCode: '',
        postName: '',
        groupTime: '',
        unitTime: '',
        reportingTo: '',
        laborRelations: '',
        trialStartTime: '',
        trialEndTime: '',
        personnelClassification: '',
        dateBirth: '',
        nativePlace: '',
        nation: '',
        idType: '',
        identityCard: '',
        age: '',
        validityPeriod: '',
        maritalStatus: '',
        idAddress: '',
        idDetailAddress: '',
        currentAddress: '',
        currentDetailAddress: '',
        serviceAddress: '',
        serviceDetailAddress: '',
        retiredSoldiers: '',
        politicalStatus: '',
        dumplingTime: '',
        telephone: '',
        cornet: '',
        officePhone: '',
        email: '',
        ncre: '',
        officialAcademicRedentials: '',
        highestDegree: '',
        graduatedInstitutions1: '',
        major1: '',
        graduationTime1: '',
        graduatedInstitutions2: '',
        major2: '',
        graduationTime2: '',
        fullTime: '',
        enroll: '',
        collegeStudents: '',
        emergencyContact: '',
        emergencyContactPhone: '',
        lastUpdateTime: '',
        pictureUrl: '',
        signatureUrl: '',
      },
      department: [],
      saveLoading: false,
      dialogVisible: false,
      personnelClassification: [],
      checkList: [],
      successFileList: [], // é˜²æ­¢åŽç«¯å‡ºçŽ°è„æ•°æ®
      isSave: false,
    }
  },
  components: {
    fileDownload
  },
  created() {
    this.init()
  },
  computed: {
    action() {
      return this.javaApi + this.$api.personnel.saveCNASFile
    }
  },
  methods: {
    annexAdd(type,row) {
      if(type === 1) {
        this.title = '编辑附件资料'
        this.addOrupdate = 1
        this.$axios.get(this.$api.personnel.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(formName) {
      this.$refs[formName].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) {
        this.$axios.post(this.$api.personnel.updateAnnex, this.annex, {
          headers: {
            'Content-Type': 'application/json'
          }
        }).then(res => {
          if(res.code == 200) {
            this.$axios.get(this.$api.personnel.getAnnexByUserId + '?userId=' + this.clickNodeVal.userId).then(res => {
              this.dialogVisible1 = false
              this.imageUrl = ''
              this.resetForm('annex')
              this.annexList = res.data
              this.$message.success('更新成功!')
            })
          }
        })
      }else {
        this.annex.id = null
        this.$axios.post(this.$api.personnel.addAnnex, this.annex, {
          headers: {
            'Content-Type': 'application/json'
          }
        }).then(res => {
          if(res.code == 200) {
            this.$axios.get(this.$api.personnel.getAnnexByUserId + '?userId=' + this.clickNodeVal.userId).then(res => {
              this.dialogVisible1 = false
              this.imageUrl = ''
              this.resetForm('annex')
              this.annexList = res.data
              this.$message.success('保存成功')
            })
          }
        })
      }
    },
    deleteAnnex(row) {
      this.$confirm('此操作将永久删除该文件, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$axios.delete(this.$api.personnel.deleteAnnex + '/' + row.id).then(res => {
          this.$message.success('删除成功!')
          this.annexList = this.annexList.filter(item => item.id != row.id)
        })
      })
    },
    beforeAvatarUpload(file) {
      const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif';
      const isLt2MB = file.size / 1024 / 1024 < 2;
      if (!isJPGorPNG) {
        this.$message.error('上传图片只能是 JPG/PNG æ ¼å¼!');
        return false;
      }
      if (!isLt2MB) {
        this.$message.error('上传图片大小不能超过 2MB!');
      }
      // æ ¡éªŒé€šè¿‡æ‰è¿”回 true,允许文件上传
      return isJPGorPNG && isLt2MB;
    },
    downloadFile(fileName) {
      let url = this.javaApi + '/img/' + fileName;
      fileDownload.downloadIamge(url, fileName)
    },
    async onSuccess(response, file, fileList, entityVal) {
      if(entityVal == 'fileName') {
        this.annex.fileName = response.data
        this.imageUrl = this.javaApi + '/img/' + 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) {
      this.$axios.get(this.$api.personnel.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)
        console.log('res.data',res);
      })
    },
    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 = ''
        }
      }
      this.$axios.post(this.$api.personnel.saveCNASPersonnelInfo, this.form, {
        headers: {
          'Content-Type': 'application/json'
        }
      }).then(res => {
        this.saveLoading = false
        this.isSave = true
        this.getUserBasisInfo(this.clickNodeVal.userId)
        this.$message.success('保存成功!')
      })
    },
    // å–人员分类的字典
    getComparisonList() {
      this.$axios.post(this.$api.enums.selectEnumByCategory, {
        category: "人员分类"
      }).then(res => {
        let data = res.data
        this.personnelClassification = data;
        this.checkList = this.form.personnelClassification.split(',')
      })
    },
    clickPersonnelClassificationSure() {
      this.dialogVisible = false
      this.form.personnelClassification = this.checkList.filter(m=>m).join(',')
    },
    async deleteFile(fileName, entityVal) {
      await this.$axios.delete(this.$api.personnel.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)
        }
      })
    },
    validateFileSize(rule, value, callback) {
      if (!value) {
        return callback(new Error('请上传文件'));
      }else {
        callback();
      }
    },
    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();
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    clickNodeVal: {
      handler(newVal, oldVal) {
        if (newVal.userId) {
          this.getUserBasisInfo(newVal.userId)
        }
      },
    }
  }
}
</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/components/do/a6-personnel/personnel-supervision.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
<!-- äººå‘˜ç›‘督 -->
<template>
  <div>
    <div style="text-align: left; margin-bottom: 15px;">
      <label>关键字</label>
      <el-input placeholder="请输入关键字" style="width: 20vh;" size="small"></el-input>
      <el-button type="primary" size="small">查询</el-button>
      <div style="float: right;">
        <el-button type="primary" size="small">查询</el-button>
        <el-button type="primary" size="small">导出excel</el-button>
      </div>
    </div>
    <div class="table">
      <el-table :data="tableData" style="width: 100%" height="70vh">
        <el-table-column prop="date" label="序号" min-width="120">
        </el-table-column>
        <el-table-column prop="name" label="流程编号" min-width="180">
        </el-table-column>
        <el-table-column prop="address" label="所属年度" min-width="180">
        </el-table-column>
        <el-table-column prop="address" label="编制日期" min-width="180">
        </el-table-column>
        <el-table-column prop="address" label="提交人" min-width="180">
        </el-table-column>
        <el-table-column prop="address" label="当前状态" min-width="120">
        </el-table-column>
        <el-table-column prop="address" label="当前责任人" min-width="180">
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="100">
          <template v-slot="scope">
            <el-button type="text" size="small">查看</el-button>
            <el-button type="text" size="small">编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="1"
        :page-sizes="[10, 20, 30, 50, 100]" :page-size="search.size" layout="->,total, sizes, prev, pager, next, jumper"
        :total="search.total">
      </el-pagination>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    clickNodeVal: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  data() {
    return {
      tableData: [],
      search: {
        size: 20,
        current: 1,
        total: 0
      }
    };
  },
  created() {
    this.init();
  },
  methods: {
    handleSizeChange(val) {
      this.search.size = val
      this.getPersonnelTraining(this.clickNodeVal.userId);
    },
    handleCurrentChange(val) {
      this.search.current = val
      this.getPersonnelTraining(this.clickNodeVal.userId);
    },
    // åˆå§‹åŒ–调用
    init() {
      if (this.clickNodeVal.userId) {
        this.getPersonnelTraining(this.clickNodeVal.userId ? this.clickNodeVal.userId : null, null);
      } else {
        this.getPersonnelTraining(null, this.clickNodeVal.id ? this.clickNodeVal.id : null);
      }
    },
    getPersonnelTraining(userId) {
      this.search.userId = userId
      this.$axios.get(this.$api.personnel.personTrainingSelect+"?userId=" + userId + "&size=" + this.search.size + "&current=" + this.search.current).then(res => {
        console.log(`output->res`,res)
      })
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    clickNodeVal(newVal) {
      if (newVal.userId) {
        this.getPersonnelTraining(newVal.userId);
      }
    }
  }
};
</script>
src/components/do/a6-personnel/reward-punishment-record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,329 @@
<!-- å¥–惩记录 -->
<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="dialogVisible = true">新增</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="userName">
              <el-select v-model="form.userName" placeholder="请选择" size="small" style="width: 100%" value-key="id"
                         @change="selectUserChange">
                <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item">
                </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>
import {
  addOrUpdateRewardPunishmentApi,
  deleteRewardPunishmentApi,
  rewardPunishmentExportApi,
  rewardPunishmentPageApi
} from "../../../assets/api/api"
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: {
        userName: [{
          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
      }
    },
    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'
        })
        // åˆ›å»ºä¸€ä¸ªè¶…链接,将文件流赋进去,然后实现这个超链接的单击事件
        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)
      })
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      this.$axios.get(this.$api.deviceScope.selectUserList).then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      })
    },
    selectUserChange(val) {
      this.form.userName = val.name
      this.form.account = val.account
      this.form.userId = val.id
    },
    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'
            }
          })
          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'].clearValidate()
      }
    }
  }
};
</script>
src/components/do/a6-personnel/track-record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,299 @@
<!-- å·¥ä½œå±¥åކ -->
<template>
  <div>
    <div style="text-align: right; margin-bottom: 15px;">
      <el-button type="primary" size="small" @click="dialogVisible = true" v-if="clickNodeVal.userId">添加工作履历</el-button>
      <el-button type="primary" size="small" @click="exportExcel" :loading="outLoading">导出excel</el-button>
    </div>
    <div class="table">
      <el-table :data="tableData" style="width: 100%" height="70vh">
        <el-table-column type="index" label="序号" width="120">
          <template v-slot="scope">
            <span>{{ (search.current - 1) * search.size + scope.$index + 1 }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="startTime" label="起始日期" min-width="180">
        </el-table-column>
        <el-table-column prop="endTime" label="结束日期" min-width="180">
        </el-table-column>
        <el-table-column prop="placeWork" label="工作单位" min-width="120">
        </el-table-column>
        <el-table-column prop="department" label="工作部门" min-width="120">
        </el-table-column>
        <el-table-column prop="post" label="职务" min-width="120">
        </el-table-column>
        <el-table-column prop="remarks" label="备注" min-width="180">
        </el-table-column>
        <el-table-column prop="createUser" label="创建人" min-width="180">
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" min-width="180">
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="150">
          <template v-slot="scope">
            <el-button type="text" size="small" @click="downloadFile(scope.row.fileName)">下载</el-button>
            <el-button type="text" size="small" @click="checkFun(scope.row)">查看</el-button>
            <el-button type="text" size="small" style="color: red;" @click="deleteFun(scope.row.id)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="1"
        :page-sizes="[10, 20, 30, 50, 100]" :page-size="search.size" layout="->,total, sizes, prev, pager, next, jumper"
        :total="search.total">
      </el-pagination>
    </div>
    <el-dialog title="提示" :visible.sync="dialogVisible" width="45%">
      <div style="height: 30vh;">
        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
          <el-row>
            <el-col :span="12">
              <el-form-item label="起始日期" prop="startTime">
                <el-date-picker v-model="ruleForm.startTime" type="date" placeholder="选择日期" size="small"
                  style="width: 99%;" format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss" required>
                </el-date-picker>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="结束日期">
                <el-date-picker v-model="ruleForm.endTime" type="date" placeholder="选择日期" size="small"
                  style="width: 99%;" format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss">
                </el-date-picker>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="工作单位" prop="placeWork">
                <el-input v-model="ruleForm.placeWork" size="small" clearable required></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="工作部门" prop="department">
                <el-input v-model="ruleForm.department" size="small" clearable required></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="最高职务" prop="post">
                <el-input v-model="ruleForm.post" size="small" clearable required></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="附件资料">
                <el-row>
                  <el-col :span="17"><el-input v-model="ruleForm.fileName" size="small" disabled></el-input></el-col>
                  <el-col :span="7">
                    <el-upload ref="upload" style="float: left; margin: 0 20px;" :action="action"
                      :on-success="onSuccess" :on-change="handleChangePic" :show-file-list="false">
                      <el-button class="uploadFile" slot="trigger" size="mini" type="primary">浏览</el-button>
                    </el-upload>
                  </el-col>
                </el-row>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="备注">
                <el-input v-model="ruleForm.remarks" size="small" clearable></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="saveOrUpdate">{{ isUpdate ? '更 æ–°' : '保 å­˜' }}</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
  import fileDownload from '../../../util/file'
export default {
  props: {
    clickNodeVal: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  data() {
    return {
      tableData: [],
      search: {
        size: 20,
        current: 1,
        total: 0
      },
      dialogVisible: false,
      ruleForm: {
        fileName: '',
        sysFileName: ''
      },
      rules: {
        startTime: [
          { required: true, message: '请输入起始日期', trigger: 'blur' },
          { required: true, message: '请输入起始日期', trigger: 'change' }
        ],
        placeWork: [
          { required: true, message: '请输入工作单位', trigger: 'blur' }
        ],
        department: [
          { required: true, message: '请输入工作部门', trigger: 'blur' }
        ],
        post: [
          { required: true, message: '请输入最高职务', trigger: 'blur' }
        ]
      },
      isUpdate: false,
      outLoading: false
    };
  },
  created() {
    this.init();
  },
  computed: {
    action() {
      return this.javaApi + this.$api.personnel.saveCNASFile
    }
  },
  methods: {
    downloadFile(fileName) {
      let url = this.javaApi + '/img/' + fileName;
      fileDownload.downloadIamge(url,fileName)
    },
    handleChangePic(file, fileList) {
      if (fileList.length > 1) {
        fileList.splice(0, 1);
      }
    },
    onSuccess(response, file, fileList) {
      if (response.code === 200) {
        this.$set(this.ruleForm, 'fileName', response.data)
      } else {
        this.$message.warning(response.message)
      }
    },
    exportExcel() {
      this.outLoading = true
      let userId = this.clickNodeVal.userId ? this.clickNodeVal.userId : null
      let departmentId = this.clickNodeVal.id ? this.clickNodeVal.id : null
      this.$axios.get(this.$api.personnel.personTrackRecordExport + "?userId=" + userId + "&departmentId=" + departmentId, { 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();
      })
    },
    saveOrUpdate() {
      this.$refs['ruleForm'].validate((valid) => {
        if (valid) {
          if (this.isUpdate) {
            this.$axios.put(this.$api.personnel.personTrackRecordUpdate, this.ruleForm, {
              headers: {
                'Content-Type': 'application/json'
              }
            }).then(res => {
              if (res.code = 200) {
                this.dialogVisible = false
                this.$message.success('更新成功!')
                this.init()
              }
            })
          } else {
            this.ruleForm.userId = this.clickNodeVal.userId
            this.$axios.post(this.$api.personnel.personTrackRecordSave, this.ruleForm, {
              headers: {
                'Content-Type': 'application/json'
              }
            }).then(res => {
              if (res.code = 200) {
                this.dialogVisible = false
                this.$message.success('新增成功!')
                this.init()
              }
            })
          }
        } else {
          return false;
        }
      });
    },
    deleteFun(id) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$axios.delete(this.$api.personnel.personTrackRecordDelete + "?id=" + id).then(res => {
          this.$message.success('删除成功!')
          this.init()
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    handleSizeChange(val) {
      this.search.size = val
      this.init()
    },
    handleCurrentChange(val) {
      this.search.current = val
      this.init()
    },
    // åˆå§‹åŒ–调用
    init() {
      if (this.clickNodeVal.userId) {
        this.getPersonnelTraining(this.clickNodeVal.userId ? this.clickNodeVal.userId : null, null);
      } else {
        this.getPersonnelTraining(null, this.clickNodeVal.id ? this.clickNodeVal.id : null);
      }
    },
    getPersonnelTraining(userId, departmentId) {
      this.$axios.get(this.$api.personnel.personTrackRecordSelect + "?userId=" + userId + "&size=" + this.search.size + "&current=" + this.search.current + "&departmentId=" + departmentId).then(res => {
        this.tableData = res.data.records
        this.search.total = res.data.total
      })
    },
    checkFun(row) {
      this.ruleForm = { ...row }
      this.dialogVisible = true
      this.isUpdate = true
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    clickNodeVal(newVal) {
      if (newVal.userId) {
        // ç”¨æˆ·id
        this.getPersonnelTraining(newVal.userId, null);
      } else {
        // éƒ¨é—¨id
        this.getPersonnelTraining(null, newVal.id);
      }
    },
    dialogVisible(newVal) {
      if (!newVal) {
        this.isUpdate = false
        this.$refs.ruleForm.resetFields();
        this.ruleForm = {}
      }
    }
  }
};
</script>
<style scoped>
>>>.el-form-item {
  margin-bottom: 13px;
}
</style>
src/components/do/a6-personnel/training-record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,319 @@
<!-- åŸ¹è®­è®°å½• -->
<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>
<!--              <el-button :loading="outLoading" size="small" type="primary" @click="exportExcel">导出</el-button>-->
            </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>
import ZTTable from '../../caorui/ZTTable/index.vue';
import TableCard from '../../caorui/TableCard/index.vue';
import {exportPersonSupervisionRecord} from "../../../assets/api/api";
export default {
  components: { TableCard, ZTTable },
  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.personnel.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
        this.$message.success('导出成功')
        const blob = new Blob([res],{ type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = '培训记录导出' + '.docx';
        link.click();
      })
    },
    // èŽ·å–å®žéªŒå®¤-培训计划列表信息
    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>
src/components/do/a8-file-handling/FileChangeRequest.vue
@@ -465,6 +465,9 @@
    // å½“前文件
    getCurrentFile(e){
      this.currentFile = this.fileList.find(m=>m.documentCode==e)
      if(!this.currentFile){
        this.currentFile = {}
      }
    },
    selectEnumByCategory() {
      this.$axios.post(this.$api.enums.selectEnumByCategory, {
src/components/view/a6-personnel.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,324 @@
<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 style="width: 10px;"></div>
    <div class="main_right">
      <!-- éƒ¨é—¨ -->
      <Department
        ref="departRef"
        :clickNodeVal="clickNodeVal"
        :currentCompaniesList="currentCompaniesList"
        :departId="departId"
        :isDepartment="isDepartment"
        :isShowAll="isShowAll"
      />
    </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 Department from '../caorui/Department/index.vue';
export default {
  components: {
    Department
  },
  data() {
    return {
      isShowAll: true, //  æ˜¯å¦å±•示标签栏
      departId: 0,
      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(() => {
        this.treeLoad = true
        this.$axios.post(this.$api.department.delDepartmentLims, {
          id: data.id
        }).then(res => {
          if (res.code == 201) return
          this.$message.success('已删除')
          this.geList();
        })
      }).catch(e => {})
    },
    addStandardTree() {
      if (this.addOb.name == null || this.addOb.factory == '') {
        this.$message.error('构架名称是必填项')
        return
      }
      this.$axios.post(this.$api.department.addDepartmentLims, this.addOb, {
        headers: {
          'Content-Type': 'application/json'
        }
      }).then(res => {
        if (res.code === 201) {
          return
        }
        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() {
      this.$axios.get(this.$api.personnel.selectCNSAPersonTree).then(res => {
        this.list = res.data;
        if(this.list.length > 0) {
          this.isDepartment = true;
          this.departId = this.list[0].id
        }
      });
    },
    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;
}
.node_i {
  color: orange;
  font-size: 18px;
}
.main {
  display: flex;
  padding: 15px 0;
}
.main_left {
  background: #ffffff;
  text-align: center;
  height: calc(100vh - 6.5em);
  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;
}
.search {
  background-color: #fff;
  height: 100%;
  display: flex;
  justify-content: end;
}
.search_thing {
  width: 350px;
  display: flex;
  align-items: center;
}
.search_label {
  width: 110px;
  font-size: 14px;
  text-align: right;
}
.search_input {
  width: calc(100% - 110px);
}
</style>
src/components/view/a7-Ensure-results-validity.vue
@@ -100,6 +100,15 @@
        <el-button :loading="ratifyLoading" type="primary" @click="handleRatify(1)">批 å‡†</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="downloadDialog" title="导出" width="600px">
      <span>
        <el-button plain type="primary" @click="controlDown">实施计划导出</el-button>
        <el-button plain type="primary" @click="processingDown">评价导出</el-button>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="downloadDialog = false">取 æ¶ˆ</el-button>
      </span>
    </el-dialog>
  </div>
</template>
@@ -333,6 +342,13 @@
              }
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
@@ -361,6 +377,8 @@
      examineInfo: {},
      ratifyInfo: {},
      upLoading: false,
      downloadDialog: false,
      download: {},
    };
  },
  mounted() {
@@ -573,6 +591,11 @@
      this.evaluateDialog = false
      this.getYearDetailPlanList()
    },
    // æ‰“开导出弹框
    downLoadPost (row) {
      this.downloadDialog = true
      this.download = row
    },
    // æ‰“开年度明细新增、修改弹框
    showDialog (type, row) {
      this.formDia = true
@@ -584,6 +607,32 @@
      this.formDia = false
      this.getYearDetailPlanList()
    },
    // æŽ§åˆ¶å•导出
    controlDown() {
      this.$axios.get(this.$api.qualityMonitor.exportQualityMonitorRatify + '?qualityMonitorDetailsId=' + this.download.qualityMonitorDetailsId, { responseType: "blob" }).then(res => {
        this.outLoading = false
        this.$message.success('导出成功')
        const blob = new Blob([res], { type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = '质量监控实施计划.docx';
        link.click();
      })
    },
    // å¤„理单导出
    processingDown() {
      this.$axios.get(this.$api.qualityMonitor.exportQualityMonitorEvaluate + '?qualityMonitorDetailsId=' + this.download.qualityMonitorDetailsId, { responseType: "blob" }).then(res => {
        this.outLoading = false
        this.$message.success('导出成功')
        const blob = new Blob([res], { type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = '质量监控评价.docx';
        link.click();
      })
    },
    delYearPlanDetail (row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
src/components/view/a7-changes-standard-methods.vue
@@ -10,7 +10,8 @@
      <div class="search-background">
        <span class="search-group">
          <span style="width: 120px">标准方法:</span>
          <el-input size="small" v-model="searchForm.methodName" clearable></el-input>
          <!-- <el-input size="small" v-model="searchForm.methodName" clearable></el-input> -->
          <el-input v-model="searchForm.methodName" clearable size="small"></el-input>
        </span>
        <span class="search-group">
          <el-button size="medium"  @click="resetSearchForm">重 ç½®</el-button>
@@ -88,6 +89,13 @@
              type: 'text',
              clickFun: (row) => {
                this.openFormDia('edit', row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              },
            },
            {
@@ -177,6 +185,19 @@
      this.formDIa = false
      this.searchList()
    },
    // å¯¼å‡º
    downLoadPost(row) {
      this.$axios.get(this.$api.processMethodVerify.exportMethodVerify + '?methodVerifyId=' + row.methodVerifyId,{responseType: "blob"}).then(res => {
        this.outLoading = false
        this.$message.success('导出成功')
        const blob = new Blob([res],{ type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = '标准(方法)确认记录.docx';
        link.click();
      })
    },
    // åˆ†é¡µ
    handleSizeChange(val) {
      this.page.size = val;
src/components/view/a7-method-verification.vue
@@ -10,7 +10,7 @@
      <div class="search-background">
        <span class="search-group">
          <span style="width: 120px">标准方法:</span>
          <el-input size="small" v-model="searchForm.methodName" clearable></el-input>
          <el-input v-model="searchForm.methodName" clearable size="small"></el-input>
        </span>
        <span class="search-group">
          <el-button size="medium"  @click="resetSearchForm">重 ç½®</el-button>
@@ -88,6 +88,13 @@
              type: 'text',
              clickFun: (row) => {
                this.openFormDia('edit', row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              },
            },
            {
@@ -172,6 +179,19 @@
        this.$refs.formDIa.openDia(row)
      })
    },
    // å¯¼å‡º
    downLoadPost(row) {
      this.$axios.get(this.$api.processMethodVerify.exportMethodVerify + '?methodVerifyId=' + row.methodVerifyId,{responseType: "blob"}).then(res => {
        this.outLoading = false
        this.$message.success('导出成功')
        const blob = new Blob([res],{ type: 'application/msword' });
        const url = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = url;
        link.download = '标准(方法)确认记录.docx';
        link.click();
      })
    },
    // å…³é—­å¼¹æ¡†
    closeDia () {
      this.formDIa = false
src/main.js
@@ -32,7 +32,7 @@
const javaApi = 'https://ztwxlims.ztt.cn:7443/lims/';
//云
// Vue.prototype.LOCATIONVUE = "http://114.132.189.42:8080";
Vue.prototype.LOCATIONVUE = "http://114.132.189.42:8080";
const javaApi = 'http://114.132.189.42:1234';
// //检测中心正式库