spring
2025-02-28 dc3af0cbb4a6d105bdff497b510cc0a87b3e8d0a
Merge branch 'dev' of http://114.132.189.42:9002/r/lims-ruoyi-before into dev
已修改16个文件
已重命名2个文件
已添加41个文件
10700 ■■■■■ 文件已修改
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/InspectionWorker.worker.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro.js 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personJobResponsibilities.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personPersonCommunicationAbilityPage.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personPersonnelCapacity.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personPostAuthorizationRecord.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personRewardPunishmentRecord.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personTrainingRecord.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personalList.js 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personalOverview.js 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/personal/personalTraining.js 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/method/standardMethodsChange.js 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/method/standardNoveltyRetrieval.js 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/user.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/styles/ruoyi.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Pagination/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/component/AddProject.vue 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableList.vue 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableOverview.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableProject.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/component/Edit.vue 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/component/Store.vue 468 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/component/contents.vue 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/externalService/serviceAndSupplyPro/index.vue 53 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personalOverview/index.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/Edit.vue 452 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/communicateAdd.vue 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/components/mandateAdd.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/index.vue 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue 576 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue 1115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue 802 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue 344 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue 303 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue 456 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/index.vue 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue 729 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/inspectionTask/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/inspectionTask/inspection.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/materialOrder/index.vue 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/productOrder/components/add.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/rawMaterialInspection/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/standard/model/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tool/file-preview.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -56,6 +56,7 @@
    "jsencrypt": "3.0.0-rc.1",
    "jspdf": "^3.0.0",
    "mammoth": "^1.9.0",
    "moment": "^2.30.1",
    "nprogress": "0.2.0",
    "pako": "^2.1.0",
    "print-js": "^1.6.0",
src/InspectionWorker.worker.js
@@ -1815,7 +1815,7 @@
    // Create version of divisor with leading zero.
    bz.unshift(0);
    // Add zeros to make remainder as long as divisor.
    // CommunicateAdd zeros to make remainder as long as divisor.
    for (; rl++ < bl; ) r.push(0);
    do {
@@ -1853,7 +1853,7 @@
        }
      }
      // Add the digit n to the result array.
      // CommunicateAdd the digit n to the result array.
      qc[qi++] = cmp ? n : ++n;
      // Update the remainder.
src/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro.js
@@ -8,3 +8,223 @@
    params: query
  })
}
export function deleteProcurementSuppliesList(query) {
  return request({
    url: '/procurementSuppliesList/deleteProcurementSuppliesList',
    method: 'delete',
    params: query
  })
}
export function exportProcurementSuppliesList(query) {
  return request({
    url: "/procurementSuppliesList/exportProcurementSuppliesList",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
export function addProcurementSuppliesList(query) {
  return request({
    url: '/procurementSuppliesList/addProcurementSuppliesList',
    method: 'post',
    data: query,
  })
}
export function selectEnumByCategory(query) {
  return request({
    url: '/enum/selectEnumByCategory',
    method: 'post',
    data: query,
  })
}
export function updateProcurementSuppliesList(query) {
  return request({
    url: '/procurementSuppliesList/updateProcurementSuppliesList',
    method: 'post',
    data: query,
  })
}
// æœåŠ¡å’Œä¾›åº”å“é‡‡è´­
export function selectSupplierManagementAll(query) {
  return request({
    url: '/supplierManagement/selectSupplierManagementAll',
    method: 'get',
    params: query
  })
}
export function addProcurementSuppliesExpends(query) {
  return request({
    url: '/procurementSuppliesExpends/addProcurementSuppliesExpends',
    method: 'post',
    data: query,
  })
}
export function deleteProcurementSuppliesExpends(query) {
  return request({
    url: '/procurementSuppliesExpends/deleteProcurementSuppliesExpends',
    method: 'delete',
    params: query
  })
}
export function procurementSuppliesExpendlist(query) {
  return request({
    url: '/procurementSuppliesExpends/procurementSuppliesExpendlist/',
    method: 'get',
    params: query
  })
}
export function exportProcurementSuppliesStoreExcel(query) {
  return request({
    url: '/procurementSuppliesStore/exportExcel',
    method: "get",
    responseType: "blob",
    params: query,
  })
}
// æ–°å¢žèŠ‚ç‚¹
export function addSuppliersDirectoryContents(query) {
  return request({
    url: '/suppliersDirectoryContents/addSuppliersDirectoryContents',
    method: 'post',
    data: query,
  })
}
// ç¼–辑节点
export function updateSuppliersDirectoryContents(query) {
  return request({
    url: '/suppliersDirectoryContents/updateSuppliersDirectoryContents',
    method: 'post',
    data: query,
  })
}
// åˆ é™¤èŠ‚ç‚¹
export function deleteSuppliersDirectoryContentsById(query) {
  return request({
    url: '/suppliersDirectoryContents/deleteSuppliersDirectoryContentsById',
    method: 'delete',
    params: query
  })
}
// é‡‡è´­ç‰©èµ„目录删除
export function deleteProcurementSuppliesContentById(query) {
  return request({
    url: '/procurementSuppliesContents/deleteProcurementSuppliesContentById',
    method: 'delete',
    params: query
  })
}
// æŸ¥è¯¢æ‰€æœ‰èŠ‚ç‚¹
export function getSuppliersDirectoryContentsNodeNames(query) {
  return request({
    url: '/suppliersDirectoryContents/getSuppliersDirectoryContentsNodeNames',
    method: 'get',
    params: query
  })
}
// é‡‡è´­ç‰©èµ„目录获取节点名称
export function getProcurementSuppliesContentsNodeNames(query) {
  return request({
    url: '/procurementSuppliesContents/getNodeNames',
    method: 'get',
    params: query
  })
}
//获取用户列表
export function selectUserCondition(query) {
  return request({
    url: "/system/newUser/selectUserCondition",
    method: "get",
    params: query,
  });
}
// é‡‡è´­ç‰©èµ„目录详情
export function selectProcurementSuppliesContentById(query) {
  return request({
    url: "/procurementSuppliesContents/selectProcurementSuppliesContentById",
    method: "get",
    params: query,
  });
}
// é‡‡è´­ç‰©èµ„目录列表
export function directoryListing(query) {
  return request({
    url: "/procurementSuppliesContents/directoryListing",
    method: "get",
    params: query,
  });
}
// è€—材入库修改
export function updateStore(query) {
  return request({
    url: '/procurementSuppliesStore/updateStore',
    method: 'post',
    data: query,
  })
}
// è€—材入库新增
export function addStore(query) {
  return request({
    url: '/procurementSuppliesStore/addStore',
    method: 'post',
    data: query,
  })
}
// æ ¹æ®id查询耗材入库
export function selectStoreById(query) {
  return request({
    url: "/procurementSuppliesStore/selectStoreById",
    method: "get",
    params: query,
  });
}
// è€—材入库列表
export function storeList(query) {
  return request({
    url: "/procurementSuppliesStore/storeList",
    method: "get",
    params: query,
  });
}
// è€—材入库删除
export function deleteStore(query) {
  return request({
    url: '/procurementSuppliesStore/deleteStore',
    method: 'delete',
    params: query
  })
}
// é‡‡è´­ç‰©èµ„目录新增
export function addProcurementSuppliesContents(query) {
  return request({
    url: '/procurementSuppliesContents/addProcurementSuppliesContents',
    method: 'post',
    data: query,
  })
}
src/api/cnas/personal/personJobResponsibilities.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
import request from "@/utils/request";
// åˆ†é¡µæŸ¥è¯¢å²—位职责
export function personJobResponsibilitiesSelect(query) {
  return request({
    url: "/personJobResponsibilities/personJobResponsibilitiesSelect",
    method: "get",
    params: query
  });
}
// æ–°å¢žå²—位职责
export function personJobResponsibilitiesSave(query) {
  return request({
    url: "/personJobResponsibilities/personJobResponsibilitiesSave",
    method: "post",
    data: query
  });
}
// å¯¼å‡ºå²—位职责
export function exportPersonJobResponsibilities(query) {
  return request({
    url: "/personJobResponsibilities/exportPersonJobResponsibilities",
    method: "post",
    params: query,
    responseType: "blob"
  });
}
// åˆ é™¤å²—位职责
export function personJobResponsibilitiesDelete(query) {
  return request({
    url: "/personJobResponsibilities/personJobResponsibilitiesDelete",
    method: "delete ",
    params: query
  });
}
src/api/cnas/personal/personPersonCommunicationAbilityPage.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
import request from "@/utils/request";
// æŸ¥è¯¢äººå‘˜æ²Ÿé€šè®°å½•
export function personPersonCommunicationAbilityPage(query) {
  return request({
    url: "/personCommunicationAbility/personPersonCommunicationAbilityPage",
    method: "get",
    params: query
  });
}
// åˆ é™¤äººå‘˜æ²Ÿé€šè®°å½•
export function deletePersonCommunicationAbility(query) {
  return request({
    url: "/personCommunicationAbility/deletePersonCommunicationAbility",
    method: "delete",
    params: query
  });
}
// å¯¼å‡ºäººå‘˜æ²Ÿé€šè®°å½•
export function exportPersonCommunicationAbility(query) {
  return request({
    url: "/personCommunicationAbility/exportPersonCommunicationAbility",
    method: "get",
    params: query,
    responseType: "blob"
  });
}
// æ–°å¢ž-编辑人员沟通记录
export function addOrUpdatePersonCommunicationAbility(query) {
  return request({
    url: "/personCommunicationAbility/addOrUpdatePersonCommunicationAbility",
    method: "post",
    data: query
  });
}
src/api/cnas/personal/personPersonnelCapacity.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
import request from "@/utils/request";
// æŸ¥è¯¢äººå‘˜èƒ½åŠ›
export function personPersonnelCapacityPage(query) {
  return request({
    url: "/personPersonnelCapacity/personPersonnelCapacityPage",
    method: "get",
    params: query
  });
}
// æ–°å¢žç¼–辑人员能力
export function addOrUpdatePersonPersonnelCapacity(query) {
  return request({
    url: "/personPersonnelCapacity/addOrUpdatePersonPersonnelCapacity",
    method: "post",
    data: query
  });
}
// æ–°å¢žç¼–辑人员能力
export function submitConfirmPersonnelCapability(query) {
  return request({
    url: "/personPersonnelCapacity/submitConfirmPersonnelCapability",
    method: "post",
    data: query
  });
}
// ç¡®è®¤äººå‘˜èƒ½åŠ›
export function confirmPersonnelCapability(query) {
  return request({
    url: "/personPersonnelCapacity/confirmPersonnelCapability",
    method: "get",
    params: query
  });
}
// åˆ é™¤äººå‘˜èƒ½åŠ›
export function deletePersonPersonnelCapacity(query) {
  return request({
    url: "/personPersonnelCapacity/deletePersonPersonnelCapacity",
    method: "delete",
    params: query
  });
}
// å¯¼å‡ºäººå‘˜èƒ½åŠ›
export function exportPersonnelCapacity(query) {
  return request({
    url: "/personPersonnelCapacity/exportPersonnelCapacity",
    method: "get",
    params: query,
    responseType: "blob"
  });
}
src/api/cnas/personal/personPostAuthorizationRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
import request from "@/utils/request";
// ä»»èŒæŽˆæƒè®°å½•查询表格
export function PersonPostAuthorizationRecordPage(query) {
  return request({
    url: "/personPostAuthorizationRecord/PersonPostAuthorizationRecordPage",
    method: "get",
    params: query
  });
}
// ä»»èŒæŽˆæƒè®°å½•删除
export function deletePersonPostAuthorizationRecord(query) {
  return request({
    url: "/personPostAuthorizationRecord/deletePersonPostAuthorizationRecord",
    method: "delete",
    params: query
  });
}
// ä»»èŒæŽˆæƒå¯¼å‡º
export function exportPersonPostAuthorizationRecord(query) {
  return request({
    url: "/personPostAuthorizationRecord/exportPersonPostAuthorizationRecord",
    method: "get",
    params: query,
    responseType: "blob"
  });
}
// ä»»èŒæŽˆæƒå¯¼å‡º
export function addOrUpdatePersonPostAuthorizationRecord(query) {
  return request({
    url: "/personPostAuthorizationRecord/addOrUpdatePersonPostAuthorizationRecord",
    method: "post",
    data: query,
  });
}
src/api/cnas/personal/personRewardPunishmentRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
import request from "@/utils/request";
// äººå‘˜ - å¥–惩记录 åˆ†é¡µæŸ¥è¯¢
export function rewardPunishmentPage(query) {
  return request({
    url: "/personRewardPunishmentRecord/rewardPunishmentPage",
    method: "get",
    params: query
  });
}
// äººå‘˜ - å¥–惩记录 å¯¼å‡º
export function rewardPunishmentExport(query) {
  return request({
    url: "/personRewardPunishmentRecord/rewardPunishmentExport",
    method: "get",
    params: query,
    responseType: 'blob'
  });
}
// äººå‘˜ - å¥–惩记录 æ–°å¢ž/更新
export function addOrUpdateRewardPunishment(query) {
  return request({
    url: "/personRewardPunishmentRecord/addOrUpdateRewardPunishment",
    method: "post",
    data: query,
  });
}
// äººå‘˜ - å¥–惩记录 æ–°å¢ž/更新
export function deleteRewardPunishment(query) {
  return request({
    url: "/personRewardPunishmentRecord/deleteRewardPunishment",
    method: "delete",
    params: query,
  });
}
src/api/cnas/personal/personTrainingRecord.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
import request from "@/utils/request";
// å¯¼å‡ºåŸ¹è®­è®°å½•
export function exportTrainingRecord(query) {
  return request({
    url: "/personTrainingRecord/exportTrainingRecord",
    method: "get",
    params: query,
    responseType: 'blob'
  });
}
// æŸ¥è¯¢äººå‘˜ åŸ¹è®­è®°å½•
export function trainingSelectTrainingRecord(query) {
  return request({
    url: "/personTrainingRecord/trainingSelectTrainingRecord",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢äººå‘˜æ˜Žç»† åŸ¹è®­è®°å½•
export function queryPersonnelDetails(query) {
  return request({
    url: "/personTrainingRecord/queryPersonnelDetails",
    method: "get",
    params: query,
  });
}
src/api/cnas/personal/personalList.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
import request from "@/utils/request";
// åˆ é™¤äººå‘˜æ˜Žç»†æ‰€åœ¨ç»„织架构
export function delUserDepardLimsId(query) {
  return request({
    url: "/system/newUser/delUserDepardLimsId",
    method: "delete",
    params: query,
  });
}
// ä¿®æ”¹äººå‘˜æ˜Žç»†æ‰€åœ¨ç»„织架构
export function upUserDepardLimsId(query) {
  return request({
    url: "/system/newUser/upUserDepardLimsId",
    method: "post",
    data: query,
  });
}
// å¯¼å‡º
export function exportPersonBasicInfo(query) {
  return request({
    url: "/personBasicInfo/exportPersonBasicInfo",
    method: "get",
    data: query,
    responseType: "blob"
  });
}
// å¯¼å‡º
export function exportPersonBasicInfoById(query) {
  return request({
    url: "/personBasicInfo/exportPersonBasicInfoById",
    method: "get",
    data: query,
    responseType: "blob"
  });
}
// èŽ·å–äººå‘˜åˆ—è¡¨
export function basicInformationOfPersonnelSelectPage(query) {
  return request({
    url: "/personBasicInfo/basicInformationOfPersonnelSelectPage",
    method: "get",
    params: query
  });
}
// åˆ é™¤éƒ¨é—¨
export function delDepartmentLims(query) {
  return request({
    url: "/department/delDepartmentLims",
    method: "delete",
    params: query
  });
}
// æ·»åŠ éƒ¨é—¨
export function addDepartmentLims(query) {
  return request({
    url: "/department/addDepartmentLims",
    method: "post",
    data: query
  });
}
// æŸ¥è¯¢CNAS人员侧边栏
export function selectCNSAPersonTree() {
  return request({
    url: "/personBasicInfo/selectCNSAPersonTree",
    method: "get"
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯é™„件列表
export function getBasicInfoFileList(query) {
  return request({
    url: "/personBasicInfo/getBasicInfoFileList",
    method: "get",
    params: query
  });
}
// åˆ é™¤é™„ä»¶
export function delBasicInfoFileList(query) {
  return request({
    url: "/personBasicInfo/delBasicInfoFileList",
    method: "delete",
    params: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†æ–°å¢ž
export function addBasicInfoWork(query) {
  return request({
    url: "/personBasicInfo/addBasicInfoWork",
    method: "post",
    data: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†ä¿®æ”¹
export function updateBasicInfoWorkList(query) {
  return request({
    url: "/personBasicInfo/updateBasicInfoWorkList",
    method: "post",
    data: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†åˆ é™¤
export function delBasicInfoWorkList(query) {
  return request({
    url: "/personBasicInfo/delBasicInfoWorkList",
    method: "delete",
    params: query
  });
}
// äººå‘˜åŸ¹è®­åŸºæœ¬ä¿¡æ¯å·¥ä½œç»åŽ†æŸ¥è¯¢
export function getBasicInfoWorkList(query) {
  return request({
    url: "/personBasicInfo/getBasicInfoWorkList",
    method: "get",
    params: query
  });
}
// èŽ·å–é™„ä»¶
export function getAnnex(query) {
  return request({
    url: "/personBasicInfo/getAnnex",
    method: "get",
    params: query
  });
}
// æ›´æ–°é™„ä»¶
export function updateAnnex(query) {
  return request({
    url: "/personBasicInfo/updateAnnex",
    method: "post",
    data: query
  });
}
// æ›´æ–°é™„ä»¶
export function getAnnexByUserId(query) {
  return request({
    url: "/personBasicInfo/getAnnexByUserId",
    method: "get",
    params: query
  });
}
// æ·»åР附件
export function addAnnex(query) {
  return request({
    url: "/personBasicInfo/addAnnex",
    method: "post",
    data: query
  });
}
// åˆ é™¤é™„ä»¶
export function deleteAnnex(query) {
  return request({
    url: "/personBasicInfo/deleteAnnex",
    method: "delete",
    params: query
  });
}
// äººå‘˜åŸºæœ¬ä¿¡æ¯æŸ¥è¯¢
export function getCNASPersonnelInfo(query) {
  return request({
    url: "/personBasicInfo/getCNASPersonnelInfo",
    method: "get",
    params: query
  });
}
// äººå‘˜åŸºæœ¬ä¿¡æ¯ä¿å­˜
export function saveCNASPersonnelInfo(query) {
  return request({
    url: "/personBasicInfo/saveCNASPersonnelInfo",
    method: "post",
    data: query
  });
}
// åˆ é™¤æ–‡ä»¶
export function deleteCNASFile(query) {
  return request({
    url: "/personBasicInfo/deleteCNASFile",
    method: "delete",
    params: query
  });
}
src/api/cnas/personal/personalOverview.js
src/api/cnas/personal/personalTraining.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,141 @@
import request from "@/utils/request";
// æŸ¥è¯¢äººå‘˜åŸ¹è®­
export function personTraining(query) {
  return request({
    url: "/personTraining/personTrainingSelect",
    method: "get",
    params: query
  });
}
// æŸ¥è¯¢åŸ¹è®­è®¡åˆ’年度计划明细表
export function queryTheAnnualPlanDetailsTable(query) {
  return request({
    url: "/personTraining/queryTheAnnualPlanDetailsTable",
    method: "get",
    params: query
  });
}
// åˆ é™¤äººå‘˜åŸ¹è®­ä¿¡æ¯
export function personTrainingDelete(query) {
  return request({
    url: "/personTraining/personTrainingDelete",
    method: "delete",
    params: query
  });
}
// å®¡æ ¸ å¹´åº¦äººå‘˜åŸ¹è®­
export function reviewAnnualPersonnelTraining(query) {
  return request({
    url: "/personTraining/reviewAnnualPersonnelTraining",
    method: "post",
    data: query
  });
}
// æ‰¹å‡† å¹´åº¦äººå‘˜åŸ¹è®­
export function approveAnnualPersonnelTraining(query) {
  return request({
    url: "/personTraining/approveAnnualPersonnelTraining",
    method: "post",
    data: query
  });
}
// å¯¼å‡ºäººå‘˜åŸ¹è®­
export function exportPersonTraining(query) {
  return request({
    url: "/personTraining/exportPersonTraining",
    method: "get",
    params: query,
    responseType: "blob"
  });
}
// å¯¼å‡ºäººå‘˜åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½•
export function exportPersonTrainingRecord(query) {
  return request({
    url: "/personTraining/exportPersonTrainingRecord",
    method: "get",
    params: query,
    responseType: "blob"
  });
}
// æ‰¹é‡åˆ é™¤ å¹´åº¦è®¡åˆ’明细表
export function deleteAnnualPlanDetailTable(query) {
  return request({
    url: "/personTraining/deleteAnnualPlanDetailTable",
    method: "delete",
    params: query
  });
}
// æ‰¹é‡åˆ é™¤ å¹´åº¦è®¡åˆ’明细表
export function addOrUpdatePersonTrainingDetailed(query) {
  return request({
    url: "/personTraining/addOrUpdatePersonTrainingDetailed",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æŸ¥è¯¢
export function trainingAndAssessmentRecordsPage(query) {
  return request({
    url: "/personTraining/trainingAndAssessmentRecordsPage",
    method: "get",
    params: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸ å¤±ç„¦æ›´æ–°
export function outOfFocusPreservation(query) {
  return request({
    url: "/personTraining/outOfFocusPreservation",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸ æ–°å¢žäººå‘˜
export function newPersonnelAddedToTrainingRecords(query) {
  return request({
    url: "/personTraining/newPersonnelAddedToTrainingRecords",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸ åˆ é™¤äººå‘˜
export function deleteTrainingAndAssessmentRecords(query) {
  return request({
    url: "/personTraining/deleteTrainingAndAssessmentRecords",
    method: "delete",
    params: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æäº¤
export function trainingAndAssessmentRecordsAdded(query) {
  return request({
    url: "/personTraining/trainingAndAssessmentRecordsAdded",
    method: "post",
    data: query
  });
}
// åŸ¹è®­ä¸Žè€ƒæ ¸è®°å½• æäº¤è¯„ä»·
export function trainingAndAssessmentRecordsEvaluate(query) {
  return request({
    url: "/personTraining/trainingAndAssessmentRecordsEvaluate",
    method: "post",
    data: query
  });
}
// äººå‘˜åŸ¹è®­è¯¦æƒ…附件列表
export function getTrainingDetailedFileList(query) {
  return request({
    url: "/personTraining/getTrainingDetailedFileList",
    method: "get",
    params: query
  });
}
// äººå‘˜åŸ¹è®­è¯¦æƒ…附件删除
export function delTrainingDetailedFileList(query) {
  return request({
    url: "/personTraining/delTrainingDetailedFileList",
    method: "delete",
    params: query
  });
}
src/api/cnas/process/method/standardMethodsChange.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
// å®žéªŒå®¤çš„æ£€æµ‹èƒ½åŠ›æ¡£æ¡ˆç›¸å…³æŽ¥å£
import request from "@/utils/request";
//标准方法更新验证列表
export function pagesMethodVerify(query) {
  return request({
    url: "/processMethodVerify/pagesMethodVerify",
    method: "get",
    params: query,
  });
}
//获取用户列表
export function selectUserCondition(query) {
  return request({
    url: "/system/newUser/selectUserCondition",
    method: "get",
    params: query,
  });
}
//查询标准方法验证详情
export function getMethodVerifyOne(query) {
  return request({
    url: "/processMethodVerify/getMethodVerifyOne",
    method: "get",
    params: query,
  });
}
// é€šè¿‡è®¾å¤‡åˆ†ç±»èŽ·å–è®¾å¤‡åˆ—è¡¨
export function deviceScopeSearch(query) {
  return request({
    url: '/deviceScope/search',
    method: 'get',
    params: query
  })
}
// æ–°å¢žæ ‡å‡†æ–¹æ³•验证
export function addMethodVerify(data) {
  return request({
    url: "/processMethodVerify/addMethodVerify",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹æ ‡å‡†æ–¹æ³•验证
export function updateMethodVerify(data) {
  return request({
    url: "/processMethodVerify/updateMethodVerify",
    method: "post",
    data: data,
  });
}
// å¯¼å‡ºæ ‡å‡†æ–¹æ³•更新验证
export function exportMethodVerify(query) {
  return request({
    url: '/processMethodVerify/exportMethodVerify',
    method: "get",
    responseType: "blob",
    params: query,
  })
}
// éªŒè¯ç¡®è®¤
export function methodVerifyAffirm(query) {
  return request({
    url: '/processMethodVerify/methodVerifyAffirm',
    method: 'get',
    params: query
  })
}
// åˆ é™¤æ ‡å‡†æ–¹æ³•更新验证
export function delMethodVerify(query) {
  return request({
    url: '/processMethodVerify/delMethodVerify',
    method: 'delete',
    params: query
  })
}
// åŽŸå§‹è®°å½•åˆ—è¡¨
export function getVerifyMethodFileList(query) {
  return request({
    url: '/processMethodVerify/getVerifyMethodFileList',
    method: 'get',
    params: query
  })
}
// åˆ é™¤éªŒè¯åŽŸå§‹è®°å½•åˆ—è¡¨
export function delVerifyMethodFileList(query) {
  return request({
    url: '/processMethodVerify/delVerifyMethodFileList',
    method: 'delete',
    params: query
  })
}
src/api/cnas/process/method/standardNoveltyRetrieval.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
// å®žéªŒå®¤çš„æ£€æµ‹èƒ½åŠ›æ¡£æ¡ˆç›¸å…³æŽ¥å£
import request from "@/utils/request";
// æ ‡å‡†æŸ¥æ–°åˆ—表
export function pageMethodSearchNew(query) {
  return request({
    url: "/processMethodSearchNew/pageMethodSearchNew",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢å­˜æ¡£
export function pageSearchNewArchived(query) {
  return request({
    url: "/processMethodSearchNew/pageSearchNewArchived",
    method: "get",
    params: query,
  });
}
// æ–°å¢žæ ‡å‡†æŸ¥æ–°å®¡æ‰¹æµç¨‹
export function addSearchNewArchived(data) {
  return request({
    url: "/processMethodSearchNew/addSearchNewArchived",
    method: "post",
    data: data,
  });
}
// æ–°å¢žæ ‡å‡†æŸ¥æ–°
export function addMethodSearchNew(data) {
  return request({
    url: "/processMethodSearchNew/addMethodSearchNew",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹æ ‡å‡†æŸ¥æ–°
export function updateMethodSearchNew(data) {
  return request({
    url: "/processMethodSearchNew/updateMethodSearchNew",
    method: "post",
    data: data,
  });
}
// å­˜æ¡£æ‰¹å‡†
export function ratifySearchNewArchivedr(data) {
  return request({
    url: "/processMethodSearchNew/ratifySearchNewArchivedr",
    method: "post",
    data: data,
  });
}
// æŸ¥è¯¢å­˜æ¡£å¤‡ä»½åˆ—表
export function pageSearchNewBackups(query) {
  return request({
    url: "/processMethodSearchNew/pageSearchNewBackups",
    method: "get",
    params: query,
  });
}
// å¯¼å‡ºæ ‡å‡†æŸ¥æ–°
export function exportMethodSearchNew(query) {
  return request({
    url: "/processMethodSearchNew/exportMethodSearchNew",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
src/api/system/user.js
@@ -187,3 +187,11 @@
    method: 'get'
  })
}
// èŽ·å–ç”¨æˆ·åˆ—è¡¨
export function selectUserCondition(query) {
  return request({
    url: "/system/newUser/selectUserCondition",
    method: "get",
    params: query,
  });
}
src/assets/styles/ruoyi.scss
@@ -121,7 +121,7 @@
  height: 32px;
  margin-bottom: 10px;
  margin-top: 15px;
  padding: 10px 20px !important;
  padding: 0 20px !important;
}
/* tree border */
src/components/Pagination/index.vue
@@ -106,7 +106,8 @@
<style scoped>
.pagination-container {
  background: #fff;
  padding: 32px 16px;
  padding: 28px 16px;
  margin-top: 10px;
}
.pagination-container.hidden {
  display: none;
src/main.js
@@ -49,6 +49,8 @@
import DictData from "@/components/DictData";
import { checkPermi } from "@/utils/permission"; // æƒé™åˆ¤æ–­å‡½æ•°
import { getToken } from "@/utils/auth";
// æ—¶é—´è½¬æ¢
import Moment from "moment";
// å…¨å±€æ–¹æ³•挂载
Vue.prototype.getDicts = getDicts;
@@ -80,6 +82,8 @@
    });
  },
});
Vue.use(Moment);
Vue.prototype.$moment = Moment;
// å…¨å±€ç»„件挂载
Vue.component("DictTag", DictTag);
src/utils/index.js
@@ -307,7 +307,7 @@
}
/**
 * Add class to element
 * CommunicateAdd class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
src/views/CNAS/externalService/serviceAndSupplyPro/component/AddProject.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
<template>
  <el-dialog
    :title="dialogTitle"
    width="60%"
    :visible.sync="dialogVisible"
  >
    <el-form :model="model" label-width="100px">
      <el-col :span="12">
        <el-form-item label="项目名称">
          <el-select
            v-model="model.name"
            placeholder="请选择项目名称"
            style="width: 100%"
            :disabled="row ? true:false"
            @change="handleSelect"
          >
            <el-option
              v-for="(v, i) in consumableOptions"
              :label="v.consumablesName"
              :value="v"
              :key="i"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="消耗数量">
          <el-input-number v-model="model.amount" :min="0" :step="1" placeholder="请输入消耗数量"></el-input-number>
        </el-form-item>
      </el-col>
    </el-form>
    <span slot="footer" class="dialog-footer">
            <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
            <el-button type="primary" @click="sumbit">ç¡® å®š</el-button>
        </span>
  </el-dialog>
</template>
<script>
import {
  addProcurementSuppliesExpends,
  procurementSuppliesList
} from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro";
export default {
  data() {
    return {
      dialogTitle: "",
      dialogVisible: false,
      model: {
        listId: undefined,
        name: ""
      },
      consumableOptions: [],
      row: undefined
    }
  },
  created() {
    this.fetchConsumableOptions()
  },
  methods: {
    fetchConsumableOptions() {
      procurementSuppliesList().then(res => {
        if (res.code === 200) {
          this.consumableOptions = res.data.records
        }
      })
    },
    openDialog(row) {
      if(row) {
        console.log(row, 'true')
        this.dialogTitle = `${row.consumablesName}添加消耗项`
        this.row = row
        this.model.listId = row.id
        this.model.name = row.consumablesName
      } else {
        this.dialogTitle = '添加消耗项'
      }
      this.dialogVisible = true
    },
    handleSelect(item) {
      console.log(item)
      this.model.listId = item.id
      this.model.name = item.consumablesName
    },
    sumbit() {
      addProcurementSuppliesExpends(this.model).then(res => {
        if (res.code === 200) {
          this.dialogVisible = false
          this.$emit('submit')
        }
      })
    }
    }
  }
</script>
src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,240 @@
<template>
  <div>
    <TableCard :showTitle="false">
      <template slot="form">
        <div class="action-box">
          <div></div>
          <div class="flex">
            <el-button icon="el-icon-plus" size="small" type="primary" @click="showDialog(undefined)">
              æ–°å»º
            </el-button>
            <el-button icon="el-icon-upload2" size="small" @click="exportExcel">
              å¯¼å‡ºExcel
            </el-button>
          </div>
        </div>
      </template>
      <template v-slot:table>
        <limsTable
          :column="columns"
          :currentChange="rowClick"
          :height="'25vh'"
          :highlightCurrentRow="true"
          :isSelection="false"
          :rowStyle="tableRowStyle"
          :table-data="tableData"
          rowKey="id"
          style="margin-top: 18px; padding: 0 15px;"
        >
          <template v-slot:consumablesTypeSlot="{row}">
            {{ findType(row.consumablesType) }}
          </template>
          <template v-slot:operation="scope">
            <el-button size="small" type="text" @click="showDialog(scope.row)">编辑</el-button>
            <el-button size="small" style="color: #f56c6c" type="text" @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </limsTable>
        <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="handleCurrent"
            @size-change="handleSize"
          >
          </el-pagination>
        </div>
      </template>
    </TableCard>
    <el-divider></el-divider>
    <div>
      <ConsumableProject ref="consumableProject"></ConsumableProject>
    </div>
    <Edit ref="editRef" :contentsId="contentsId" @submit="fetchData"/>
  </div>
</template>
<script>
import TableCard from './index.vue';
import Edit from "./Edit.vue"
import limsTable from '@/components/Table/lims-table.vue'
import {
  deleteProcurementSuppliesList,
  procurementSuppliesList,
  exportProcurementSuppliesList
} from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro";
import ConsumableProject from "./ConsumableProject.vue"
export default {
  dicts: ["consumables_type"],
  components: {
    TableCard, limsTable,Edit, ConsumableProject
  },
  props: {
    contentsId: {
      type: Number,
      required: true,
    }
  },
  watch: {
    contentsId(newVal, oldVal) {
      if (newVal !== 0) {
        this.fetchData()
      }
    }
  },
  data() {
    return {
      columns: [
        {
          label: "货号",
          prop: "itemNumber"
        },
        {
          label: "类别",
          prop: "consumablesType",
          dataType: "slot",
          slot: "consumablesTypeSlot"
        },
        {
          label: "名称",
          prop: "consumablesName"
        },
        {
          label: "规格",
          prop: "specifications"
        },
        {
          label: "参考供应商",
          prop: "supplierName"
        },
        {
          label: "库存下限",
          prop: "lowerLimit"
        },
        {
          label: "当前库存",
          prop: "currentAmount"
        },
        {
          label: "计量单位",
          prop: "unit"
        },
        {
          label: "备注",
          prop: "remark"
        },
        {
          label: "负责人",
          prop: "personInChargeName"
        },
        {
          label: "最近更新人",
          prop: "updateUserName"
        },
        {
          label: "最近更新日期",
          prop: "updateTime"
        },
        {
          fixed: 'right',
          label: "操作",
          width: 120,
          dataType: "slot",
          slot: "operation"
        }
      ],
      tableData: [],
      pagination: {
        current: 1,
        pageSize: 20,
        total: 0
      },
      options: [],
    }
  },
  mounted() {
    this.fetchData()
    this.options = this.dict.type.consumables_type;
  },
  methods: {
    async fetchData() {
      procurementSuppliesList({ contentId: this.contentsId}).then(res => {
        if (res.code === 200) {
          this.tableData = res.data.records
          if (this.tableData.length > 0) {
            this.rowClick(this.tableData[0])
          }
        }
      })
    },
    findType(val) {
      this.$nextTick()
      let res
      const e = this.options.find(item => item.value == val)
      if(e) {
        res = e.label
      } else {
        res = '-'
      }
      return res
    },
    showDialog(row) {
      this.$refs.editRef.openDialog(row);
    },
    async exportExcel() {
      exportProcurementSuppliesList({parentId:this.contentsId}).then(res => {
        const blob = new Blob([res], {type: 'application/octet-stream'});
        this.$download.saveAs(blob, '耗材列表.xlsx')
        this.$message.success('导出成功')
      })
    },
    handleCurrent() {
    },
    handleSize() {
    },
    handleDelete(row) {
      deleteProcurementSuppliesList({ id:row.id }).then(res => {
        if (res.code === 200) {
          this.$message.success('删除成功')
          this.fetchData()
        }
      })
    },
    rowClick(row) {
      this.$refs.consumableProject.fetchListId(row)
    },
    tableRowStyle({row}) {
      if(row.currentAmount <= row.lowerLimit) {
        return { background: '#ffcaca' }
      } else {
        return {}
      }
    }
  }
}
</script>
<style scoped>
.flex {
  display: flex;
}
.action-box {
  width: 100%;
  padding-top: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.pagination {
  padding-top: 15px;
  padding-right: 10px;
  display: flex;
  justify-content: space-between
}
</style>
src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableOverview.vue
@@ -29,7 +29,6 @@
import TableCard from './index.vue';
import { procurementSuppliesList } from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro"
import limsTable from '@/components/Table/lims-table.vue'
import axios from "axios";
export default {
    components: { CardPanel, TableCard, limsTable },
src/views/CNAS/externalService/serviceAndSupplyPro/component/ConsumableProject.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,164 @@
<template>
  <div>
    <TableCard :showTitle="false">
      <template slot="form">
        <div class="action-box">
          <div></div>
          <div class="flex">
            <el-button icon="el-icon-plus" size="small" type="primary" @click="showDialog">
              æ·»åŠ é¡¹ç›®
            </el-button>
            <el-button icon="el-icon-upload2" size="small" @click="exportExcel">
              å¯¼å‡º
            </el-button>
          </div>
        </div>
      </template>
      <template v-slot:table>
        <limsTable
          :column="columns"
          :height="'25vh'"
          :isSelection="true"
          :table-data="tableData"
          style="margin-top: 18px; padding: 0 15px;"
        >
          <template v-slot:operation="scope">
            <el-button size="small" type="text" @click="deleteData(scope.row)">删除</el-button>
          </template>
        </limsTable>
        <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="handleCurrent"
            @size-change="handleSize"
          >
          </el-pagination>
        </div>
      </template>
    </TableCard>
    <AddProject ref="AddProjectRef" @submit="fetchData"/>
  </div>
</template>
<script>
import TableCard from './index.vue';
import limsTable from '@/components/Table/lims-table.vue'
import Edit from "./Edit.vue"
import AddProject from './AddProject.vue';
import {
  deleteProcurementSuppliesExpends,
  procurementSuppliesExpendlist
} from "@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro";
export default {
  components: {
    TableCard, limsTable, Edit, AddProject
  },
  data() {
    return {
      columns: [
        // {
        //   label: "编号"
        // },
        {
          label: "项目名称",
          prop: "listName"
        },
        {
          label: "消耗数量",
          prop: "amount"
        },
        {
          label: "录入人",
          prop: "enterUserName"
        },
        {
          label: "最近更新人",
          prop: "updateUserName"
        },
        {
          label: "最近更新日期",
          prop: "updateTime"
        },
        {
          label: "操作",
          dataType: "slot",
          slot: "operation"
        }
      ],
      tableData: [],
      pagination: {
        current: 1,
        pageSize: 20,
        total: 0
      },
      listId: 0,
      row: undefined
    }
  },
  mounted() {
    this.fetchData()
  },
  methods: {
    fetchListId(row) {
      if(row) {
        this.listId = row.id
        this.row = row
      }
      this.fetchData()
    },
    async fetchData() {
      if (this.listId === 0) return
      procurementSuppliesExpendlist({
        procurementSuppliesListId:this.listId
      }).then(res => {
        if (res.code === 200) {
          this.tableData = res.data
        }
      })
    },
    showDialog() {
      this.$refs.AddProjectRef.openDialog(this.row);
    },
    deleteData(row) {
      deleteProcurementSuppliesExpends({ expendId:row.expendId}).then(res => {
        if (res.code === 200) {
          this.$message.success('删除成功')
          this.fetchData()
        }
      })
    },
    handleCurrent() {
    },
    handleSize() {
    },
    exportExcel() {
    }
  }
}
</script>
<style scoped>
.flex {
  display: flex;
}
.action-box {
  width: 100%;
  padding-top: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.pagination {
  padding-top: 15px;
  padding-right: 10px;
  display: flex;
  justify-content: space-between
}
</style>
src/views/CNAS/externalService/serviceAndSupplyPro/component/Edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,252 @@
<template>
  <el-dialog
    :visible.sync="dialogVisible"
    title="添加耗材项目信息"
    width="70%"
  >
    <el-form ref="modelForm" :model="model" :rules="rules" label-width="100px">
      <el-col :span="12">
        <el-form-item label="耗材类型" prop="consumablesType">
          <el-select v-model="model.consumablesType" placeholder="请选择耗材类型" size="small" style="width: 100%">
            <el-option v-for="(v, i) in dict.type.consumables_type" :key="i" :label="v.label" :value="v.value"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="货号">
          <el-input v-model="model.itemNumber" placeholder="请输入货号" size="small"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="耗材名称">
          <el-input v-model="model.consumablesName" placeholder="请输入耗材名称" size="small"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="规格">
          <el-input v-model="model.specifications" placeholder="请输入规格" size="small"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="计量单位">
          <el-input v-model="model.unit" placeholder="请输入计量单位" size="small"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="参考价格">
          <el-input-number v-model="model.referencePrice" :min="0" :precision="2" :step="0.01" placeholder="请输入参考价格"
                           size="small"></el-input-number>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="存放位置">
          <el-select v-model="model.contentId" placeholder="请选择存放位置" size="small" style="width: 100%">
            <el-option v-for="(v, i) in procurementSuppliesContentOptions" :key="i" :label="v.nodeName"
                       :value="v.id"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="负责人">
          <el-select v-model="model.personInCharge" placeholder="请选择负责人" size="small" style="width: 100%">
            <el-option v-for="(v, i) in userOptions" :key="i" :label="v.name" :value="v.id"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="库存上限">
          <el-input-number v-model="model.upperLimit" :min="0" :step="1" placeholder="请输入库存上限" size="small"></el-input-number>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="库存下限">
          <el-input-number v-model="model.lowerLimit" :min="0" :step="1" placeholder="请输入库存下限" size="small"></el-input-number>
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="供应商">
          <el-select v-model="model.supplier" placeholder="请选择供应商" size="small" style="width: 100%">
            <el-option v-for="(v, i) in supplierOptions" :key="i" :label="v.supplierName"
                       :value="v.supplierManagementId"></el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="耗材图标">
          <div class="rows">
            <el-input v-model="model.consumablesIcon" placeholder="请输入耗材图标" size="small" style="width: 90%;"/>
            <el-upload
              ref="upload"
              :action="action"
              :headers="uploadHeader"
              :on-success="onSuccessIcon"
              :show-file-list="false"
              style="float: left; margin: 0 12px 0 20px;"
            >
              <el-button slot="trigger" class="uploadFile" size="small" type="primary">浏览</el-button>
            </el-upload>
          </div>
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="耗材附件">
          <div class="rows">
            <el-input v-model="model.attachment" placeholder="请输入耗材附件" size="small" style="width: 90%;"/>
            <el-upload
              ref="upload"
              :action="action"
              :on-success="onSuccessFile"
              :show-file-list="false"
              :headers="uploadHeader"
              style="float: left; margin: 0 12px 0 20px;"
            >
              <el-button slot="trigger" class="uploadFile" size="small" type="primary">浏览</el-button>
            </el-upload>
          </div>
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="备注">
          <el-input
            v-model="model.remark"
            :rows="2"
            placeholder="请输入备注"
            size="small"
            type="textarea"
          >
          </el-input>
        </el-form-item>
      </el-col>
    </el-form>
    <span slot="footer" class="dialog-footer">
            <el-button @click="resetForm">取 æ¶ˆ</el-button>
            <el-button type="primary" @click="submit">保 å­˜</el-button>
        </span>
  </el-dialog>
</template>
<script>
import {
  addProcurementSuppliesList,
  updateProcurementSuppliesList,
  selectSupplierManagementAll,
  getProcurementSuppliesContentsNodeNames,
  selectUserCondition
} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
export default {
  data() {
    return {
      dialogVisible: false,
      model: {
        consumablesType: undefined,
        consumablesIcon: undefined,
        attachment: undefined,
      },
      procurementSuppliesContentOptions: [],
      userOptions: [],
      supplierOptions: [],
      rules: {
        consumablesType: [{ required: true, message: '请选择耗材类型', trigger: 'blur' }],
      },
    }
  },
  dicts: ["consumables_type"],
  props: {
    contentsId: {
      type: Number,
      required: true,
    }
  },
  computed: {
    action() {
      return this.javaApi + '/personBasicInfo/saveCNASFile'
    }
  },
  mounted() {
    this.findProcurementSuppliesContentOptions()
    this.findUserOptions()
    this.findSupplierOptions()
  },
  methods: {
    // é‡ç½®è¡¨å•
    resetForm() {
      this.$refs.modelForm.resetFields();
      this.dialogVisible = false
    },
    openDialog(row) {
      if (row) {
        console.log("row", row)
        this.model = row
      } else {
        this.model = {}
      }
      this.dialogVisible = true
    },
    findProcurementSuppliesContentOptions() {
      getProcurementSuppliesContentsNodeNames().then(res => {
        if (res.code === 200) {
          this.procurementSuppliesContentOptions = res.data
        }
      })
    },
    findUserOptions() {
      selectUserCondition().then(res => {
        if (res.code === 200) {
          this.userOptions = res.data
        }
      })
    },
    findSupplierOptions() {
      selectSupplierManagementAll().then(res => {
        if (res.code === 200) {
          this.supplierOptions = res.data
        }
      })
    },
    async onSuccessIcon(response) {
      this.$set(this.model, "consumablesIcon", response.data)
    },
    async onSuccessFile(response) {
      this.$set(this.model, "attachment", response.data)
    },
    submit() {
      this.$refs.modelForm.validate((valid) => {
        if (valid) {
          if (this.model.id) {
            updateProcurementSuppliesList(this.model).then(res => {
              if (res.code === 200) {
                this.dialogVisible = false
              }
            })
          } else {
            addProcurementSuppliesList(this.model).then(res => {
              if (res.code === 200) {
                this.dialogVisible = false
                this.$emit('submit')
              }
            })
          }
        }
      })
    }
  }
}
</script>
<style scoped>
>>>.el-dialog {
  margin: 6vh auto 50px !important;
}
>>> .el-dialog__body {
  max-height: 42em;
  overflow-y: auto;
}
.rows {
  width: 100%;
  display: flex;
  justify-content: space-between;
}
>>>.el-form-item__content {
  line-height: 39px;
}
</style>
src/views/CNAS/externalService/serviceAndSupplyPro/component/Store.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,468 @@
<template>
  <div>
    <div style="
        display: flex;
        justify-content: flex-end;
        margin-right: 20px;
        margin-bottom: 20px;
      ">
      <el-button icon="el-icon-plus" size="small" type="primary" @click="addOrUpdateStore('add')">添加
      </el-button>
      <el-button icon="el-icon-download" size="small" @click="importExcel">
        å¯¼å‡ºexcel
      </el-button>
    </div>
    <div class="table">
      <limsTable
        :column="tableColumn"
        :height="'calc(100vh - 20em)'"
        :table-data="storageTableData"
        :table-loading="tableLoading"
        style="padding: 0 10px;margin-bottom: 16px"
        :page="page"
        @pagination="pagination">
      </limsTable>
    </div>
    <!-- ç¼–辑-新增弹框 -->
    <el-dialog :before-close="handleClose" :close-on-click-modal="false"
               :close-on-press-escape="false" :title="title"
               :visible.sync="dialogVisible" width="70%">
      <!-- å…¥åº“单 -->
      <div>
        <div style="display: flex; align-items: center">
          <span style="margin-left: 10px">入库单</span>
        </div>
        <el-form ref="formModel" :model="form" label-width="auto">
          <el-col :span="12">
            <el-form-item label="入库单号">
              <el-input v-model="form.oddNumbers" placeholder="请输入入库单号" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库库存">
              <el-input v-model="form.inventory" placeholder="请输入入库库存" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库总金额">
              <el-input v-model="form.totalAmount" placeholder="请输入入库总金额" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库日期">
              <el-date-picker v-model="form.storageTime" format="yyyy-MM-dd"
                              placeholder="选择日期"
                              size="small"
                              style="width: 100%" type="date" value-format="yyyy-MM-dd"></el-date-picker>
            </el-form-item>
          </el-col>
            <el-col :span="12">
              <el-form-item label="入库人">
                <el-select v-model="form.storageUser" size="small" style="width: 100%">
                  <el-option v-for="item in users" :key="item.id" :label="item.name" :value="item.id"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          <el-col :span="12">
            <el-form-item label="入库说明">
              <el-input v-model="form.remark" :rows="2" placeholder="请输入内容" type="textarea">
              </el-input>
            </el-form-item>
          </el-col>
        </el-form>
      </div>
      <!-- å…¥åº“明细 -->
      <div>
        <div>入库明细</div>
        <div class="input-form">
          <div>
            <div>
              <span>耗材名称:</span>
              <el-select v-model="formTwo.id" filterable placeholder="请选择耗材名称" size="small" style="width: 70%">
                <el-option v-for="(v, i) in consumableOptions" :key="i" :label="v.consumablesName"
                  :value="v.id"></el-option>
              </el-select>
            </div>
          </div>
          <div>
            <div>
              <span>单价:</span>
              <el-input v-model="formTwo.unitPrice" placeholder="请输入单价" size="small" style="width: 70%">
              </el-input>
            </div>
          </div>
          <div>
            <div>
              <span>入库数量:</span>
              <el-input v-model="formTwo.storeNumber" placeholder="请输入入库数量" size="small" style="width: 70%">
              </el-input>
            </div>
          </div>
          <div>
            <div>
              <span>总价:</span>
              <el-input v-model="formTwo.totalPrice" placeholder="请输入总价" size="small" style="width: 70%">
              </el-input>
            </div>
          </div>
          <el-button size="mini" type="primary"
            @click="addTableData">添加
          </el-button>
        </div>
        <el-table :data="consumables" style="margin-top: 10px">
          <el-table-column label="编号" type="index" width="120px"></el-table-column>
          <el-table-column label="货号" prop="itemNumber"></el-table-column>
          <el-table-column label="类别" prop="type"></el-table-column>
          <el-table-column label="名称" prop="consumablesName"></el-table-column>
          <el-table-column label="规格" prop="specifications"></el-table-column>
          <el-table-column label="参考供应商" prop="supplier"></el-table-column>
          <el-table-column label="计量单位" prop="unit"></el-table-column>
          <el-table-column label="单价" prop="unitPrice"></el-table-column>
          <el-table-column label="入库数量" prop="storeNumber"></el-table-column>
          <el-table-column label="总价" prop="totalPrice"></el-table-column>
          <el-table-column label="操作" width="80px">
            <template slot-scope="scope">
              <el-button size="mini" style="color: #f56c6c" type="text" @click="deleteTableData(scope.$index)">删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 æ¶ˆ</el-button>
        <el-button type="primary" :loading="saveLoading" @click="save">保 å­˜</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  addStore,
  deleteStore,
  exportProcurementSuppliesStoreExcel,
  procurementSuppliesList,
  selectStoreById,
  selectUserCondition,
  storeList,
  updateStore
} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
import limsTable from '@/components/Table/lims-table.vue'
export default {
  computed: {
    title() {
      return this.dialogType == "add" ? "新建入库" : "编辑入库";
    },
  },
  dicts: ["consumables_type"],
  props: {
    contentsId: {
      type: Number,
      default: 0
    }
  },
  watch: {
  },
  data() {
    return {
      mutiList: [],
      consumables: [],
      users: [],
      form: {
        oddNumbers: null,
        inventory: null,
        totalAmount: null,
        storageTime: null,
        storageUser: null,
        remark: null,
      },
      formTwo: {
        consumablesName: null,
        unitPrice: null,
        storeNumber: null,
        totalPrice: null,
      },
      dialogVisible: false,
      dialogType: "",
      upIndex: 0,
      tableColumn: [
        {
          label: '入库单号',
          prop: 'oddNumbers',
          minWidth: '100'
        },
        {
          label: '耗材名称',
          prop: 'consumablesName',
          minWidth: '100'
        },
        {
          label: '入库数量',
          prop: 'storeNumber',
          minWidth: '100'
        },
        {
          label: '入库总价',
          prop: 'totalPrice',
          minWidth: '100'
        },
        {
          label: '入库人',
          prop: 'storageUserName',
          minWidth: '100'
        }, {
          label: '入库日期',
          prop: 'storageTime',
          minWidth: '100'
        }, {
          label: '说明',
          prop: 'remark',
          minWidth: '100'
        }, {
          label: '登记人',
          prop: 'registrantName',
          minWidth: '160'
        },{
          label: '登记日期',
          prop: 'registrantTime',
          minWidth: '100'
        },
        {
          dataType: 'action',
          fixed: 'right',
          minWidth: '120',
          label: '操作',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.addOrUpdateStore('edit', row);
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteStore(row)
              },
            }
          ]
        }
      ],
      tableLoading: false,
      page: {
        total: 0,
        size: 10,
        current: 1
      },
      consumableOptions: [],
      options: [],
      storageTableData: [],
      searchForm: {
        orderBy: {
          field: "id",
          order: "desc",
        },
      },
      saveLoading: false,
    };
  },
  components: {
    limsTable,
  },
  mounted() {
    this.searchList();
    this.getUserList();
    this.fetchListOptions()
    this.options = this.dict.type.consumables_type
  },
  methods: {
    // ä¿å­˜
    save() {
      let data = {
        store: this.form,
        consumables: this.consumables,
      };
      this.saveLoading = true;
      if (this.dialogType === "update") {
        updateStore(data).then((res) => {
          this.saveLoading = false
          if (res.code == 200) {
            this.$message.success("修改成功");
            this.handleClose();
            // this.$refs.selectList()
            this.searchList()
          }
        }).catch((err) => {
          this.saveLoading = false
        })
      } else {
        addStore(data).then((res) => {
          this.saveLoading = false
          if (res.code == 200) {
            this.$message.success("新增成功");
            this.handleClose();
            // this.$refs.selectList()
            this.searchList()
          }
        }).catch((err) => {
          this.saveLoading = false
        })
      }
    },
    findType(val) {
      console.log(val)
      return this.options.find(item => item.value === val).label
    },
    // æ·»åŠ è¡¨æ ¼æ•°æ®
    addTableData() {
      this.$nextTick()
      console.log('this.consumableOptions',this.consumableOptions)
      this.consumableOptions.forEach(item => {
        if (item.id === this.formTwo.id) {
          this.consumables.push({
            itemNumber: null,
            type: this.findType(item.consumablesType),
            consumablesName: item.consumablesName,
            specifications: item.specifications,
            supplier: item.supplierName,
            unit: item.unit,
            unitPrice: this.formTwo.unitPrice,
            storeNumber: this.formTwo.storeNumber,
            totalPrice: this.formTwo.totalPrice,
          });
        }
      })
    },
    deleteTableData(index) {
      this.consumables.splice(index, 1);
    },
    // æ‰“开弹框
    addOrUpdateStore(type,row) {
      if (type === 'edit') {
        this.dialogType = "update";
        selectStoreById({id:row.id}).then(res => {
          if (res.code === 201) return
          this.consumables = res.data.consumables
          this.form = {...res.data.store}
        }).catch(err => {
          console.log('err---', err);
        })
      } else {
        this.dialogType = "add";
      }
      this.dialogVisible = true;
    },
    // æŸ¥è¯¢åˆ—表
    searchList () {
      this.tableLoading = true
      storeList({...this.page,...this.searchForm}).then(res => {
        this.tableLoading = false
        if (res.code === 200){
          this.storageTableData = res.data.records
          this.page.total = res.data.total
        }
      }).catch(err => {
        console.log('err---', err);
        this.tableLoading = false
      })
    },
    // å¯¼å‡ºexcel
    async importExcel() {
      exportProcurementSuppliesStoreExcel({parentId:this.contentsId}).then(res => {
        const blob = new Blob([res], {type: 'application/octet-stream'});
        this.$download.saveAs(blob, '耗材入库.xlsx')
        this.$message.success('导出成功')
      })
    },
    handleClose() {
      this.form = {
        oddNumbers: null,
        inventory: null,
        totalAmount: null,
        storageTime: null,
        storageUser: null,
        remark: null,
      };
      this.formTwo = {
        consumablesName: null,
        unitPrice: null,
        storeNumber: null,
        totalPrice: null,
      };
      this.consumables = [];
      this.dialogVisible = false;
    },
    viewIssued(row) {
      console.log(row);
    },
    // èŽ·å–æ‰€æœ‰ç”¨æˆ·
    getUserList() {
      selectUserCondition().then((res) => {
          this.users = res.data;
        });
    },
    async fetchListOptions() {
      procurementSuppliesList({contentsId: this.contentsId}).then(res => {
        if (res.code === 200) {
          this.consumableOptions = res.data.records
        }
      })
    },
    // åˆ é™¤
    deleteStore (row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        console.log('row>>>>>>>>>>>>>>s',row)
        deleteStore({
          id:row.id,
          consumablesId:row.consumablesId
        }).then(res => {
          this.tableLoading = false
          if (res.code === 200){
            this.$message.success('删除成功')
            this.searchList()
          }
        }).catch(err => {
          this.tableLoading = false
          console.log('err---', err);
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    pagination(page) {
      this.page.size = page.limit
      this.searchList();
    },
  },
};
</script>
<style scoped>
.el-dialog {
  margin: 6vh auto 50px !important;
}
.el-dialog__body {
  max-height: 42em;
  overflow-y: auto;
}
.input-form {
  display: flex;
  margin: 10px 0;
}
</style>
src/views/CNAS/externalService/serviceAndSupplyPro/component/contents.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,312 @@
<template>
  <div class="parent-class">
    <div style="display: flex; justify-content: flex-end; margin-right: 20px">
      <el-button
        type="primary"
        @click="addContents"
        size="small"
        icon="el-icon-plus"
        >添加子节点</el-button
      >
      <el-button
        type="danger"
        @click="deletetContents"
        size="small"
        icon="el-icon-delete"
        >删除子节点</el-button
      >
      <el-button
        type="warning"
        @click="updateContents"
        size="small"
        icon="el-icon-edit"
        >更新子节点</el-button
      >
    </div>
    <el-form label-width="100px">
      <el-form-item label="节点名称">
        <el-input
          v-model="form.nodeName"
          style="width: 200px"
          size="small"
        ></el-input>
      </el-form-item>
      <el-form-item label="代号">
        <el-input
          v-model="form.code"
          style="width: 200px"
          size="small"
        ></el-input>
      </el-form-item>
      <el-form-item label="更新人">
        <el-select v-model="form.updateUser">
          <el-option
            v-for="item in users"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="更新时间">
        <el-input
          v-model="form.updateTime"
          style="width: 200px"
          size="small"
        ></el-input>
      </el-form-item>
    </el-form>
    <!-- æ–°å¢žå¼¹æ¡† -->
    <el-dialog title="添加节点" :visible.sync="dialogVisible" width="40%">
      <el-form
        label-width="100px"
        :model="addForm"
        ref="addForm"
        :rules="rules"
      >
        <el-form-item label="父节点名称">
          <!-- <el-select v-model="addForm.parentId">
              <el-option v-for="(item,index) in nodeNames" :key="index" :label="item.nodeName" :value="item.id"></el-option>
            </el-select> -->
          <el-cascader
            v-model="addForm.parentId"
            :options="treeData"
            :props="{ checkStrictly: true, value: 'id', label: 'nodeName' }"
            clearable
          ></el-cascader>
        </el-form-item>
        <el-form-item label="节点名称" prop="nodeName">
          <el-input
            v-model="addForm.nodeName"
            style="width: 200px"
            size="small"
          ></el-input>
        </el-form-item>
        <el-form-item label="代号">
          <el-input
            v-model="addForm.code"
            style="width: 200px"
            size="small"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitForm">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  addSuppliersDirectoryContents,
  updateSuppliersDirectoryContents,
  deleteSuppliersDirectoryContentsById,
  getSuppliersDirectoryContentsNodeNames,
  selectUserCondition,
  selectProcurementSuppliesContentById,
  getProcurementSuppliesContentsNodeNames,
  addProcurementSuppliesContents, deleteProcurementSuppliesContentById
} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
export default {
  props: {
    id: {
      type: Number,
      default: 0,
    },
    treeData: {
      type: Array,
      default: () => [],
    },
    from: {
      type: String,
      default: "耗材树"
    }
  },
  data() {
    return {
      nodeNames: [],
      users: [],
      dialogVisible: false,
      form: {
        nodeName: "",
        code: "",
        updateUser: "",
        updateTime: "",
      },
      addForm: {
        nodeName: "",
        code: "",
        updateUser: "",
        updateTime: "",
        parentId: null,
      },
      rules: {
        nodeName: [
          { required: true, message: "请输入节点名称", trigger: "blur" },
        ],
      },
    };
  },
  mounted() {
    if (this.id !== 0) {
      this.getContentsDetail();
    }
    this.getNodeNames();
    this.getUserList();
  },
  watch: {
    id(newVal, oldVal) {
      if (newVal !== 0) {
        console.log(newVal, oldVal);
        this.getContentsDetail();
      }
    },
  },
  methods: {
    // èŽ·å–ç›®å½•è¯¦æƒ…
    getContentsDetail() {
      selectProcurementSuppliesContentById({id:this.id})
        .then((res) => {
          if (res.data == null) {
            this.form = {
              nodeName: "",
              code: "",
              updateUser: "",
              updateTime: "",
            };
            return;
          }
          this.form = res.data;
        });
    },
    // æ–°å»º
    addContents() {
      this.dialogVisible = true;
      this.resetForm();
    },
    resetForm() {
      this.addForm = {
        nodeName: "",
        code: "",
        updateUser: "",
        updateTime: "",
        parentId: null,
      };
    },
    async submitForm() {
      let flag = true;
      this.$refs.addForm.validate((valid) => {
        if (!valid) {
          flag = false;
          return false;
        }
      });
      if (this.addForm.parentId) {
        this.addForm.parentId =
          this.addForm.parentId[this.addForm.parentId.length - 1];
      }
      if (!flag) {
        return;
      }
      try {
        let res = null
        console.log('this.from',this.from)
        if(this.from == '耗材树' ){
          console.log('111')
          res = await addProcurementSuppliesContents(this.addForm)
        }else {
          console.log('222')
          res = await addSuppliersDirectoryContents(this.addForm)
        }
        if (res.code === 200) {
          this.$message.success("添加成功");
          this.dialogVisible = false;
          this.$emit("contentsUpdate", res.data);
          this.getContentsDetail();
        }
      }catch (error){
        this.$message.error("添加失败");
      }
    },
    // æ›´æ–°
    updateContents() {
      Object.keys(this.form).forEach((key) => {
        if (key == "children") {
          delete this.form[key];
        }
      });
      updateSuppliersDirectoryContents(this.form).then((res) => {
          if (res.code === 200) {
            this.$message.success("更新成功");
            this.$emit("contentsUpdate", this.id);
            this.dialogVisible = false;
            this.getContentsDetail();
          }
        });
    },
    // åˆ é™¤
    deletetContents() {
      if (
        this.form.id == null ||
        this.form.id == "" ||
        this.form.id == undefined
      ) {
        this.$message.error("请选择要删除的节点");
        return;
      }
      this.$confirm("此操作将删除该节点, æ˜¯å¦ç»§ç»­?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        if(this.from == '耗材树'){
          deleteProcurementSuppliesContentById({id:this.form.id}).then((res) => {
            if (res.code == 200) {
              this.$message.success("删除成功");
              this.$emit("contentsUpdate", this.form.parentId, true);
              this.getContentsDetail();
            }
          });
        }else {
          deleteSuppliersDirectoryContentsById({id:this.form.id}).then((res) => {
            if (res.code == 200) {
              this.$message.success("删除成功");
              this.$emit("contentsUpdate", this.form.parentId, true);
              this.getContentsDetail();
            }
          });
        }
      });
    },
    // èŽ·å–æ‰€æœ‰ç›®å½•èŠ‚ç‚¹
    getNodeNames() {
      if(this.from == '耗材树'){
        getProcurementSuppliesContentsNodeNames().then(res => {
          this.nodeNames = res.data;
        })
      }else {
        getSuppliersDirectoryContentsNodeNames().then(res => {
          this.nodeNames = res.data;
        })
      }
    },
    // èŽ·å–æ‰€æœ‰ç”¨æˆ·
    getUserList() {
      selectUserCondition().then((res) => {
        this.users = res.data;
      })
    },
  },
  created() {},
};
</script>
  <style scoped>
.parent-class {
  margin-top: 20px;
}
</style>
src/views/CNAS/externalService/serviceAndSupplyPro/index.vue
@@ -27,30 +27,33 @@
        <el-tab-pane label="耗材总览" name="first" :lazy="true">
          <ConsumableOverview v-if="activeName == 'first'" :contentsId="contentsId"></ConsumableOverview>
        </el-tab-pane>
<!--        <el-tab-pane label="耗材列表" name="second" :lazy="true">-->
<!--          <ConsumableList v-if="activeName == 'second'" :contentsId="contentsId"></ConsumableList>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="耗材入库" name="third" :lazy="true">-->
<!--          <Store v-if="activeName == 'third'" :contentsId="contentsId"></Store>-->
<!--        </el-tab-pane>-->
<!--        <el-tab-pane label="目录维护" name="fourth" :lazy="true">-->
<!--          <Contents-->
<!--            v-if="activeName == 'fourth'"-->
<!--            :id="contentsId"-->
<!--            @contentsUpdate="contentsUpdate"-->
<!--            :treeData="treeData"-->
<!--            from="耗材树"-->
<!--          ></Contents>-->
<!--        </el-tab-pane>-->
        <el-tab-pane label="耗材列表" name="second" :lazy="true">
          <ConsumableList v-if="activeName == 'second'" :contentsId="contentsId"></ConsumableList>
        </el-tab-pane>
        <el-tab-pane label="耗材入库" name="third" :lazy="true">
          <Store v-if="activeName == 'third'" :contentsId="contentsId"></Store>
        </el-tab-pane>
        <el-tab-pane label="目录维护" name="fourth" :lazy="true">
          <Contents
            v-if="activeName == 'fourth'"
            :id="contentsId"
            @contentsUpdate="contentsUpdate"
            :treeData="treeData"
            from="耗材树"
          ></Contents>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>
<script>
// import Contents from "@/components/do/a6.service-and-supply-purchase/contents.vue";
// import Store from "@/components/do/a6.service-and-supply-purchase/store.vue";
import ConsumableOverview from "../serviceAndSupplyPro/component/ConsumableOverview.vue";
// import ConsumableList from "@/components/do/a6.service-and-supply-purchase/ConsumableList.vue"
import Contents from "./component/contents.vue";
import Store from "./component/Store.vue";
import ConsumableOverview from "./component/ConsumableOverview.vue";
import ConsumableList from "./component/ConsumableList.vue"
import {
  directoryListing
} from '@/api/cnas/externalService/serviceAndSupplyPro/serviceAndSupplyPro'
export default {
  data() {
@@ -70,10 +73,10 @@
    };
  },
  components: {
    // Contents,
    // Store,
    ConsumableOverview
    // ConsumableList
    Contents,
    Store,
    ConsumableOverview,
    ConsumableList
  },
  watch: {
    contentsId(newVal, oldVal) {
@@ -129,9 +132,7 @@
    },
    // æŸ¥è¯¢æ‰€æœ‰ç›®å½•
    getTreeData() {
      this.$axios
        .get(this.$api.procurementSuppliesContents.directoryListing)
        .then((res) => {
      directoryListing().then((res) => {
          this.treeData = res.data;
        });
    },
src/views/CNAS/personnel/personalOverview/index.vue
src/views/CNAS/personnel/personnelInfo/components/AddInDetail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,175 @@
<template>
  <div>
    <el-dialog :visible.sync="addTrainingPlanDia" title="新增培训计划" width="50%" @close="closeAdd">
      <div class="body">
        <el-form ref="trainingPlanForm" :model="trainingPlan" label-position="right" label-width="90px" :rules="trainingPlanRules">
          <el-row>
            <el-col :span="12">
              <el-form-item label="培训日期:" prop="trainingDate">
                <el-date-picker v-model="trainingPlan.trainingDate" format="yyyy-MM"
                                placeholder="选择日期" size="small" value-format="yyyy-MM"
                                type="month" style="width: 100%"></el-date-picker>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="课时:" prop="classHour">
                <el-input type="number" v-model="trainingPlan.classHour" label="描述文字" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训目标:" prop="trainingObjectives">
                <el-input v-model="trainingPlan.trainingObjectives" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="参加对象:" prop="participants">
                <el-input v-model="trainingPlan.participants" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训内容:" prop="trainingContent">
                <el-input v-model="trainingPlan.trainingContent" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训讲师:" prop="trainingLecturerId">
                <el-select v-model="trainingPlan.trainingLecturerId"
                           clearable filterable
                           placeholder="请选择" size="small" style="width: 100%;">
                  <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="培训方式:" prop="trainingMode">
                <el-input v-model="trainingPlan.trainingMode" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="举办部门:" prop="holdingDepartment">
                <el-input v-model="trainingPlan.holdingDepartment" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="备注:" prop="remarks">
                <el-input v-model="trainingPlan.remarks" placeholder="请输入" size="small"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
                <el-button @click="closeAdd">取 æ¶ˆ</el-button>
        <el-button type="primary" :loading="submitAddLoading" @click="submitAdd">ç¡® å®š</el-button>
            </span>
    </el-dialog>
  </div>
</template>
<script>
import {addOrUpdatePersonTrainingDetailed} from "@/api/cnas/personal/personalTraining";
import {selectUserCondition} from "@/api/system/user";
export default {
  props: {
    currentChangeRow: {
      type: Object,
      default: () => {
        return {}
      }
    },
  },
  name: 'Add',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      addTrainingPlanDia: false,
      submitAddLoading: false,
      trainingPlan: {
        planId: '',
        id: '',
        trainingDate: '',
        classHour: '',
        trainingObjectives: '',
        participants: '',
        trainingContent: '',
        trainingLecturerId: '',
        trainingMode: '',
        holdingDepartment: '',
        remarks: '',
      },
      trainingPlanRules: {
        trainingDate: [{ required: true, message: '请选择培训日期', trigger: 'change' }],
        trainingContent: [{ required: true, message: '请输入培训内容', trigger: 'blur' }],
        trainingLecturerId: [{ required: true, message: '请选择培训讲师', trigger: 'blur' }],
      },
      responsibleOptions: [],
      operationType: ''
    };
  },
  // æ–¹æ³•集合
  methods: {
    showDialog(id, type, row) {
      this.addTrainingPlanDia = true;
      this.operationType = type
      if (this.operationType === 'edit') {
        this.trainingPlan = this.HaveJson(row)
      } else {
        this.trainingPlan = {
          id: '',
          trainingDate: '',
          classHour: '',
          trainingObjectives: '',
          participants: '',
          trainingContent: '',
          trainingLecturerId: '',
          trainingMode: '',
          holdingDepartment: '',
          remarks: '',
        }
      }
      this.trainingPlan.planId = id
      this.getUserList()
    },
    // æäº¤æ–°å¢ž
    submitAdd() {
      this.$refs.trainingPlanForm.validate((valid) => {
        if (valid) {
          this.submitAddLoading = true
          this.trainingPlan.planId = this.currentChangeRow.id
          const personTrainingDetailed = this.trainingPlan
          addOrUpdatePersonTrainingDetailed(personTrainingDetailed).then(res => {
            this.submitAddLoading = false
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.closeAdd();
            }
          }).catch(() => {
            this.submitAddLoading = false
          })
        }
      })
    },
    // å…³é—­å¼¹æ¡†
    closeAdd() {
      this.$refs['trainingPlanForm'].resetFields();
      this.$emit('search')
      this.addTrainingPlanDia = false;
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      selectUserCondition().then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      })
    },
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/components/Edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,452 @@
<template>
  <div>
    <div class="page-header">
      <h4><span class="line"></span><span>培训与考核记录</span></h4>
      <div class="btns">
        <el-button size="small" type="primary" @click="submitForm(3)" v-if="this.currentRow.state !== 1">撤销</el-button>
        <el-button size="small" type="primary" @click="submitForm(0)" v-if="this.currentRow.state !== 1">提交</el-button>
        <el-button size="small" @click="$emit('goBack')">返回</el-button>
      </div>
    </div>
    <div class="form_title">
      <el-row>
        <el-col :span="7">
          <span class="form_label">培训内容:</span>
          <span> {{ trainingForm.trainingContent }} </span>
        </el-col>
        <el-col :span="5">
          <span class="form_label">状态:</span>
          <el-tag v-if="trainingForm.state === 1" type="success">已完成</el-tag>
          <el-tag v-if="trainingForm.state === 2" type="warning">待评价</el-tag>
          <el-tag v-if="trainingForm.state === 3" type="primary">未开始</el-tag>
        </el-col>
        <el-col :span="4">
          <span class="form_label">培训讲师:</span>
          <span> {{ trainingForm.trainingLecturerName }} </span>
        </el-col>
      </el-row>
      <el-row style="margin: 15px 0">
        <el-form>
          <el-row>
          <el-col :span="5">
            <el-form-item label="培训日期:">
              <el-date-picker v-model="trainingForm.openingTime" format="yyyy-MM-dd" :disabled="currentRow.state !== 3"
                              placeholder="选择日期" size="small" value-format="yyyy-MM-dd"
                              type="date" style="width: 60%"></el-date-picker>
            </el-form-item>
          </el-col>
            <el-col :span="7">
              <el-form-item label="培训地点">
                <el-input v-model="trainingForm.placeTraining" :disabled="currentRow.state !== 3" :rows="2" placeholder="请输入"
                          size="small" style="width: 60%" type="text"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="评价人">
                <el-select v-model="trainingForm.assessmentUserId" :disabled="currentRow.state !== 3" placeholder="请选择" size="small" style="width: 50%">
                  <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="考核方式">
                <el-input v-model="trainingForm.assessmentMethod" :disabled="currentRow.state !== 3" :rows="2" placeholder="请输入"
                          size="small" style="width: 79%" type="textarea"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="评价时间">
                <el-date-picker v-model="trainingForm.assessmentDate" :disabled="currentRow.state !== 2 || isDisabled"
                                type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" size="small"
                                placeholder="选择日期">
                </el-date-picker>
              </el-form-item>
            </el-col>
          <el-col :span="12">
            <el-form-item label="本次培训综合评价">
              <el-input v-model="trainingForm.comprehensiveAssessment" :disabled="currentRow.state !== 2 || isDisabled" :rows="2" placeholder="请输入"
                        size="small" style="width: 68%" type="textarea"></el-input>
            </el-form-item>
          </el-col>
          </el-row>
        </el-form>
      </el-row>
    </div>
    <el-divider>人员详情</el-divider>
    <div>
      <div class="items_center">
        <span>姓名</span>
        <el-input v-model="userName" class="search" placeholder="请输入"
                  size="small"></el-input>
        <el-button size="small" type="primary" @click="getInfo">查询</el-button>
      </div>
      <div class="items_btn">
        <el-button :disabled="currentRow.state === 1" size="small" type="primary" @click="addPerson">新增人员</el-button>
        <el-button :disabled="currentRow.state === 1" size="small" @click="batchDelete">批量删除</el-button>
      </div>
      <el-table :data="trainingTableData" height="calc(100vh - 30em)" stripe style="width: 100%"
                @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column label="序号" type="index" width="60"></el-table-column>
        <el-table-column label="姓名" prop="userName"></el-table-column>
        <el-table-column label="工号" prop="account"></el-table-column>
        <el-table-column label="角色" prop="roleName"></el-table-column>
        <el-table-column label="电话号码" prop="phone"></el-table-column>
        <el-table-column label="考核结果" prop="examinationResults">
          <template v-slot="scope">
            <el-input v-model="scope.row.examinationResults" :disabled="currentRow.state === 1" clearable size="small" style="width: 100%" @blur="updatePersonResult(scope.row)"></el-input>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog :visible.sync="selectUserDia" title="选择用户" width="70%">
      <div class="search" style="margin-bottom: 9px;">
        <div class="search_thing">
          <div class="search_label">用户名:</div>
          <div class="search_input">
            <el-input
              v-model="addUserTableInfo.name"
              clearable
              placeholder="请输入"
              size="small"
              @keyup.enter.native="selectUserList"
            ></el-input>
          </div>
        </div>
      </div>
      <div v-if="selectUserDia" class="body" style="height: 60vh;">
        <lims-table :tableData="tableData1" :column="column1"
                    :isSelection="true" :handleSelectionChange="selectMethod"
                    @pagination="pagination1" :height="'calc(100vh - 290px)'"
                    :page="page1" :tableLoading="tableLoading1"></lims-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="selectUserDia = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="selectUser">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import {selectUserCondition} from "@/api/business/inspectionTask";
import {mapGetters} from "vuex";
import {
  newPersonnelAddedToTrainingRecords,
  outOfFocusPreservation, trainingAndAssessmentRecordsAdded, trainingAndAssessmentRecordsEvaluate,
  trainingAndAssessmentRecordsPage
} from "@/api/cnas/personal/personalTraining";
export default {
  name: 'Edit',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {limsTable},
  props: {
    currentRow: {
      type: Object,
      default: () => {
        return {}
      }
    },
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      isSelectedList: [], // ç¦ç”¨çš„多选
      userName: undefined,
      trainingForm: {
        code: '111111',
        date: '2024-10-10',
      },
      trainingColumn: [
        {
          label: '姓名',
          prop: 'userName'
        },
        {
          label: '工号',
          prop: 'account'
        },
        {
          label: '角色',
          prop: 'roleName'
        },
        {
          label: '电话号码',
          prop: 'phone'
        },
        {
          label: '考核结果',
          prop: 'result'
        }
      ],
      trainingTableData: [],
      trainingLoading: false,
      isDisabled: false,
      selectUserDia: false, // æ·»åŠ äººå‘˜å¼¹æ¡†
      tableData1: [],
      tableLoading1: false,
      column1: [
        {label: '姓名', prop: 'name'},
        {label: '账号', prop: 'account'},
        {label: '角色', prop: 'roleName'},
        {
          dataType: 'tag',
          label: '状态',
          prop: 'status',
          formatData: (params) => {
            if (params == 0) {
              return '启用'
            } else {
              return ''
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'success'
            } else {
              return 'danger'
            }
          }
        },
        {label: '电话号码', prop: 'phone'},
      ],
      page1: {
        total:0,
        size:10,
        current:1
      },
      addUserTableInfo: {
        name: null,
      },
      multipleSelection: [],
      userList: [],
    };
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  mounted() {
    this.trainingForm = this.currentRow
    this.getInfo()
    this.getUserList()
    this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
  },
  // æ–¹æ³•集合
  methods: {
    // èŽ·å–å½“å‰æ•°æ®
    async getInfo() {
      this.trainingLoading = true
      await trainingAndAssessmentRecordsPage({
        trainingDetailedId: this.currentRow.id,
        userName: this.userName
      }).then(res => {
        if (res.code === 200) {
          this.trainingTableData = res.data
        }
        this.trainingLoading = false
      })
    },
    updatePersonResult(row) {
      outOfFocusPreservation(row).then(res => {
        this.$message.success("操作成功!")
      })
    },
    addPerson() {
      this.isSelectedList = this.trainingTableData.map(item => item.userId)
      this.selectUserDia = true;
    },
    selectUserList () {
      this.tableLoading1 = true
      selectUserCondition({...this.addUserTableInfo}).then(res => {
        this.tableData1 = res.data.records
        this.page1.total = res.data.total
      }).catch(err => {
        this.tableLoading1 = false
      })
    },
    pagination1 (page) {
      this.page1.size = page.limit
      this.selectUserList()
    },
    // è¡¨æ ¼é€‰æ‹©æ–¹æ³•
    selectMethod(val) {
      this.multipleSelection = val
    },
    selectUser() {
      let selects = this.multipleSelection;
      if (selects.length == 0) {
        this.$message.error('未选择数据');
        return;
      }
      let list = []
      selects.forEach(a => {
        const obj = {
          courseId: this.currentRow.id,
          examinationResults: "",
          userId: a.id
        }
        list.push(obj)
      });
      newPersonnelAddedToTrainingRecords(list).then(res => {
        this.isSelectedList = []
        this.selectUserDia = false;
        this.getInfo()
      })
    },
    // æ‰¹é‡åˆ é™¤
    handleSelectionChange(list) {
      this.multipleSelection = list
    },
    batchDelete() {
      if (this.multipleSelection.length > 0) {
        let ids = this.multipleSelection.map(item => item.trainingRecordId)
        this.$confirm('是否确认删除所选择的数据?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          let formData = new FormData()
          formData.append('ids', ids)
          deleteTrainingAndAssessmentRecords(formData).then(res => {
            if (res.code == 200) {
              this.$message.success('删除成功');
              this.getInfo()
            }
          });
        }).catch(() => {
          this.$message.warning('取消删除');
        });
      } else {
        this.$message.warning('请选择需要删除的数据')
      }
    },
    handleSizeChange(val) {
      this.search.size = val;
      this.getInfo();
    },
    handleCurrentChange(val) {
      this.search.current = val;
      this.getInfo();
    },
    /**
     * @desc æäº¤è¡¨å•
     */
    async submitForm(status) {
      let state = this.currentRow.state
      if (this.trainingForm.assessmentUserId) {
        state = 2
      }
      if (this.trainingForm.comprehensiveAssessment) {
        state = 1
      }
      if (status === 3) {
        state = 3
      }
      let data = {
        assessmentMethod: this.trainingForm.assessmentMethod,
        openingTime: this.trainingForm.openingTime,
        placeTraining: this.trainingForm.placeTraining,
        comprehensiveAssessment: this.trainingForm.comprehensiveAssessment,
        trainingDetailedId: this.trainingForm.id,
        assessmentUserId: this.trainingForm.assessmentUserId,
        assessmentDate: this.trainingForm.assessmentDate,
        state: state
      }
      let code = {}
      if (state === 2) {
        code = await trainingAndAssessmentRecordsAdded(data)
      } else {
        code = await trainingAndAssessmentRecordsEvaluate(data)
      }
      this.isDisabled = this.trainingForm.assessmentUserId !== this.userId
      if(code.code === 200) {
        this.currentRow.state = state
        this.$message.success("操作成功")
      }
    },
    getUserList(){
      selectUserCondition({ type: 0 }).then((res) => {
        this.userList = res.data;
      })
    },
  }
};
</script>
<style scoped>
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  margin-bottom: 10px;
}
h4 {
  display: flex;
  align-items: center;
}
h4 .line {
  display: inline-block;
  width: 3px;
  height: 16px;
  background: #3A7BFA;
  margin-right: 4px;
}
.form_title {
  font-size: 14px;
  padding: 0 20px;
  margin-bottom: 10px;
}
.el-divider {
  margin: 0 1em 1em 0;
}
.form__input_label {
  width: 90px;
  margin-right: 6px;
  color: #606266;
}
.form__input_label2 {
  width: 210px;
  margin-right: 6px;
  color: #606266;
}
.search_thing {
  display: flex;
  align-items: center
}
.search_label {
  width: 120px;
}
.pagination {
  display: flex;
  justify-content: space-between
}
.items_center {
  float: left;
  width: 50%;
  text-align: left;
}
.items_btn {
  text-align: right;
  width: 50%;
  float: right;
  margin-bottom: 1em;
}
.search {
  width: 180px;
  padding: 0 16px;
}
</style>
src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,186 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="附件上传" width="80%" @closed="closeFilesLook">
      <div style="display: flex;justify-content: space-between;">
        <el-upload ref='upload'
                   :action="fileAction"
                   :auto-upload="true"
                   :before-upload="fileBeforeUpload" :data="{trainingDetailedId: info.id}"
                   :headers="uploadHeader" :on-error="onError"
                   :on-success="handleSuccessUp"
                   :show-file-list="false"
                   accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
          <el-button size="small" style="height: 38px" type="primary">附件上传</el-button>
        </el-upload>
      </div>
      <div>
        <lims-table :tableData="tableData" :column="columnData"
                    :height="'calc(100vh - 47em)'"
                    :highlightCurrentRow="true"
                    :tableLoading="tableLoading"></lims-table>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="lookDialogVisible"
      fullscreen
      title="查看附件" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}"
                   :fileUrl="javaApi+'/word/'+currentInfo.fileUrl" style="height: 90vh;overflow-y: auto;top: 0"/>
    </el-dialog>
  </div>
</template>
<script>
import file from '@/utils/file';
import filePreview from '@/components/Preview/filePreview.vue';
import limsTable from "@/components/Table/lims-table.vue";
import {delTrainingDetailedFileList, getTrainingDetailedFileList} from "@/api/cnas/personal/personalTraining";
import {delCustomById} from "@/api/system/customer";
export default {
  name: 'ViewRecord',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {limsTable, filePreview },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '预览',
              type: 'text',
              clickFun: (row) => {
                this.handleLook(row)
              }
            },
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delete(row)
              }
            }
          ]
        }
      ],
      tableData: [],
      info: {},
      currentInfo:{},
      lookDialogVisible: false,
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      this.searchTableList()
    },
    // æŸ¥è¯¢é™„件列表
    searchTableList () {
      this.tableLoading = true
      getTrainingDetailedFileList({trainingDetailedId: this.info.id}).then(res => {
        this.tableLoading = false
        this.tableData = res.data
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    closeFilesLook () {
      this.filesDialogVisible = false
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
    // åˆ é™¤
    delete (row) {
      this.$confirm('是否删除当前数据?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.tableLoading = true
        delTrainingDetailedFileList({detailedFileId: row.detailedFileId}).then(res => {
          this.tableLoading = false
          this.$message.success('删除成功')
          this.searchTableList()
        }).catch(err => {
          this.tableLoading = false
          console.log('err---', err);
        })
      }).catch(() => {})
    },
    // ä¸Šä¼ éªŒè¯
    fileBeforeUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    onError(err, file, fileList,type) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response, ) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchTableList()
      }
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row){
      this.currentInfo = row
      this.lookDialogVisible = true
    },
  },
  computed: {
    fileAction() {
      return this.javaApi + '/personTraining/uploadTrainingDetailedFile'
    }
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/components/communicateAdd.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,136 @@
<template><div class="add">
  <el-dialog
    :title="isEdit ?'编辑附件资料':'新增附件资料'"
    :visible.sync="dialogVisible"
    width="40%"
  >
    <el-form
      :model="form"
      ref="form"
      :rules="rules"
      label-width="80px"
      size="small"
    >
      <el-form-item label="沟通人" prop="userId">
        <el-select
          v-model="form.userId"
          placeholder="请选择"
          style="width: 100%" multiple
        >
          <el-option
            v-for="(item, index) in userList"
            :key="index"
            :label="item.name"
            :value="item.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="沟通时间" prop="communicationTime">
        <el-date-picker
          v-model="form.communicationTime"
          type="datetime"
          value-format="yyyy-MM-dd HH:mm:ss"
          placeholder="请选择日期时间"
          style="width: 100%"
        >
        </el-date-picker>
      </el-form-item >
      <el-form-item label="沟通地点" prop="communicationPlace">
        <el-input v-model="form.communicationPlace" placeholder="请填写沟通地点"></el-input>
      </el-form-item >
      <el-form-item label="沟通内容" prop="communicationContent">
        <el-input v-model="form.communicationContent" placeholder="请填写沟通内容"></el-input>
      </el-form-item >
    </el-form>
    <div slot="footer" class="foot">
      <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
      <el-button type="primary" :loading="loading" @click="submitForm">ç¡® å®š</el-button>
    </div>
  </el-dialog>
</div>
</template>
<script>
import {selectUserCondition} from "@/api/business/inspectionTask";
import {addOrUpdatePersonCommunicationAbility} from "@/api/cnas/personal/personPersonCommunicationAbilityPage";
export default {
  data() {
    return {
      isEdit: false,
      dialogVisible: false,
      form: {
        id: '',
        userId: [],
        communicationTime: undefined,
        communicationPlace: undefined,
        communicationContent: undefined
      },
      rules: {
        userId: [{ required: true, message: '请选择沟通人', trigger: 'change' }],
        communicationTime: [{ required: true, message: '请选择沟通时间', trigger: 'change' }],
        communicationPlace: [{ required: true, message: '请填写沟通地点', trigger: 'blur' }],
        communicationContent: [{ required: true, message: '请填写沟通内容', trigger: 'blur' }],
      },
      loading: false,
      userList: []
    }
  },
  methods: {
    /**
     * @desc æ˜¾ç¤ºæ¨¡æ€æ¡†
     * @param {*} row
     * @param {*} type
     */
    openDialog(row, type) {
      this.getUserList()
      this.dialogVisible = true
      if(type) {
        this.isEdit = true
        this.form.id = row.id
        this.form.userId = row.userId.split(',').map(m=>Number(m))
        this.form.communicationTime = row.communicationTime
        this.form.communicationPlace = row.communicationPlace
        this.form.communicationContent = row.communicationContent
      } else {
        this.form.id = ''
        this.resetForm('form')
      }
    },
    /**
     * @desc èŽ·å–ç”¨æˆ·ä¿¡æ¯
     */
    async getUserList() {
      selectUserCondition().then((res) => {
        this.userList = res.data;
      })
    },
    /**
     * @desc æäº¤è¡¨å•
     */
    async submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.loading = true
          const params = {
            id: this.form.id,
            userId: this.form.userId.join(','),
            communicationTime: this.form.communicationTime,
            communicationPlace: this.form.communicationPlace,
            communicationContent: this.form.communicationContent,
          }
          addOrUpdatePersonCommunicationAbility(params).then((res) => {
            this.loading = false
            this.resetForm('form')
            this.$emit('submit')
            this.dialogVisible = false
          }).catch((err) => {
            this.loading = false
          })
        }
      })
    }
  }
}
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/components/mandateAdd.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,200 @@
<template>
  <div class="add">
    <el-dialog
      :title="isEdit ?'编辑附件资料':'新增附件资料'"
      :visible.sync="dialogVisible"
      width="50%"
    >
      <el-form
        ref="ruleForm"
        :rules="rules"
        :model="form"
        label-width="130px"
        size="medium"
      >
        <el-form-item label="证书编号" prop="certificateNumber">
          <el-input v-model="form.certificateNumber" placeholder="请输入" style="width: 100%">
          </el-input>
        </el-form-item >
        <el-form-item label="被任职人员" prop="userId">
          <el-select v-model="form.userId" placeholder="请选择">
            <el-option
              v-for="(item, index) in userList"
              :key="index"
              :label="item.name"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item >
        <el-form-item label="任职岗位" prop="post">
          <el-input v-model="form.post" placeholder="请输入"></el-input>
        </el-form-item >
        <el-form-item label="理论考试成绩" prop="num1">
          <el-input v-model="form.num1" placeholder="请输入"></el-input>
        </el-form-item >
        <el-form-item label="操作技能考试成绩" prop="num2">
          <el-input v-model="form.num2" placeholder="请输入"></el-input>
        </el-form-item >
        <el-form-item label="操作类型" prop="operationType">
          <el-input v-model="form.operationType" placeholder="请选择"></el-input>
        </el-form-item >
        <el-row>
          <el-col :span="20">
            <el-form-item label="上岗证书">
              <el-input v-model="form.systemFileName" size="small" disabled>
                <el-button slot="append" icon="el-icon-delete-solid"
                           @click="deleteFile(form.systemFileName)"></el-button>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-upload ref="upload" style="float: left; margin: 0 12px 0 20px;" :action="action"
                       :headers="uploadHeader"
                       :show-file-list="false"
                       :on-success="onSuccess">
              <el-button class="uploadFile" slot="trigger" size="small" type="primary">上传</el-button>
            </el-upload>
          </el-col>
        </el-row>
        <el-form-item label="备注">
          <el-input v-model="form.remarks" placeholder="请选择"></el-input>
        </el-form-item >
      </el-form>
      <div slot="footer" class="foot">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" :loading="loading" @click="submitForm">ç¡® å®š</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {deleteCNASFile} from "@/api/cnas/personal/personalList";
import {selectUserCondition} from "@/api/business/inspectionTask";
import {addOrUpdatePersonPostAuthorizationRecord} from "@/api/cnas/personal/personPostAuthorizationRecord";
export default {
  data() {
    return {
      isEdit: false,
      dialogVisible: false,
      form: {
        id: undefined,
        certificateNumber: undefined,
        userId: undefined,
        post: undefined,
        operationType: undefined,
        fileList: [],
        fileName: undefined,
        systemFileName: undefined,
        remarks: undefined,
        num2:undefined,
        num1:undefined
      },
      rules: {
        certificateNumber: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
        userId: [{ required: true, message: '请选择被任职人员', trigger: 'change' }],
        post: [{ required: true, message: '任职岗位', trigger: 'blur' }],
        operationType: [{ required: true, message: '操作类型', trigger: 'blur' }],
      },
      loading: false,
      userList: []
    }
  },
  computed: {
    action() {
      return this.javaApi + '/personBasicInfo/saveCNASFile'
    }
  },
  methods: {
    onSuccess(response, file, fileList) {
      this.$set(this.form, "systemFileName", response.data)
    },
    deleteFile(fileName) {
      deleteCNASFile({fileName: fileName}).then(res => {
        this.$message.success('删除成功!')
        this.$set(this.form, "systemFileName", null)
      })
    },
    async openDialog(row, type) {
      await this.getUserList()
      this.dialogVisible = true
      if(type) {
        this.isEdit = true
        this.form.id = row.id
        this.form.certificateNumber = row.certificateNumber
        this.form.userId = Number(row.userId)
        this.form.post = row.post
        this.form.operationType = row.operationType
        this.form.systemFileName = row.systemFileName
        this.form.remarks = row.remarks
        this.form.num1 = row.num1
        this.form.num2 = row.num2
      } else {
        this.resetForm('ruleForm')
      }
    },
    closeDialog() {
      this.resetForm('ruleForm')
      this.dialogVisible = false
    },
    /**
     * @desc èŽ·å–ç”¨æˆ·ä¿¡æ¯
     */
    async getUserList() {
      selectUserCondition().then((res) => {
        this.userList = res.data;
      })
    },
    /**
     * @desc æäº¤è¡¨å•
     */
    submitForm() {
      this.$refs.ruleForm.validate((valid) => {
        if(valid) {
          const params = {
            id: this.form.id,
            certificateNumber: this.form.certificateNumber,
            userId: this.form.userId,
            post: this.form.post,
            operationType: this.form.operationType,
            systemFileName: this.form.systemFileName,
            remarks: this.form.remarks,
            num1: this.form.num1,
            num2: this.form.num2
          }
          this.loading = true
          addOrUpdatePersonPostAuthorizationRecord(params).then(res => {
            this.loading = false
            this.closeDialog()
            this.$emit('refresh')
          }).catch(err => {
            this.loading = false
          })
        }
      })
    },
    /**
     * @desc ä¸Šä¼ æ–‡ä»¶
     */
    beforeUpload(file) {
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        return false;
      } else {
        this.form.fileList = [file]
        this.form.fileName = file.name
        return true;
      }
    },
  }
}
</script>
<style scoped>
.foot {
    width: 100%;
}
.add >>> .el-dialog__footer {
    padding-right: 20px;
}
</style>
src/views/CNAS/personnel/personnelInfo/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,329 @@
<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="[22]"
        :expand-on-click-node="false"
        :filter-node-method="filterNode"
        :props="{ children: 'children', label: 'name' }"
        highlight-current
        node-key="id"
        style="height:calc(100% - 70px);overflow-y: scroll;scrollbar-width: none;"
        @node-click="handleNodeClick"
        @node-expand="nodeOpen"
        @node-collapse="nodeClose"
      >
        <div slot-scope="{ node, data }" class="custom-tree-node">
          <el-row style="width: 100%;">
            <el-col :span="22" style="text-align: left;">
              <span><i
                :class="`node_i ${data.children != undefined&&data.children.length>0 ? 'el-icon-folder-opened' : 'el-icon-tickets'}`"></i>
                {{ data.name }}</span>
            </el-col>
            <el-col v-if="node.level>1 && data.id !== null" :span="2" style="text-align: right;">
              <el-button size="mini" type="text" @click.stop="remove(node, data)">
                <i class="el-icon-delete"></i>
              </el-button>
            </el-col>
          </el-row>
        </div>
      </el-tree>
    </div>
    <div class="main_right">
      <el-tabs v-model="activeName" :lazy="true" type="border-card">
        <el-tab-pane label="人员基本信息" name="人员基本信息">
          <PersonnelList v-if="activeName === '人员基本信息' && isShowAll" ref="personnelList" :currentCompaniesList="currentCompaniesList"
                         :departId="departId" @refreshTree="refreshTree"
                         @updatePerson="updatePerson"></PersonnelList>
          <personnelInformation v-if="activeName === '人员基本信息' && !isShowAll" :clickNodeVal="clickNodeVal"></personnelInformation>
        </el-tab-pane>
        <el-tab-pane label="培训计划" name="培训计划">
          <PersonnelTraining v-if="activeName === '培训计划'" ref="personnelTraining"
                             :departId="departId" :isDepartment="isDepartment"></PersonnelTraining>
        </el-tab-pane>
        <el-tab-pane label="岗位职责" name="岗位职责">
          <job-responsibilities v-if="activeName === '岗位职责'" ref="jobResponsibilities"
                                :departId="departId"
                                :isDepartment="isDepartment"></job-responsibilities>
        </el-tab-pane>
        <el-tab-pane label="奖惩记录" name="奖惩记录">
          <rewardPunishmentRecord v-if="activeName === '奖惩记录'"
                                  :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord>
        </el-tab-pane>
        <el-tab-pane label="培训记录" name="培训记录">
          <training-record v-if="activeName === '培训记录'" ref="trainingRecord"
                           :departId="departId"
                           :isDepartment="isDepartment"></training-record>
        </el-tab-pane>
        <el-tab-pane label="任职授权记录" name="任职授权记录">
          <Mandate v-if="activeName === '任职授权记录'" ref="manDateRef" :departId="departId" :isDepartment="isDepartment"></Mandate>
        </el-tab-pane>
        <el-tab-pane label="人员能力" name="人员能力">
          <personnel-capacity v-if="activeName === '人员能力'" ref="personnelCapacity"
                              :departId="departId"
                              :isDepartment="isDepartment"></personnel-capacity>
        </el-tab-pane>
        <el-tab-pane label="沟通记录" name="沟通记录">
          <Communicate v-if="activeName === '沟通记录'" ref="communicateRef" :departId="departId" :isDepartment="isDepartment"></Communicate>
        </el-tab-pane>
      </el-tabs>
    </div>
    <el-dialog :visible.sync="addDia" title="架构新增" width="400px">
      <div class="body">
        <el-row style="line-height: 50px;">
          <el-col :span="6" style="text-align: right;">
            <span class="required-span">* </span>架构名称:
          </el-col>
          <el-col :offset="1" :span="16">
            <el-input v-model="addOb.name" clearable placeholder="请输入架构名称" size="small" @keyup.enter.native="addStandardTree"></el-input>
          </el-col>
        </el-row>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDia = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="addStandardTree">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import PersonnelList from './tabs/personnel-list.vue'
import personnelInformation from './tabs/personnel-information.vue'
import PersonnelTraining from './tabs/personnelTraining';
import JobResponsibilities from './tabs/job-responsibilities.vue';
import rewardPunishmentRecord from "./tabs/reward-punishment-record.vue";
import TrainingRecord from './tabs/training-record.vue';
import Mandate from './tabs/mandate.vue';
import PersonnelCapacity from './tabs/personnel-capacity.vue';
import Communicate from './tabs/communicate.vue'
import {addDepartmentLims, delDepartmentLims, selectCNSAPersonTree} from "@/api/cnas/personal/personalList";
export default {
  components: {
    PersonnelList, personnelInformation, PersonnelTraining, JobResponsibilities, rewardPunishmentRecord, TrainingRecord, Mandate, PersonnelCapacity, Communicate
  },
  data() {
    return {
      isShowAll: true, //  æ˜¯å¦å±•示标签栏
      activeName: '人员基本信息',
      departId: 1,
      list: [],
      addDia: false,
      addOb: {
        name: '',
        fatherId: ''
      },
      search: '',
      clickNodeVal: {},
      addUserForm: {
        name: ''
      },
      currentCompaniesList: [],
      entity: {
        name: '',
        departLimsId: '',
        orderBy: {
          field: 'id',
          order: 'asc'
        }
      },
      overallRecord: '人员列表',
      isDepartment: false,
    };
  },
  mounted() {
    this.geList();
  },
  methods: {
    remove(node, data) {
      this.$confirm("是否删除该层级", "提示", {
        type: "error"
      }).then(() => {
        delDepartmentLims({
          id: data.id
        }).then(res => {
          this.$message.success('已删除')
          this.geList();
        })
      }).catch(e => {})
    },
    addStandardTree() {
      if (this.addOb.name == null || this.addOb.factory == '') {
        this.$message.error('构架名称是必填项')
        return
      }
      addDepartmentLims(this.addOb).then(res => {
        this.$message.success('添加成功')
        this.addDia = false
        this.geList();
        this.addOb.name = ''
        this.addOb.fatherId = ''
      })
    },
    handleAdd() {
      if (this.addOb.fatherId) {
        this.addDia = true;
      } else {
        this.$message.error('请选择一个架构层级')
      }
    },
    // äººå‘˜åˆ—表编辑
    updatePerson(row) {
      const node = this.findNodeById(this.list, row.name);
      if (node) {
        this.handleNodeClick(node);
      } else {
        this.$message.warning('未找到该人员');
      }
    },
    // æ–°å»ºäººå‘˜åŽåˆ·æ–°æ ‘
    refreshTree () {
      this.geList()
    },
    findNodeById(treeData, name) {
      for (let i = 0; i < treeData.length; i++) {
        if (treeData[i].name === name) {
          return treeData[i]; // æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
        }
        if (treeData[i].children && treeData[i].children.length > 0) {
          const foundNode = this.findNodeById(treeData[i].children, name);
          if (foundNode) {
            return foundNode; // åœ¨å­èŠ‚ç‚¹ä¸­æ‰¾åˆ°ï¼Œè¿”å›žè¯¥èŠ‚ç‚¹
          }
        }
      }
      return null; // æ²¡æœ‰æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žnull
    },
    searchFilter() {
      this.$refs.tree.filter(this.search);
    },
    // èŽ·å–æ ‘
    geList() {
      selectCNSAPersonTree().then(res => {
        this.list = res.data;
        if(this.list.length > 0) {
          this.isDepartment = true;
        }
      });
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },
    nodeClose(data, node, el) {
      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder');
    },
    nodeOpen(data, node, el) {
      $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder-opened');
    },
    handleNodeClick(val, node, el) {
      //树的值
      this.clickNodeVal = val;
      // å­˜å‚¨çˆ¶çº§èŠ‚ç‚¹çº§æ•°
      if (node) {
        this.getNodeParent(node);
        this.clickNodeVal.level = node.level;
        this.clickNodeVal.parent = node.parent.data;
      }
      this.entity.departLimsId = val.id;
      this.addOb.fatherId = val.id;
      // æ˜¯å¦æ˜¾ç¤ºè®¾å¤‡è¯¦æƒ…
      this.isShowAll = val.id !== null;
      if (val.id) {    // å¦‚果是实验室
        this.departId = val.id;
        this.isDepartment = true;
      }
      if (val.userId) { // æ˜¯äººå‘˜
        this.departId = val.userId;
        this.isDepartment = false
      }
    },
    getNodeParent(val) {
      if (val.parent != null) {
        this.currentCompaniesList[val.level - 1] = val.data.id;
        this.selectTree += ' - ' + val.label;
        this.getNodeParent(val.parent);
      }
    }
  }
};
</script>
<style scoped>
>>>.el-table__body-wrapper::-webkit-scrollbar {
  height: 14px;
  /* è®¾ç½®æ»šåŠ¨æ¡å®½åº¦ */
}
.node_i {
  color: orange;
  font-size: 18px;
}
.custom-tree-node {
  width: 80%;
  line-height: 32px;
}
.custom-tree-node .el-icon-delete {
  color: #3A7BFA;
  opacity: 0;
  font-size: 15px;
}
.custom-tree-node:hover .el-icon-delete {
  opacity: 1;
}
.main {
  display: flex;
  padding: 15px 0;
}
.main_left {
  background: #ffffff;
  text-align: center;
  height: calc(100vh - 8em);
  width: 270px;
  border-radius: 15px;
}
.main_right {
  width: calc(100% - 288px);
  border-radius: 15px;
}
.div_left_input {
  margin: 15px 0;
  width: 90%;
}
>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item {
  border: 0 none;
}
>>> .el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
  color: black;
}
>>> .el-tabs--border-card > .el-tabs__header {
  border-bottom: none;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/communicate.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,153 @@
<template>
  <div class="flex_column">
    <div v-if="isDepartment" style="display: flex;justify-content: space-between;margin-bottom: 10px">
      <el-button size="small" type="primary" @click="getTableData">刷新</el-button>
      <el-button size="small" type="primary" icon="el-icon-plus" @click="openDialog">新增</el-button>
    </div>
    <lims-table :tableData="tableData" :column="columnData"
                @pagination="page" :height="'calc(100vh - 18em)'"
                :page="pagination" :tableLoading="loading"></lims-table>
    <Add ref="communicateModal" @submit="getTableData"></Add>
  </div>
</template>
<script>
import CommunicateAdd from "../components/communicateAdd.vue"
import limsTable from "@/components/Table/lims-table.vue";
import {
  deletePersonCommunicationAbility, exportPersonCommunicationAbility,
  personPersonCommunicationAbilityPage
} from "@/api/cnas/personal/personPersonCommunicationAbilityPage";
export default {
  components: {
    limsTable,
    Add: CommunicateAdd
  },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      columnData: [
        {
          label: '沟通人',
          prop: 'userName'
        }, {
          label: '沟通时间',
          prop: 'communicationTime'
        }, {
          label: '沟通地点',
          prop: 'communicationPlace'
        }, {
          label: '沟通内容',
          prop: 'communicationContent'
        }, {
          label: '操作',
          dataType: 'action',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.openDialog(row, true)
              }
            }, {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.handleDown(row)
              }
            }, {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delPerson(row.id)
              }
            }
          ]
        },
      ],
      tableData: [],
      pagination: {
        current: 1,
        size: 20,
        total: 0
      },
      loading: false
    }
  },
  mounted() {
    this.getTableData()
  },
  methods: {
    openDialog(row, type=false) {
      this.$refs.communicateModal.openDialog(row, type)
    },
    getTableData() {
      this.loading = true
      const params = this.isDepartment ? {
        departLimsId: this.departId,
        current: this.pagination.current,
        size: this.pagination.size
      } : {
        userId: this.departId,
        current: this.pagination.current,
        size: this.pagination.size
      }
      personPersonCommunicationAbilityPage(params).then(res => {
        this.loading = false
        this.tableData = res.data.records
        this.pagination.total = res.data.total
      }).catch(err => {
        this.loading = false
      })
    },
    page (page) {
      this.pagination.size = page.limit
      this.getTableData()
    },
    /**
     * @desc åˆ é™¤æ²Ÿé€šè®°å½•
     */
    delPerson(id) {
      this.$confirm('此操作将永久删除该文件, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        deletePersonCommunicationAbility({id: id}).then(res => {
          this.$message.success('删除成功!');
          this.getTableData()
        })
      })
    },
    async handleDown(row){
      exportPersonCommunicationAbility({id:row.id}).then(res => {
        const blob = new Blob([res],{ type: 'application/octet-stream' });
        this.$download.saveAs(blob, row.userName+'-沟通记录'+'.docx');
      })
    }
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (newId) {
          this.getTableData();
        }
      }
    }
  }
}
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,395 @@
<!-- å²—位职责 -->
<template>
  <div class="view">
    <div style="display: flex;justify-content: space-between;">
      <el-form ref="page" size="small" :inline="true">
        <el-form-item label="员工">
          <el-input v-model="userName" clearable placeholder="请输入员工" size="small" style="width: 20vh;"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button size="small" type="primary" @click="refreshTable">查询</el-button>
        </el-form-item>
      </el-form>
      <div>
        <el-button size="small" type="primary" @click="addPost">新增</el-button>
        <!--        <el-button size="small" type="primary">导出excel</el-button>-->
      </div>
    </div>
    <div class="table">
      <el-table :data="tableData" v-loading="tableLoading" height="66.5vh" 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" align="center">
          <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" style="color: #f56c6c" 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"
                     background
                     style="margin-top: 10px"
                     @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 '@/utils/date'
import {
  exportPersonJobResponsibilities, personJobResponsibilitiesDelete,
  personJobResponsibilitiesSave,
  personJobResponsibilitiesSelect
} from "@/api/cnas/personal/personJobResponsibilities";
import {selectUserCondition} from "@/api/cnas/resourceDemand/facilitiesEnvironment/facilitiesAndEnvironment";
import {mapGetters} from "vuex";
export default {
  data() {
    return {
      userName: '',
      tableData: [],
      tableLoading: false,
      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 params = this.isDepartment ? {
        userName: this.userName,
        departmentId: this.search.userId,
        size: this.search.size,
        current: this.search.current,
      }: {
        userName: this.userName,
        userId: this.search.userId,
        size: this.search.size,
        current: this.search.current,
      }
      this.tableLoading = true
      personJobResponsibilitiesSelect(params).then(res => {
        this.tableLoading = false
        this.tableData = res.data.records;
        this.search.total = res.data.total;
      }).catch(err => {
        this.tableLoading = false
      })
    },
    //提交表单
    async submitForm(saveState) {
      this.$refs.form.validate((valid) => {
        if (valid === true || saveState !== '1submit') {
          // ç»™å½“前环节设置创建人与时间
          let user = this.nickName;
          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];
          personJobResponsibilitiesSave(this.form).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) {
      exportPersonJobResponsibilities({id:row.id}).then(res => {
        const blob = new Blob([res],{ type: 'application/octet-stream' });
        this.$download.saveAs(blob, row.incumbentName+'-岗位职责'+'.docx');
        this.$message.success('导出成功')
      })
    },
    // åˆ é™¤å²—位职责
    deletePost(row) {
      this.$confirm('此操作将永久删除此数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        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() {
      selectUserCondition().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);
      }
    }
  },
  computed: {
    ...mapGetters(['nickName'])
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/tabs/mandate.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,178 @@
<template>
  <div class="flex_column">
    <div>
      <div v-if="isDepartment" style="display: flex;justify-content: space-between;margin-bottom: 10px">
        <el-button size="small" type="primary" @click="getTableData">刷新</el-button>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="openDialog">新增</el-button>
      </div>
      <lims-table :tableData="tableData" :column="columnData"
                  @pagination="page" :height="'calc(100vh - 18em)'"
                  :page="pagination" :tableLoading="loading"></lims-table>
    </div>
    <Add ref="mandateModal" @refresh="getTableData"></Add>
  </div>
</template>
<script>
import Add from "../components/mandateAdd.vue"
import limsTable from "@/components/Table/lims-table.vue";
import {
  deletePersonPostAuthorizationRecord, exportPersonPostAuthorizationRecord,
  PersonPostAuthorizationRecordPage
} from "@/api/cnas/personal/personPostAuthorizationRecord";
import {delCustomById} from "@/api/system/customer";
export default {
  components: {
    limsTable,
    Add
  },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      columnData: [
        {
          label: '序号',
          prop: 'id'
        }, {
          label: '证书编号',
          prop: 'certificateNumber'
        }, {
          label: '被任职人员',
          prop: 'userName'
        }, {
          label: '任职岗位',
          prop: 'post'
        }, {
          label: '理论考试成绩',
          prop: 'num1',
          width: 120
        },{
          label: '操作技能考试成绩',
          prop: 'num2',
          width: 150
        },{
          label: '操作时间',
          prop: 'updateTime'
        }, {
          label: '备注',
          prop: 'remarks',
          width: 300
        }, {
          label: '操作',
          dataType: 'action',
          width: 160,
          fixed: 'right',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.openDialog(row, true)
              }
            }, {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.handleDown(row)
              }
            }, {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteNotify(row.id)
              }
            }
          ]
        },
      ],
      tableData: [],
      pagination: {
        current: 1,
        size: 20,
        total: 0
      },
      loading: false
    }
  },
  mounted() {
    this.getTableData()
  },
  methods: {
    openDialog(row, type=false) {
      this.$refs.mandateModal.openDialog(row, type)
    },
    /**
     * @desc æŸ¥è¯¢è¡¨æ ¼æ•°æ®
     */
    async getTableData() {
      const params = this.isDepartment ? {
        departLimsId: this.departId,
        current: this.pagination.current,
        size: this.pagination.pageSize
      } : {
        userId: this.departId,
        current: this.pagination.current,
        size: this.pagination.pageSize
      }
      this.loading = true
      PersonPostAuthorizationRecordPage(params).then(res => {
        this.loading = false
        this.tableData = res.data.records
        this.pagination.total = res.data.total
      }).catch(err => {
        this.loading = false
      })
    },
    page (page) {
      this.pagination.size = page.limit
      this.getTableData()
    },
    /**
     * @desc åˆ é™¤ä»»èŒè®°å½•
     */
    deleteNotify(id) {
      this.$confirm('是否删除当前数据?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        deletePersonPostAuthorizationRecord({id: id}).then(res => {
          this.$message.success('删除成功')
          this.getTableData()
        }).catch(e => {
          this.$message.error('删除失败')
        })
      }).catch(() => {})
    },
    handleDown(row){
      exportPersonPostAuthorizationRecord({id:row.id}).then(res => {
        const blob = new Blob([res],{ type: 'application/octet-stream' });
        this.$download.saveAs(blob, '任职授权-'+row.certificateNumber+'-'+row.post + '.docx')
      })
    }
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (newId) {
          this.getTableData();
        }
      }
    }
  }
}
</script>
<style scoped>
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnel-capacity.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,576 @@
<!-- äººå‘˜èƒ½åŠ› -->
<template>
  <div>
    <div style="display: flex;justify-content: space-between;">
      <el-form ref="page" size="small" :inline="true">
        <el-form-item label="姓名">
          <el-input v-model="userName" placeholder="请输入姓名" size="small" clearable></el-input>
        </el-form-item>
        <el-form-item>
          <el-button size="small" type="primary" @click="refreshTable">查 è¯¢</el-button>
        </el-form-item>
      </el-form>
      <div>
        <el-button v-if="!isDepartment" size="small" type="primary" @click="addAppointPost('add')">新增</el-button>
      </div>
    </div>
    <lims-table :tableData="tableData" :column="yearColumnData"
                @pagination="pagination" :height="'calc(100vh - 20em)'"
                :page="search" :tableLoading="yearLoading">
      <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>
    </lims-table>
    <!--新增能力认定弹框-->
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :title="title"
               :visible.sync="dialogVisible"
               width="80%" @close="resetForm">
      <el-form v-if="dialogVisible" ref="infoForm" :model="form" :rules="rules">
        <el-col :span="12">
          <el-form-item label="人员:" label-width="110px" prop="userId">
            <el-select v-model="form.userId" disabled clearable
                       filterable size="small" style="width: 100%;">
              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <div style="display: flex;justify-content: space-evenly;font-weight: 600">
            <span>查核结果</span>
            <span>符合与否</span>
            <span>备注</span>
          </div>
        </el-col>
        <el-col :span="8">
          <el-form-item label="学历:" label-width="110px" prop="academicDegree">
            <el-input v-model="form.academicDegree" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="academicConformNot" style="text-align: center">
            <el-radio-group v-model="form.academicConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="academicRemarks">
            <el-input v-model="form.academicRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="相关年限:" label-width="110px" prop="relatedYears">
            <el-input v-model="form.relatedYears" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="relatedYearsConformNot" style="text-align: center">
            <el-radio-group v-model="form.relatedYearsConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="relatedYearsRemarks    ">
            <el-input v-model="form.relatedYearsRemarks    " :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="相关培训:" label-width="110px" prop="relatedTraining">
            <el-input v-model="form.relatedTraining" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="relatedTrainingConformNot" style="text-align: center">
            <el-radio-group v-model="form.relatedTrainingConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="relatedTrainingRemarks">
            <el-input v-model="form.relatedTrainingRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
                      size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="相关经验:" label-width="110px" prop="relevantExperience">
            <el-input v-model="form.relevantExperience" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="relevantExperienceConformNot" style="text-align: center">
            <el-radio-group v-model="form.relevantExperienceConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="relevantExperienceRemarks">
            <el-input v-model="form.relevantExperienceRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
                      size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="上岗证:" label-width="110px" prop="workLicense">
            <el-input v-model="form.workLicense" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"
                      style="width: 100%">
            </el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="workLicenseConformNot" style="text-align: center">
            <el-radio-group v-model="form.workLicenseConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="workLicenseRemarks">
            <el-input v-model="form.workLicenseRemarks" :disabled="operationType === 'view' || operationType === 'confirm'" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="岗位职责:" label-width="110px" prop="jobResponsibilitiesTem" style="height: 450px">
            <el-checkbox-group v-model="form.jobResponsibilitiesTem" :disabled="operationType === 'view' || operationType === 'confirm'"
                               @change="selectResponsibilities">
              <el-checkbox v-for="city in dict.type.responsibilities_list" :key="city.value" :label="city.label"
                           :value="city.value"></el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item class="radio-group" prop="jobResponsibilitiesConformNot"
                        style="text-align: center;height: 420px">
            <el-radio-group v-model="form.jobResponsibilitiesConformNot" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
              <el-radio :label="1">符合</el-radio>
              <el-radio :label="2">不符合</el-radio>
              <el-radio :label="3">不适用</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item prop="jobResponsibilitiesRemarks" style="height: 420px">
            <el-input v-model="form.jobResponsibilitiesRemarks" :disabled="operationType === 'view' || operationType === 'confirm'"
                      size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <span style="padding-left: 110px;font-size: 14px">备注:岗位职责达到5项及5项以上为符合</span>
        </el-col>
        <el-col :span="16">
          <el-form-item label="综合评价:" label-width="110px" prop="comprehensiveAssessment">
            <el-radio-group v-model="form.comprehensiveAssessment" :disabled="operationType === 'view' || operationType === 'confirm'" v-removeAriaHidden>
              <el-radio label="Qualified this position">可胜任该岗位</el-radio>
              <el-radio label="You can work while training">可边培训边上岗</el-radio>
              <el-radio label="Iconpetent for the position">不胜任该岗位</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item prop="confirmOperatingPersonnelId" label="确认人:">
            <el-select v-model="form.confirmOperatingPersonnelId" clearable :disabled="operationType === 'view' || operationType === 'confirm'"
                       filterable size="small" style="width: 50%;">
              <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="operationType !== 'view'" @click="resetForm">取消</el-button>
        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm">保存</el-button>
        <el-button v-if="operationType !== 'view' && operationType !== 'confirm'" type="primary" @click="submitForm1">提交并通知</el-button>
        <el-button v-if="operationType === 'confirm'" type="primary" @click="verifyGet">确认</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import {
  addOrUpdatePersonPersonnelCapacity,
  confirmPersonnelCapability,
  deletePersonPersonnelCapacity,
  exportPersonnelCapacity,
  personPersonnelCapacityPage,
  submitConfirmPersonnelCapability
} from "@/api/cnas/personal/personPersonnelCapacity";
import {selectUserCondition} from "@/api/cnas/resourceDemand/facilitiesEnvironment/facilitiesAndEnvironment";
import {mapGetters} from "vuex";
export default {
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  components: {
    limsTable
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  dicts: ['responsibilities_list'],
  data() {
    return {
      userName: '',
      tableData: [],
      search: {
        size: 20,
        current: 1,
        total: 0
      },
      title: '新增能力认定',
      operationType: '',
      yearColumnData: [
        {
          label: '岗位',
          prop: 'postName',
          minWidth: '100'
        }, {
          label: '姓名',
          prop: 'userName',
          minWidth: '100'
        }, {
          label: '学历',
          prop: 'academicDegree',
          minWidth: '100'
        }, {
          label: '专业',
          prop: 'major',
          minWidth: '100'
        }, {
          label: '职称',
          prop: 'professionalTitle',
          minWidth: '100'
        }, {
          dataType: 'slot',
          label: '岗位职责',
          prop: 'jobResponsibilities',
          minWidth: '200px',
          slot: 'jobResponsibilities'
        }, {
          dataType: 'tag',
          label: '综合评价',
          minWidth: '140px',
          prop: 'comprehensiveAssessment',
          formatData: (params) => {
            if (params == 'Qualified this position') {
              return '可胜任该岗位';
            } else if (params == 'You can work while training') {
              return '可边培训边上岗';
            } else {
              return '不胜任该岗位';
            }
          },
          formatType: (params) => {
            if (params == 'Qualified this position') {
              return 'success';
            } else if (params == 'You can work while training') {
              return 'warning';
            } else {
              return 'danger';
            }
          }
        }, {
          label: '确认人',
          prop: 'confirmOperatingPersonnelName',
          minWidth: '100'
        }, {
          label: '确认日期',
          prop: 'confirmDate',
          minWidth: '160'
        }, {
          dataType: 'action',
          minWidth: '220',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.handleViewClick('edit', row);
              },
              disabled: (row) => {
                if (row.confirmDate) {
                  return true
                } else {
                  return false
                }
              },
            },
            {
              name: '查看',
              type: 'text',
              clickFun: (row) => {
                this.handleViewClick('view', row);
              }
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              }
            },
            {
              name: '确认',
              type: 'text',
              clickFun: (row) => {
                this.handleViewClick('confirm', row);
              },
              disabled: (row) => {
                if (row.confirmDate || this.userId != row.confirmOperatingPersonnelId) {
                  return true
                } else {
                  return false
                }
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deletePost(row.id);
              },
              disabled: (row) => {
                if (row.confirmDate) {
                  return true
                } else {
                  return false
                }
              }
            }
          ]
        }],
      yearLoading: false,
      dialogVisible: false,
      verifyGetId: '',
      form: {
        jobResponsibilitiesTem: []
      },
      responsibleOptions: [],
      rules: {
        confirmOperatingPersonnelId: [{ required: true, message: '请选择确认人', trigger: 'change' }],
        userId: [{ required: true, message: '请选择人员', trigger: 'change' }],
        academicDegree: [{ required: true, message: '请输入学历查核结果', trigger: 'blur' }],
        academicConformNot: [{ required: true, message: '请选择学历符合与否', trigger: 'change' }],
        relatedYears: [{ required: true, message: '请输入相关年限查核结果', trigger: 'blur' }],
        relatedYearsConformNot: [{ required: true, message: '请选择相关年限符合与否', trigger: 'change' }],
        relatedTraining: [{ required: true, message: '请输入相培训限查核结果', trigger: 'blur' }],
        relatedTrainingConformNot: [{ required: true, message: '请选择相关培训符合与否', trigger: 'change' }],
        relevantExperience: [{ required: true, message: '请输入相关经验查核结果', trigger: 'blur' }],
        relevantExperienceConformNot: [{ required: true, message: '请选择相关经验符合与否', trigger: 'change' }],
        workLicense: [{ required: true, message: '请输入上岗证查核结果', trigger: 'blur' }],
        workLicenseConformNot: [{ required: true, message: '请选择上岗证符合与否', trigger: 'change' }],
        jobResponsibilitiesTem: [{ required: true, message: '请选择岗位职责查核结果', trigger: 'change' }],
        jobResponsibilitiesConformNot: [{ required: true, message: '请选择岗位职责符合与否', trigger: 'change' }],
        comprehensiveAssessment: [{ required: true, message: '请选择综合评价', trigger: 'change' }]
      },
      responsibilities: []
    };
  },
  mounted() {
    this.getList(this.departId);
  },
  methods: {
    // ä¸‹è½½
    downLoadPost(row) {
      exportPersonnelCapacity({id: row.id}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '人员能力导出.docx')
      })
    },
    // æŸ¥è¯¢
    refreshTable() {
      this.getList(this.departId);
    },
    // èŽ·å–äººå‘˜èƒ½åŠ›åˆ—è¡¨ä¿¡æ¯
    getList(userId) {
      this.search.userId = userId;
      const params = this.isDepartment ?
        {
          departmentId: this.search.userId,
          size: this.search.size,
          current: this.search.current,
          userName: this.userName,
        }: {
          userId: this.search.userId,
          size: this.search.size,
          current: this.search.current,
          userName: this.userName,
        }
      this.yearLoading = true
      personPersonnelCapacityPage(params).then(res => {
        this.yearLoading = false
        this.tableData = res.data.records;
        this.search.total = res.data.total;
      }).catch(err => {
        console.log(err);
        this.yearLoading = false
      })
    },
    pagination (page) {
      this.search.size = page.limit
      this.refreshTable()
    },
    selectResponsibilities(arr) {
      let arrTem = [];
      arr.map(val => {
        const index = this.dict.type.responsibilities_list.findIndex(item => item.label === val);
        if (index > -1) {
          arrTem.push(this.dict.type.responsibilities_list[index].value);
        }
      });
      this.form.jobResponsibilities = arrTem.join(',');
    },
    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.form.userId = this.departId
      this.getUserList();
    },
    // ç¼–辑/查看
    handleViewClick(type, row) {
      this.operationType = type;
      this.verifyGetId = row.id
      this.title = this.operationType === 'edit' ? '修改能力认定' : '查看能力认定'
      this.dialogVisible = true;
      this.form = {...row}
      if(this.form.responsibilities) {
        this.$set(this.form, 'jobResponsibilitiesTem', this.form.responsibilities.split(","))
      } else {
        this.$set(this.form, 'jobResponsibilitiesTem', [])
      }
      this.getUserList();
    },
    // ä¿å­˜
    submitForm() {
      this.$refs.infoForm.validate((valid) => {
        if (valid) {
          addOrUpdatePersonPersonnelCapacity(this.form).then(res => {
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.getList(this.departId);
              this.dialogVisible = false;
            }
          });
        }
      });
    },
    // æäº¤å¹¶é€šçŸ¥
    submitForm1() {
      this.$refs.infoForm.validate((valid) => {
        if (valid) {
          submitConfirmPersonnelCapability(this.form).then(res => {
            if (res.code == 200) {
              this.$message.success('提交成功');
              this.getList(this.departId);
              this.dialogVisible = false;
            }
          });
        }
      });
    },
    verifyGet () {
      confirmPersonnelCapability({id: this.verifyGetId}).then(res => {
        if (res.code == 200) {
          this.$message.success('确认成功');
          this.resetForm()
          this.getList(this.departId);
        }
      });
    },
    // åˆ é™¤å²—位职责
    deletePost(id) {
      this.$confirm('此操作将永久删除此数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        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(){
      selectUserCondition().then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      })
    },
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    departId: {
      handler(newId, oldId) {
        this.getList(newId);
      }
    },
  }
};
</script>
<style scoped>
>>> .el-dialog__body {
  max-height: 74vh;
  overflow-y: auto;
}
.radio-group >>> .el-form-item__error {
  padding-left: 38px;
}
>>>.el-checkbox__label {
  width: 212px;
  white-space: pre-wrap;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnel-information.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1115 @@
<template>
  <div>
    <div style="text-align: right;margin-bottom: 10px">
<!--       <el-button size="small" @click="$emit('goBackList')">返回</el-button>-->
      <el-button size="small" type="primary" @click="downPerson">下载档案</el-button>
      <el-button size="small" type="primary" @click="dialogVisible = true">人员分类</el-button>
      <el-button :loading="saveLoading" size="small" type="primary" @click="save">保存</el-button>
    </div>
    <div>
      <div style="display: flex;flex-direction: row;">
        <div style="width: 12em">
          <el-image :src="javaApi + '/img/' + form.pictureUrl" fit="fill"
                    style="width:100%;height: 300px;border: 1px solid #000;border-radius: 10px;margin-left: 6px;margin-top: 10px;">
            <div slot="error" class="image-slot">
              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
            </div>
          </el-image>
          <el-image :src="javaApi + '/img/' + form.signatureUrl" fit="fill"
                    style="width:80%;height: 50px;border: 1px solid #000;border-radius: 10px;margin-left: 22px;margin-top: 20px;">
            <div slot="error" class="image-slot">
              <i class="el-icon-picture-outline" style="font-size: 40px;"></i>
            </div>
          </el-image>
        </div>
        <div style="height: calc(100vh - 14em);overflow-y: auto">
          <el-form ref="form" :model="form" label-width="110px">
            <el-row>
              <el-col :span="8">
                <el-form-item label="姓名">
                  <el-input disabled v-model="form.name" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="工号">
                  <el-input disabled v-model="form.account" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="当前状态">
                  <el-radio-group v-model="form.currentState">
                    <el-radio label="1formal" size="mini">正式</el-radio>
                    <el-radio label="2intern" size="mini">实习</el-radio>
                    <el-radio label="3leaveOffice" size="mini">离职</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="性别">
                  <el-radio-group v-model="form.sex">
                    <el-radio label="1" size="mini">男</el-radio>
                    <el-radio label="0" size="mini">女</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="公司名称">
                  <el-input v-model="form.corporateName" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="所属部门">
                  <el-cascader v-model="form.departLimsId" :options="department" :props="{ label: 'name', value: 'id',checkStrictly: true }"  filterable style="width: 100%;"></el-cascader>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="岗位名称">
                  <el-input v-model="form.postName" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="入集团时间">
                  <el-date-picker v-model="form.groupTime" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="劳动关系">
                  <el-radio-group v-model="form.laborRelations">
                    <el-radio :label=0 size="mini">合同工</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="公司邮箱">
                  <el-input v-model="form.email" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="工作时间">
                  <el-date-picker v-model="form.workingTime" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="合同到期时间">
                  <el-date-picker v-model="form.contractLifeTime" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="职称">
                  <el-input v-model="form.professionalTitle" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="16" style="text-align: left;">
                <el-form-item label="人员分类">
                  <span style="color: #000;">{{ form.personnelClassification }}</span>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="出生日期">
                  <el-date-picker v-model="form.dateBirth" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                                  @change="getAge"
                                  style="width: 99%;" type="date" value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="籍贯">
                  <el-input v-model="form.nativePlace" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="民族">
                  <el-input v-model="form.nation" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="身份证号">
                  <el-input v-model="form.identityCard" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="年龄">
                  <el-input-number v-model="form.age" :max="130" :min="1"
                                   controls-position="right" size="small" style="width: 99%;"></el-input-number>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="婚姻状况">
                  <el-radio-group v-model="form.maritalStatus">
                    <el-radio :label=0 size="mini">已婚</el-radio>
                    <el-radio :label=1 size="mini">未婚</el-radio>
                  </el-radio-group>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="证件有效期">
                  <el-date-picker v-model="form.validityPeriod" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="证件地址">
                  <el-input v-model="form.idAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="证件详细地址">
                  <el-input v-model="form.idDetailAddress" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="政治面貌">
                  <el-input v-model="form.politicalStatus" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="入党/团时间">
                  <el-date-picker v-model="form.dumplingTime" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="手机号">
                  <el-input v-model="form.telephone" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="最高学历">
                  <el-input v-model="form.officialAcademicRedentials" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="最高学位">
                  <el-input v-model="form.highestDegree" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="毕业院校1">
                  <el-input v-model="form.graduatedInstitutions1" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="专业1">
                  <el-input v-model="form.major1" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="毕业时间1">
                  <el-date-picker v-model="form.graduationTime1" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="毕业院校2">
                  <el-input v-model="form.graduatedInstitutions2" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="专业2">
                  <el-input v-model="form.major2" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="毕业时间2">
                  <el-date-picker v-model="form.graduationTime2" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="8">
                <el-form-item label="登记时间">
                  <el-date-picker v-model="form.lastUpdateTime" format="yyyy-MM-dd" placeholder="选择日期"
                                  size="small" style="width: 99%;" type="date"
                                  value-format="yyyy-MM-dd HH:mm:ss">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="备注">
                  <el-input type="textarea" v-model="form.remarks" clearable size="small"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="18">
                <el-form-item label="个人照片">
                  <el-input v-model="form.pictureUrl" disabled size="small">
                    <el-button v-if="form.pictureUrl" slot="append" icon="el-icon-delete-solid"
                               @click="deleteFile(form.pictureUrl, 'pictureUrl')"></el-button>
                  </el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-upload ref="upload" :action="action"
                           :headers="uploadHeader"
                           :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"
                           :headers="uploadHeader"
                           :on-success="(response, file, fileList) => onSuccess(response, file, fileList, 'signatureUrl')"
                           :show-file-list="false"
                           style="float: left; margin: 0 10px 0 10px;">
                  <el-button slot="trigger" class="uploadFile" size="small" type="primary">上传</el-button>
                </el-upload>
                <el-button v-if="form.signatureUrl" class="uploadFile" size="small"
                           type="primary" @click="downloadFile(form.signatureUrl)">下载</el-button>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="20">
                <el-form-item label="证书资料" >
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd(0)">新增</el-button>
              </el-col>
            </el-row>
            <lims-table :tableData="annexList" :column="columnData2" style="width: 96%;margin-left: 34px"
                        height="200" :tableLoading="tableLoading2"></lims-table>
            <el-row style="margin-top: 10px">
              <el-col :span="20">
                <el-form-item label="附件资料" >
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-upload ref='upload'
                           :action="fileAction"
                           :auto-upload="true" :data="{userId: clickNodeVal.userId}"
                           :before-upload="fileBeforeUpload"
                           :headers="uploadHeader" :on-error="onError"
                           :on-success="handleSuccessUp"
                           :show-file-list="false"
                           accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
                  <el-button size="small" type="primary">附件上传</el-button>
                </el-upload>
              </el-col>
            </el-row>
            <lims-table :tableData="tableData" :column="columnData" style="width: 96%;float: right;"
                        height="200" :tableLoading="tableLoading"></lims-table>
            <el-row style="margin-top: 10px">
              <el-col :span="20">
                <el-form-item label="工作经历" >
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-button size="mini" style="float: right;margin-right: 25px" type="primary" @click="annexAdd1('add')">新增</el-button>
              </el-col>
            </el-row>
            <el-table :data="tableData1" border height="200" style="width: 96%;float: right;" v-loading="tableLoading1">
              <el-table-column label="序号" type="index" width="55px" align="center">
              </el-table-column>
              <el-table-column label="工作经历" prop="workExperience">
              </el-table-column>
              <el-table-column align="center" label="操作">
                <template slot-scope="scope">
                  <el-button type="text" size="mini" @click="annexAdd1('edit',scope.row)">编辑</el-button>
                  <el-button type="text" size="mini" @click="deleteAnnex1(scope.row)" style="color: #f56c6c">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-form>
        </div>
      </div>
    </div>
    <!-- äººå‘˜åˆ†ç±»å¼¹æ¡† -->
    <el-dialog :visible.sync="dialogVisible" title="提示" width="40%" @open="getComparisonList">
      <div style="height: 30vh;">
        <el-row>
          <el-col :span="4">
            äººå‘˜åˆ†ç±»ï¼š
          </el-col>
          <el-col :span="20" style="text-align: left;">
            <el-checkbox-group v-model="checkList">
              <el-checkbox v-for="v in dict.type.personnl_type" :key="v.value"
                           :label="v.value"></el-checkbox>
            </el-checkbox-group>
          </el-col>
        </el-row>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="clickPersonnelClassificationSure">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <!-- æ–°å¢žé™„件资料 -->
    <el-dialog :before-close="handleClose" :title="title" :visible.sync="dialogVisible1" width="40%" @open="getComparisonList">
      <el-form ref="annex" :model="annex" :rules="rules" label-width="100px">
        <el-row>
          <el-col :span="16">
            <el-form-item label="证件号" prop="idNumber">
              <el-input v-model="annex.idNumber" clearable size="small" style="width: 100%;"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="发证单位" prop="issueUnit">
              <el-input v-model="annex.issueUnit" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="级别">
              <el-input v-model="annex.level" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="有效期" prop="periodValidity">
              <el-input v-model="annex.periodValidity" clearable size="small"></el-input>
<!--              <el-date-picker v-model="annex.periodValidity" format="yyyy-MM-dd" placeholder="选择日期" size="small"-->
<!--                              style="width: 99%;" type="date" value-format="yyyy-MM-dd">-->
<!--              </el-date-picker>-->
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="复印件">
              <el-input v-model="annex.copy" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="原件">
              <el-input v-model="annex.original" clearable size="small"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="margin-top: 15px">
          <el-col :span="16">
            <el-form-item label="文件">
              <el-upload
                :action="action"
                :before-upload="beforeAvatarUpload"
                :headers="uploadHeader"
                :on-success="(response,file,fileList) => onSuccess(response, file, fileList, 'fileName')"
                :show-file-list="false">
                <span v-if="annex.fileName">{{annex.fileName}}</span>
<!--                <img v-if="imageUrl" :src="imageUrl" class="avatar">-->
                <i v-else class="el-icon-upload avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancellation">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitForm">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <!-- æ–°å¢žå·¥ä½œç»åކ -->
    <el-dialog @close="handleClose2" title="添加工作经历" :visible.sync="dialogVisible2" width="40%">
      <el-form ref="annex2" :model="annex2" label-width="100px">
        <el-row>
          <el-col :span="16">
            <el-form-item label="工作经历" prop="idNumber">
              <el-input type="textarea" v-model="annex2.workExperience" clearable size="small" style="width: 100%;"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleClose2">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitForm2">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import fileDownload from '@/utils/file'
import {
  addAnnex,
  addBasicInfoWork,
  delBasicInfoFileList,
  delBasicInfoWorkList,
  deleteAnnex, deleteCNASFile,
  exportPersonBasicInfoById,
  getAnnex,
  getAnnexByUserId,
  getBasicInfoFileList,
  getBasicInfoWorkList,
  getCNASPersonnelInfo,
  saveCNASPersonnelInfo,
  updateAnnex,
  updateBasicInfoWorkList
} from "@/api/cnas/personal/personalList";
import limsTable from "@/components/Table/lims-table.vue";
export default {
  props: {
    clickNodeVal: {
      type: Object,
      default: () => { return {} }
    },
  },
  dicts: ['personnl_type'],
  data() {
    return {
      operationType: '',
      basicInfoWorkId: '',
      dialogVisible2: false,
      annex2: {
        workExperience: ''
      },
      tableLoading: false,
      tableData: [],
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delete(row)
              }
            }
          ]
        }
      ],
      columnData2: [
        {
          label: '证件号',
          prop: 'idNumber',
          minWidth: '150px'
        },{
          label: '发证单位',
          prop: 'issueUnit',
          minWidth: '150px'
        },{
          label: '文件名称',
          prop: 'fileName',
          minWidth: '200px'
        },{
          label: '级别',
          prop: 'level',
          minWidth: '150px'
        },{
          label: '有效期',
          prop: 'periodValidity',
          minWidth: '150px'
        },{
          label: '添加时间',
          prop: 'createTime',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '130',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.downloadFile(row.fileName)
              }
            },
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.annexAdd(1,row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteAnnex(row)
              }
            }
          ]
        }
      ],
      tableLoading1: false,
      tableLoading2: false,
      tableData1: [],
      addOrupdate: null,
      title: '',
      annexList: [],
      imageUrl: '',
      annex: {
        userId: '',
        idNumber: '',
        issueUnit: '',
        level: '',
        periodValidity: '',
        copy: '',
        original: '',
        fileName: ''
      },
      rules: {
        idNumber: [
          { required: true, message: '请输入证件号', trigger: 'blur' }
        ],
        issueUnit: [
          { required: true, message: '请输入发证单位', trigger: 'blur' }
        ],
        periodValidity: [
          { required: false, message: '请选择有效期', trigger: 'blur' }
        ]
      },
      dialogVisible1: false,
      form: {
        userId: '',
        name: '',
        account: '',
        currentState: '',
        sex: '',
        corporateName: '',
        department: '',
        departLimsId: [],
        postName: '',
        groupTime: '',
        laborRelations: '',
        workingTime: '',
        contractLifeTime: '',
        personnelClassification: '',
        dateBirth: '',
        nativePlace: '',
        nation: '',
        identityCard: '',
        age: '',
        validityPeriod: '',
        maritalStatus: '',
        idAddress: '',
        idDetailAddress: '',
        politicalStatus: '',
        dumplingTime: '',
        telephone: '',
        email: '',
        officialAcademicRedentials: '',
        highestDegree: '',
        graduatedInstitutions1: '',
        major1: '',
        graduationTime1: '',
        graduatedInstitutions2: '',
        major2: '',
        graduationTime2: '',
        lastUpdateTime: '',
        pictureUrl: '',
        signatureUrl: '',
        professionalTitle: '',
        remarks: '',
      },
      department: [],
      saveLoading: false,
      dialogVisible: false,
      checkList: [],
      successFileList: [], // é˜²æ­¢åŽç«¯å‡ºçŽ°è„æ•°æ®
      isSave: false,
    }
  },
  components: {limsTable, fileDownload},
  created() {
    this.init()
    this.searchTableList()
    this.searchTableList2()
  },
  computed: {
    action() {
      return this.javaApi + '/personBasicInfo/saveCNASFile'
    },
    fileAction() {
      return this.javaApi + '/personBasicInfo/uploadBasicInfoFile'
    },
  },
  methods: {
    // ä¸‹è½½æ¡£æ¡ˆ
    downPerson(){
      exportPersonBasicInfoById({id: this.clickNodeVal.userId}).then(res => {
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '人员档案.docx');
        this.$message.success('导出成功')
      })
    },
    // ä¸Šä¼ éªŒè¯
    fileBeforeUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    onError(err, file, fileList,type) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response, ) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchTableList()
      } else {
        this.$message.error(response.message);
      }
    },
    // æŸ¥è¯¢é™„件列表
    searchTableList () {
      this.tableLoading = true
      getBasicInfoFileList({userId: this.clickNodeVal.userId}).then(res => {
        this.tableLoading = false
        this.tableData = res.data
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        fileDownload.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
    // åˆ é™¤
    delete (row) {
      this.$confirm('此操作将删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        delBasicInfoFileList({basicInfoFileId: row.basicInfoFileId}).then(res => {
          this.tableLoading = false
          this.$message.success('删除成功')
          this.searchTableList();
        }).catch(err => {
          this.tableLoading = false
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      })
    },
    // æ‰“开工作经历探况
    annexAdd1 (type, row) {
      this.operationType = type
      if (type === 'edit') {
        this.basicInfoWorkId = row.basicInfoWorkId
        this.annex2.workExperience = row.workExperience
      } else {
        this.basicInfoWorkId = ''
        this.annex2.workExperience = ''
      }
      this.dialogVisible2 = true
    },
    // æäº¤å·¥ä½œç»åކ
    submitForm2 () {
      const params = {
        workExperience: this.annex2.workExperience,
        userId: this.clickNodeVal.userId,
        basicInfoWorkId: this.basicInfoWorkId
      }
      this.tableLoading1 = true
      if (this.operationType === 'add') {
        addBasicInfoWork(params).then(res => {
          this.tableLoading1 = false
          if (res.code == 200) {
            this.dialogVisible2 = false
            this.$message.success('新增成功')
            this.searchTableList2();
          }
        }).catch(err => {
          this.tableLoading1 = false
        })
      } else {
        updateBasicInfoWorkList(params).then(res => {
          this.tableLoading1 = false
          this.dialogVisible2 = false
          this.$message.success('修改成功')
          this.searchTableList2();
        }).catch(err => {
          this.tableLoading1 = false
        })
      }
    },
    // å…³é—­å·¥ä½œç»åŽ†å¼¹æ¡†
    handleClose2 () {
      this.dialogVisible2 = false
      this.annex2.workExperience = ''
    },
    // åˆ é™¤å·¥ä½œç»åކ
    deleteAnnex1 (row) {
      this.$confirm('此操作将删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading1 = true
        delBasicInfoWorkList({basicInfoWorkId: row.basicInfoWorkId}).then(res => {
          this.tableLoading1 = false
          this.$message.success('删除成功')
          this.searchTableList2();
        }).catch(err => {
          this.tableLoading1 = false
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // æŸ¥è¯¢å·¥ä½œç»åŽ†åˆ—è¡¨
    searchTableList2 () {
      this.tableLoading1 = true
      getBasicInfoWorkList({userId: this.clickNodeVal.userId}).then(res => {
        this.tableLoading1 = false
        this.tableData1 = res.data
      }).catch(err => {
        this.tableLoading1 = false
        console.log('err---', err);
      })
    },
    annexAdd(type,row) {
      if(type === 1) {
        this.title = '编辑附件资料'
        this.addOrupdate = 1
        getAnnex({id: row.id}).then(res => {
          this.annex = res.data
          this.imageUrl = this.javaApi + '/img/' + res.data.fileName
        })
      }else {
        this.title = '新增附件资料'
        this.addOrupdate = 2
      }
      this.dialogVisible1 = true
    },
    submitForm() {
      this.$refs['annex'].validate((valid) => {
        if (valid) {
          this.addAnnex()
        } else {
          return false
        }
      })
    },
    addAnnex() {
      if(this.annex.fileName == "" || this.annex.fileName == null || this.annex.fileName == undefined) {
        this.$message.error("请上传文件")
        return
      }
      this.annex.userId = this.clickNodeVal.userId
      if(this.addOrupdate === 1) {
        updateAnnex(this.annex).then(res => {
          if(res.code == 200) {
            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
              this.imageUrl = ''
              this.resetForm('annex')
              this.annexList = res.data
              this.dialogVisible1 = false
              this.$message.success('更新成功!')
            })
          }
        })
      }else {
        this.annex.id = null
        addAnnex(this.annex).then(res => {
          if(res.code == 200) {
            getAnnexByUserId({userId: this.clickNodeVal.userId}).then(res => {
              this.imageUrl = ''
              this.resetForm('annex')
              this.annexList = res.data
              this.dialogVisible1 = false
              this.$message.success('保存成功')
            })
          }
        })
      }
    },
    deleteAnnex(row) {
      this.$confirm('此操作将永久删除该文件, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteAnnex({id: row.id}).then(res => {
          this.$message.success('删除成功!')
          this.annexList = this.annexList.filter(item => item.id != row.id)
        })
      })
    },
    beforeAvatarUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    downloadFile(fileName) {
      let state = /\.(jpg|jpeg|png|gif)$/i.test(fileName)
      if (state) {
        let url = this.javaApi + '/img/' + fileName;
        fileDownload.downloadIamge(url, fileName)
      } else {
        const url = this.javaApi + '/word/' + fileName
        const link = document.createElement('a');
        link.href = url;
        link.download = fileName;
        link.click();
        this.$message.success('下载成功')
      }
    },
    async onSuccess(response, file, fileList, entityVal) {
      if(entityVal == 'fileName') {
        this.annex.fileName = response.data
      }
      // åœ¨ä¿å­˜èµ‹å€¼æ–°æ–‡ä»¶
      this.successFileList.push(response.data)
      this.$set(this.form, entityVal, response.data)
    },
    // åˆå§‹åŒ–调用
    init() {
      if (!this.clickNodeVal.userId) {
        let user = JSON.parse(localStorage.getItem('user'))
        this.getUserBasisInfo(user.userId)
        this.clickNodeVal.userId = user.userId
      } else {
        this.getUserBasisInfo(this.clickNodeVal.userId)
      }
    },
    getUserBasisInfo(userId) {
      getCNASPersonnelInfo({userId: userId}).then(res => {
        this.form = res.data.PersonBasicInfoDto
        this.department = res.data.department
        this.annexList = res.data.annexList
        this.form.departLimsId = res.data.PersonBasicInfoDto.departLimsId.split(',').filter(a => a != "").map(Number)
      })
    },
    async save() {
      this.saveLoading = true
      this.form.userId = this.clickNodeVal.userId
      if(Array.isArray(this.form.departLimsId)) {
        if(this.form.departLimsId.length > 0) {
          this.form.departLimsId = this.form.departLimsId.join(',').trim() + ','
        }else {
          this.form.departLimsId = ''
        }
      }
      saveCNASPersonnelInfo(this.form).then(res => {
        this.saveLoading = false
        this.isSave = true
        this.getUserBasisInfo(this.clickNodeVal.userId)
        this.$message.success('保存成功!')
      })
    },
    // å–人员分类的字典
    getComparisonList() {
      if (this.checkList.length > 0) {
        this.form.personnelClassification = this.checkList.split(',')
      }
    },
    clickPersonnelClassificationSure() {
      this.dialogVisible = false
      this.form.personnelClassification = this.checkList.filter(m=>m).join(',')
    },
    async deleteFile(fileName, entityVal) {
      await deleteCNASFile({fileName: fileName}).then(res => {
        this.$message.success('删除成功!')
        this.$set(this.form, entityVal, null)
        let index = this.successFileList.indexOf(fileName)
        if (index != -1) {
          this.successFileList.splice(index, 1)
        }
      })
    },
    cancellation() {
      this.dialogVisible1 = false
      this.imageUrl = ''
      this.resetForm('annex')
    },
    handleClose(done) {
      this.imageUrl = ''
      this.annex = {
        userId: '',
        idNumber: '',
        issueUnit: '',
        level: '',
        periodValidity: '',
        copy: '',
        original: '',
        fileName: ''
      }
      done();
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    getAge (val) {
      this.form.age = this.calculateAge(val)
    },
    calculateAge(birthDateString) {
      // è§£æžå‡ºç”Ÿæ—¥æœŸå­—符串为日期对象
      const birthDate = new Date(birthDateString);
      // èŽ·å–å½“å‰æ—¥æœŸ
      const currentDate = new Date();
      // è®¡ç®—年份差
      let age = currentDate.getFullYear() - birthDate.getFullYear();
      // æ£€æŸ¥æ˜¯å¦å·²ç»è¿‡äº†ä»Šå¹´çš„生日
      const currentMonth = currentDate.getMonth();
      const currentDay = currentDate.getDate();
      const birthMonth = birthDate.getMonth();
      const birthDay = birthDate.getDate();
      if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) {
        // å¦‚果还没到今年的生日,年龄减1
        age--;
      }
      return age;
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    clickNodeVal: {
      handler(newVal, oldVal) {
        if (newVal.userId) {
          this.getUserBasisInfo(newVal.userId)
          this.searchTableList()
          this.searchTableList2()
        }
      },
    }
  }
}
</script>
<style scoped>
>>>.el-table__body-wrapper::-webkit-scrollbar {
  height: 12px;
  /* è®¾ç½®æ»šåŠ¨æ¡å®½åº¦ */
}
>>>.el-form-item {
    margin-bottom: 3px;
}
.el-input {
    border-radius: 15px;
}
.el-icon-picture-outline {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}
.uploadFile {
    margin-top: 2px;
    float: left;
}
  .avatar-uploader-icon {
    font-size: 28px;
    color: #0f8bf1;
    width: 178px;
    height: 50px;
    text-align: center;
    border: 1px solid #d9d9d9;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,317 @@
<template>
  <div>
    <div style="display: flex;justify-content: space-between;">
      <el-form :model="entity" ref="entity" size="small" :inline="true">
        <el-form-item label="人员名称">
          <el-input v-model="entity.name" clearable></el-input>
        </el-form-item>
        <el-form-item>
          <el-button size="small" style="margin-left: 10px" @click="refresh()">重 ç½®</el-button>
          <el-button size="small" type="primary" @click="refreshTable()">查 è¯¢</el-button>
        </el-form-item>
      </el-form>
      <div>
        <el-button
          :loading="outLoading"
          size="small"
          type="primary"
          @click="handleDown">导出</el-button>
        <el-button size="small" type="primary" @click="openSelectUserDia">新建</el-button>
      </div>
    </div>
    <div class="search-table">
      <el-table v-loading="tableLoading" :data="tableData" border height="calc(100vh - 21em)" style="width: 100%;">
        <el-table-column align="center" label="序号" type="index" width="60"></el-table-column>
        <el-table-column label="员工编号" prop="account" width="150"></el-table-column>
        <el-table-column label="姓名" prop="name" width="120"></el-table-column>
        <el-table-column label="籍贯" prop="nativePlace" width="120"></el-table-column>
        <el-table-column label="证件地址" prop="idAddress" show-overflow-tooltip width="100"></el-table-column>
        <el-table-column label="手机号" prop="telephone" show-overflow-tooltip width="100"></el-table-column>
        <el-table-column label="毕业院校" prop="graduatedInstitutions1" width="100"></el-table-column>
        <el-table-column label="所学专业" prop="major1" width="100"></el-table-column>
        <el-table-column label="毕业时间" prop="graduationTime1" width="100"></el-table-column>
        <el-table-column label="最高学历" prop="officialAcademicRedentials" width="100"></el-table-column>
        <el-table-column label="最高学位" prop="highestDegree" width="100"></el-table-column>
        <el-table-column label="职称" prop="professionalTitle" width="100"></el-table-column>
        <el-table-column fixed="right" label="操作" width="120" align="center">
          <template slot-scope="scope">
            <el-button size="small" type="text" @click="$emit('updatePerson', scope.row)">编辑</el-button>
            <el-button size="small" type="text" @click="deletePerson(scope.row)" style="color: #f56c6c">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        :current-page="1"
        :current-page.sync="page.current"
        :page-size="page.size"
        :page-sizes="[10, 20, 30, 50, 100]"
        :total="page.total"
        background
        layout="->,total, sizes, prev, pager, next, jumper"
        style="margin-top: 10px"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>
    <el-dialog :visible.sync="selectUserDia" title="选择用户" width="70%">
      <div class="search" style="margin-bottom: 9px;">
        <div class="search_thing">
          <div class="search_label">用户名:</div>
          <div class="search_input">
            <el-input
              v-model="addUserTableInfo.name"
              clearable
              placeholder="请输入"
              size="small"
              @change="selectUserList"
            ></el-input>
          </div>
          <el-button size="small" style="margin-left: 10px" type="primary" @click="selectUserList">查询</el-button>
        </div>
      </div>
      <div v-if="selectUserDia" class="body" style="height: 60vh;">
        <lims-table :tableData="tableData1" :column="column1"
                    :isSelection="true" :handleSelectionChange="selectMethod"
                    :height="'calc(100vh - 290px)'"
                    :tableLoading="tableLoading1"></lims-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="selectUserDia = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="selectUser">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {selectUserCondition} from "@/api/business/inspectionTask";
import limsTable from "@/components/Table/lims-table.vue";
import {
  basicInformationOfPersonnelSelectPage,
  delUserDepardLimsId,
  exportPersonBasicInfo,
  upUserDepardLimsId
} from "@/api/cnas/personal/personalList";
import store from "@/store";
import {Message} from "element-ui";
export default {
  name: 'PersonnelList',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {limsTable},
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    },
    currentCompaniesList: {
      type: Array,
      default: []
    }
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      page: {
        size: 20,
        current: 1,
      },
      outLoading: false,
      tableLoading: false,
      tableData: [], // äººå‘˜æ€»åˆ—表数据
      tableData1: [],
      tableLoading1: false,
      column1: [
        {label: '姓名', prop: 'name'},
        {label: '账号', prop: 'account'},
        {label: '角色', prop: 'roleName'},
        {
          dataType: 'tag',
          label: '状态',
          prop: 'status',
          formatData: (params) => {
            if (params == 0) {
              return '启用'
            } else {
              return ''
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'success'
            } else {
              return 'danger'
            }
          }
        },
        {label: '电话号码', prop: 'phone'},
      ],
      page1: {
        total:0,
        size:10,
        current:1
      },
      selectUserDia: false, // æ·»åŠ äººå‘˜å¼¹æ¡†
      entity: {
        name: '',
        orderBy: {
          field: 'id',
          order: 'asc'
        }
      },
      addUserTableInfo: {
        name: null,
        isCustom: 0,
      },
      multipleSelection: []
    };
  },
  mounted() {
    this.refreshTable();
  },
  // æ–¹æ³•集合
  methods: {
    /**
     * @desc èŽ·å–è®¾å¤‡id
     */
    // é‡ç½®
    refresh() {
      this.page = {
        size: 20,
        current: 1,
      };
      this.entity.name = ''
      this.refreshTable();
    },
    // æŸ¥è¯¢äººå‘˜åˆ—表数据
    refreshTable() {
      this.tableLoading = true;
      this.entity.departLimsId = this.departId;
      const params = {
        size: this.page.size,
        current: this.page.current,
        departmentId: this.entity.departLimsId,
        name: this.entity.name,
      }
      basicInformationOfPersonnelSelectPage(params).then(res => {
        this.tableLoading = false;
        this.page.total = res.data.total;
        this.tableData = res.data.records;
      }).catch(err => {
        this.tableLoading = false;
      })
    },
    // åˆ é™¤äººå‘˜
    deletePerson(row) {
      this.$confirm('是否删除当前数据?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delUserDepardLimsId({id: row.userId}).then(res => {
          this.$message.success('删除成功');
          this.refreshTable();
          this.$emit('refreshTree')
        }).catch(e => {
          this.$message.error('删除失败');
        });
      }).catch(() => {
      });
    },
    handleSizeChange(val) {
      this.page.size = val;
      this.refreshTable();
    },
    handleCurrentChange(val) {
      this.page.current = val;
      this.refreshTable();
    },
    // æ‰“开新增人员弹框
    openSelectUserDia () {
      this.selectUserDia = true;
      this.selectUserList()
    },
    // æŸ¥è¯¢æ–°å¢žå¼¹æ¡†çš„人员列表
    selectUserList () {
      this.tableLoading1 = true
      selectUserCondition().then(res => {
        this.tableLoading1 = false
        this.tableData1 = res.data
      }).catch(err => {
        this.tableLoading1 = false
      })
    },
    // è¡¨æ ¼é€‰æ‹©æ–¹æ³•
    selectMethod(val) {
      this.multipleSelection = val
    },
    // æäº¤éœ€è¦æ·»åŠ çš„äººå‘˜
    selectUser() {
      if (!this.currentCompaniesList.length > 0) {
        this.$message.warning("请选择部门!")
        return;
      }
      let selects = this.HaveJson(this.multipleSelection)
      if (selects.length === 0) {
        this.$message.error('未选择数据');
        return;
      }
      let ids = [];
      selects.forEach(a => {
        ids.push(a.id);
      });
      let str = '';
      this.currentCompaniesList.forEach(a => {
        if (a) {
          str += a + ',';
        }
      });
      upUserDepardLimsId({
        ids: JSON.stringify(ids),
        id: str
      }).then(res => {
        this.selectUserDia = false;
        this.$message.success('添加成功');
        this.refreshTable();
        this.$emit('refreshTree')
      });
    },
    // å¯¼å‡ºäººå‘˜ä¿¡æ¯
    handleDown() {
      this.outLoading = true;
      let entity = this.HaveJson(this.entity)
      delete entity.orderBy;
      exportPersonBasicInfo({...entity}).then(res => {
        this.outLoading = false;
        const blob = new Blob([res], {type: 'application/octet-stream'});
        this.$download.saveAs(blob, '人员信息.xlsx')
        this.$message.success('导出成功')
      })
    },
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (newId) {
          this.page.current = 1
          this.refreshTable();
        }
      }
    }
  }
};
</script>
<style scoped>
.search_thing {
  display: flex;
  align-items: center;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,802 @@
<!-- äººå‘˜åŸ¹è®­ -->
<template>
  <div class="flex_column">
    <div v-if="!editPlanShow && isDepartment">
      <div class="title">
        <span style="font-weight: bold">年度计划</span>
      </div>
      <div style="display: flex;justify-content: space-between;">
        <el-form :model="page" ref="page" size="small" :inline="true">
          <el-form-item label="编制人">
            <el-input v-model="page.compilerName" clearable></el-input>
          </el-form-item>
          <el-form-item>
            <el-button size="small" type="primary" @click="getYearPlanList(departId)">查 è¯¢</el-button>
          </el-form-item>
        </el-form>
        <div>
          <el-button size="small" type="primary" @click="uploadDia = true, getUserList()">导入</el-button>
        </div>
      </div>
      <lims-table :tableData="yearPlanTableData" :column="yearPlanColumn"
                  :currentChange="currentChange"
                  @pagination="pagination" height="40vh"
                  :page="page" :tableLoading="yearLoading"></lims-table>
    </div>
    <div v-if="!editPlanShow" class="table">
      <div>
        <div class="title">
          <span style="font-weight: bold">年度计划明细</span>
        </div>
        <div style="display: flex;justify-content: space-between;">
          <el-form :model="inDetailForm" ref="inDetailForm" size="small" :inline="true">
            <el-form-item label="培训讲师">
              <el-input v-model="inDetailForm.trainingLecturerName" class="search" clearable placeholder="请输入" size="small"></el-input>
            </el-form-item>
            <el-form-item label="培训日期">
              <el-date-picker v-model="inDetailForm.trainingDate" clearable
                              format="yyyy-MM-dd" placeholder="选择日期" size="small"
                              type="date" value-format="yyyy-MM-dd"></el-date-picker>
            </el-form-item>
            <el-form-item>
              <el-button size="small" type="primary" @click="searchTable">查 è¯¢</el-button>
            </el-form-item>
          </el-form>
          <div>
            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" @click="batchDelete">批量删除</el-button>
            <el-button v-if="isDepartment && currentChangeRow && isOperation" size="small" type="primary" @click="addTrainingPlan('add')">新增</el-button>
          </div>
        </div>
        <lims-table :tableData="inDetailPlanTableData" :column="inDetailPlanColumn"
                    :height="isDepartment ? '40vh' : '62vh' "
                    :isSelection="true" :handleSelectionChange="handleSelectionChange"
                    @pagination="pagination1"
                    :page="inDetailPagination" :tableLoading="yearDetailLoading"></lims-table>
      </div>
    </div>
    <Add ref="addPlan" :currentChangeRow="currentChangeRow" @search="getInDetailPlan(currentRowId, departId)"></Add>
    <Edit
      v-if="editPlanShow"
      ref="editPlan"
      :currentRow="currentRow"
      @del="getInDetailPlan(currentRowId, departId)"
      @goBack="goBack"
    ></Edit>
    <el-dialog :visible.sync="reviewDialog" title="审核" width="30%" @close="auditRemarks = ''">
      <span>
        å®¡æ ¸å¤‡æ³¨ï¼š
        <el-input v-model="auditRemarks" type="textarea"></el-input>
      </span>
      <span style="margin-top: 10px;display: inline-block">
        æ‰¹å‡†äººï¼š
        <el-select v-model="approverId" clearable
                   filterable size="small" style="width: 70%;">
          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button :loading="reviewLoading" @click="handleReview(2)">不通过</el-button>
        <el-button :loading="reviewLoading" type="primary" @click="handleReview(1)">通 è¿‡</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="approvalDialog" title="批准" width="30%" @close="approvalRemarks = ''">
      <span>
        æ‰¹å‡†å¤‡æ³¨ï¼š
        <el-input v-model="approvalRemarks" type="textarea"></el-input>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button :loading="approvalLoading" @click="handleApproval(2)">不批准</el-button>
        <el-button :loading="reviewLoading" type="primary" @click="handleApproval(1)">批 å‡†</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="uploadDia" title="数据导入" width="500px">
      <div style="display: flex;align-items: center;">
        <div style="width: 70px">年份:</div>
        <el-date-picker
          v-model="planYear"
          type="year"
          value-format="yyyy"
          clearable
          size="small"
          format="yyyy"
          placeholder="选择年">
        </el-date-picker>
      </div>
      <div style="display: flex;align-items: center;margin: 10px 0">
        <div style="width: 70px">审核人:</div>
        <el-select v-model="reviewerId" clearable
                   filterable size="small" style="width: 50%;">
          <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </div>
      <div style="margin: 0 auto;">
        <el-upload ref="upload" :action="javaApi + '/personTraining/personTrainingImport' + '?planYear=' + planYear + '&reviewerId=' + reviewerId"
                   :auto-upload="false" :before-upload="beforeUpload" :file-list="fileList" :headers="uploadHeader"
                   :limit="1" :on-error="onError" :on-success="onSuccess" accept=".xlsx" drag
                   name="file">
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        </el-upload>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="uploadDia = false">取 æ¶ˆ</el-button>
        <el-button :loading="uploading" type="primary" @click="submitUpload()">上 ä¼ </el-button>
      </span>
    </el-dialog >
    <view-record v-if="ViewRecord" ref="ViewRecord"></view-record>
  </div>
</template>
<script>
import Add from '../components/AddInDetail.vue';
import Edit from '../components/Edit.vue';
import ViewRecord from "../components/ViewRecord.vue";
import limsTable from "@/components/Table/lims-table.vue";
import {mapGetters} from "vuex";
import {
  approveAnnualPersonnelTraining, deleteAnnualPlanDetailTable, exportPersonTraining, exportPersonTrainingRecord,
  personTraining,
  personTrainingDelete,
  queryTheAnnualPlanDetailsTable, reviewAnnualPersonnelTraining
} from "@/api/cnas/personal/personalTraining";
import {selectUserCondition} from "@/api/system/user";
export default {
  name: 'PersonnelTraining',
  components: {limsTable, ViewRecord, Add, Edit },
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  data() {
    return {
      planYear: '',
      reviewerId: '',
      responsibleOptions: [],
      search: {},
      superviseForm: {},
      inDetailForm: {
        trainingLecturerName: '',
        trainingDate: '',
      },
      yearLoading: false,
      yearDetailLoading: false,
      yearPlanTableData: [], // å¹´åº¦è®¡åˆ’表数据
      yearPlanColumn: [
        {
          label: '文件名称',
          width: '160px',
          prop: 'fileName'
        }, {
          label: '创建时间',
          width: '160px',
          prop: 'createTime'
        },{
          label: '编制人',
          prop: 'compilerName'
        }, {
          label: '编制日期',
          width: '160px',
          prop: 'compilationDate'
        }, {
          label: '审核人',
          prop: 'reviewerName',
          minWidth: '100px',
        }, {
          dataType: 'tag',
          label: '审核状态',
          prop: 'reviewerStatus',
          width: '100px',
          formatData: (params) => {
            if (params == 1) {
              return '通过';
            } else if (params == 2) {
              return '不通过';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 1) {
              return 'success';
            } else if (params == 2) {
              return 'danger';
            } else {
              return null
            }
          }
        }, {
          label: '审核备注',
          prop: 'auditRemarks',
          minWidth: '100px',
        }, {
          label: '审核日期',
          width: '160px',
          prop: 'auditDate'
        }, {
          label: '批准人',
          prop: 'approverName',
          minWidth: '100px',
        }, {
          label: '批准备注',
          prop: 'approvalRemarks',
          minWidth: '100px',
        }, {
          dataType: 'tag',
          label: '批准状态',
          minWidth: '100px',
          prop: 'approvalStatus',
          formatData: (params) => {
            if (params == 1) {
              return '批准';
            } else if (params == 2) {
              return '不批准';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 1) {
              return 'success';
            } else if (params == 2)  {
              return 'danger';
            } else {
              return null
            }
          }
        }, {
          label: '批准日期',
          width: '160px',
          prop: 'approvalDate'
        }, {
          dataType: 'action',
          width: '180px',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '导出',
              type: 'text',
              disabled: (row) => {
                if(row.approvalStatus === 1 && row.reviewerStatus === 1) {
                  return false;
                } else {
                  return true;
                }
              },
              clickFun: (row) => {
                this.downLoadPost(row);
              }
            },
            {
              name: '审核',
              type: 'text',
              disabled: (row) => {
                if(row.reviewerStatus === 1 || this.userId != row.reviewerId) {
                  return true;
                } else {
                  return false;
                }
              },
              clickFun: (row) => {
                this.handleCheck(row.id);
              }
            },
            {
              name: '批准',
              type: 'text',
              disabled: (row) => {
                if(row.approvalStatus === 1 || this.userId != row.approverId || row.reviewerStatus != 1) {
                  return true;
                } else {
                  return false;
                }
              },
              clickFun: (row) => {
                this.handleApprove(row.id);
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteFun(row.id);
              },
              disabled: (row) => {
                if(row.reviewerStatus === 1) {
                  return true;
                } else {
                  return false;
                }
              },
            }
          ]
        }],
      inDetailPlanTableData: [], // å¹´åº¦è®¡åˆ’明细表表数据
      inDetailPlanColumn: [
       {
          label: '培训目标',
          prop: 'trainingObjectives',
          width: '100px',
        }, {
          label: '培训内容',
          prop: 'trainingContent',
          width: '100px',
        }, {
          label: '培训方式',
          prop: 'trainingMode',
          width: '100px',
        }, {
          dataType: 'tag',
          label: '课程状态',
          width: '100px',
          prop: 'state',
          formatData: (params) => {
            if (params == 1) {
              return '已完成';
            } else if (params == 2) {
              return '待评价';
            } else if (params == 3) {
              return '未开始';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 1) {
              return 'success';
            } else if (params == 2) {
              return 'warning';
            } else if (params == 3) {
              return 'primary';
            } else if (params == 4) {
              return 'info';
            } else {
              return null
            }
          }
        }, {
          label: '参加对象',
          prop: 'participants',
          width: '100px',
        }, {
          label: '举办部门',
          prop: 'holdingDepartment',
          width: '100px',
        }, {
          label: '培训讲师',
          prop: 'trainingLecturerName',
          width: '100px',
        }, {
          label: '培训日期',
          prop: 'trainingDate',
          width: '100px',
        }, {
          label: '开始时间',
          prop: 'openingTime',
          width: '100px',
        }, {
          label: '课时',
          prop: 'classHour',
          width: '100px',
        }, {
          label: '备注',
          prop: 'remarks',
          width: '100px',
        }, {
          dataType: 'action',
          width: '200',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.addTrainingPlan('edit', row);
              },
            },
            {
              name: '结果明细',
              type: 'text',
              clickFun: (row) => {
                this.editInDetail(row);
              },
              showHide: () => {
                if (this.isDepartment) {
                  return true;
                } else {
                  return false;
                }
              }
            },
            {
              name: '附件',
              type: 'text',
              clickFun: (row) => {
                this.viewRecord(row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadInDetail(row);
              }
            },
          ]
        }],
      page: {
        total:0,
        size:10,
        current:1,
        compilerName: ""
      },
      inDetailPagination: {
        total:0,
        size:10,
        current:1,
      },
      editPlanShow: false,
      currentRow: {},
      currentRowId: null, // å½“前选中数据的id
      auditRemarks: '', // å®¡æ ¸å¤‡æ³¨
      reviewDialog: false, // å®¡æ ¸å¼¹æ¡†
      reviewLoading: false, // å®¡æ ¸æäº¤æŒ‰é’®
      approvalRemarks: '', // å®¡æ ¸å¤‡æ³¨
      approvalDialog: false, // å®¡æ ¸å¼¹æ¡†
      approvalLoading: false, // å®¡æ ¸æäº¤æŒ‰é’®
      multipleSelection: [], // å¹´åº¦æ˜Žç»†è¡¨é€‰ä¸­çš„æ•°æ®
      uploadDia: false,
      uploading: false,
      isOperation: false,
      ViewRecord: false,
      fileList: [],
      currentChangeRow: {},
      approverId: ''
    };
  },
  mounted() {
    if (this.isDepartment) {
      this.getYearPlanList(this.departId)
    } else {
      this.getInDetailPlan('', this.departId)
    }
  },
  methods: {
    searchTable () {
      this.getInDetailPlan(this.currentRowId)
    },
    // æŸ¥è¯¢-年度计划表
    getYearPlanList(userId) {
      this.yearLoading = true
      const params = this.isDepartment ?
      {
        departmentId: userId,
        size: this.page.size,
        current: this.page.current,
        compilerName: this.page.compilerName,
      }: {
          userId: userId,
          size: this.page.size,
          current: this.page.current,
          compilerName: this.page.compilerName,
        }
      personTraining(params).then(res => {
        this.yearLoading = false
        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])
        }
      }).catch(err => {
        this.yearLoading = false
      })
    },
    pagination (page) {
      this.page.size = page.limit
      this.getYearPlanList()
    },
    currentChange (row) {
      const now = new Date();
      const currentYear = now.getFullYear();
      if (row) {
        this.currentChangeRow = row
        this.currentRowId = row.id
        if (row.createTime.slice(0,4) == currentYear) {
          this.isOperation = true;
        } else {
          this.isOperation = false;
        }
        this.getInDetailPlan(row.id)
      }
    },
    getInDetailPlan (id) {
      if (this.inDetailForm.trainingDate === null) {
        this.inDetailForm.trainingDate = ''
      }
      const userId = this.isDepartment ? '' : this.departId
      const params =
        {
          userId: userId,
          size: this.inDetailPagination.pageSize,
          current: this.inDetailPagination.current,
          id: id,
          trainingLecturerName: this.inDetailForm.trainingLecturerName,
          trainingDate: this.inDetailForm.trainingDate,
        }
      this.yearDetailLoading = true
      queryTheAnnualPlanDetailsTable(params).then(res => {
        this.yearDetailLoading = false
        this.inDetailPlanTableData = res.data.records;
        this.inDetailPagination.total = res.data.total;
      }).catch(err => {
        this.yearDetailLoading = false
      })
    },
    pagination1 (page) {
      this.inDetailPagination.size = page.limit
      this.getInDetailPlan(this.currentRowId)
    },
    // æ–°å¢žå¹´åº¦è®¡åˆ’明细表
    addTrainingPlan(type, row) {
      if (!this.currentRowId) {
        this.$message.warning('请选择一条计划进行新增')
        return
      }
      this.$refs.addPlan.showDialog(this.currentRowId, type, row);
    },
    // å¹´åº¦è®¡åˆ’表-删除
    deleteFun(id) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        personTrainingDelete({id: id}).then(res => {
          this.$message.success('删除成功!');
          this.getYearPlanList(this.departId);
        });
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // å¹´åº¦è®¡åˆ’表-审核
    handleCheck(id) {
      this.currentRowId = id
      this.reviewDialog = true
      this.getUserList()
    },
    // æäº¤å®¡æ ¸
    handleReview (status) {
      const personTrainingUpdateDto = {
        id: this.currentRowId,
        auditRemarks: this.auditRemarks,
        reviewerStatus: status,
        approverId: this.approverId
      }
      this.reviewLoading = true
      reviewAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
        if (res.code === 200) {
          this.$message.success('提交成功!');
          this.reviewDialog = false
          this.getYearPlanList(this.departId);
        }
        this.reviewLoading = false
      }).catch(() => {
        this.reviewLoading = false
      })
    },
    // å¹´åº¦è®¡åˆ’表-批准
    handleApprove(id) {
      this.currentRowId = id
      this.approvalDialog = true
    },
    // æäº¤æ‰¹å‡†
    handleApproval (status) {
      const personTrainingUpdateDto = {
        id: this.currentRowId,
        approvalRemarks: this.approvalRemarks,
        approvalStatus: status
      }
      this.approvalLoading = true
      approveAnnualPersonnelTraining(personTrainingUpdateDto).then(res => {
        if (res.code === 200) {
          this.$message.success('提交成功!');
          this.approvalDialog = false
          this.getYearPlanList(this.departId);
        }
        this.approvalLoading = false
      }).catch(() => {
        this.approvalLoading = false
      })
    },
    // å¹´åº¦è®¡åˆ’表-下载
    downLoadPost(row) {
      exportPersonTraining({id: row.id}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, row.fileName + '.docx')
        this.$message.success('导出成功')
      })
    },
    // å¹´åº¦è®¡åˆ’-导入
    submitUpload() {
      if (this.$refs.upload.uploadFiles.length == 0) {
        this.$message.error('未选择文件')
        return
      }
      this.uploading = true
      this.$refs.upload.submit();
      this.uploading = false
    },
    onSuccess(response, file, fileList) {
      this.$refs.upload.clearFiles()
      this.uploadDia = false
      this.uploading = false
      if (response.code != 200) {
        this.$message.error(response.msg)
        return
      }
      this.$message.success('上传成功')
      this.standardList = []
      this.productList = []
      this.getYearPlanList(this.departId)
    },
    onError(err, file, fileList) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
      this.uploading = false
    },
    beforeUpload(file, fileList) {
      if (file.type != 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
        this.$message.error('上传文件格式不正确');
        this.$refs.upload.clearFiles()
        return false;
      }
    },
    // å¹´åº¦è®¡åˆ’明细表-编辑
    editInDetail(row) {
      this.editPlanShow = true;
      this.currentRow = row
    },
    //
    goBack() {
      this.editPlanShow = false;
      this.getInDetailPlan(this.currentRowId)
    },
    viewRecord (row) {
      this.ViewRecord = true
      this.$nextTick(() => {
        this.$refs.ViewRecord.openDia(row)
      })
    },
    // å¹´åº¦è®¡åˆ’明细表-下载
    downLoadInDetail(row) {
      exportPersonTrainingRecord({id: row.id}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '人员培训与考核记录.docx')
        this.$message.success('导出成功')
      })
    },
    // å¹´åº¦è®¡åˆ’明细表-多选
    handleSelectionChange(list) {
      this.multipleSelection = list
    },
    // å¹´åº¦æ˜Žç»†è¡¨-删除
    batchDelete () {
      if (this.multipleSelection.length > 0) {
        let ids = []
        this.multipleSelection.forEach(item => {
          ids.push(item.id)
        })
        this.$confirm('是否确认删除所选择的数据?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          deleteAnnualPlanDetailTable({ids: ids.join(',')}).then(res => {
            if (res.code == 200) {
              this.$message.success('删除成功');
              this.getInDetailPlan(this.currentRowId);
            }
          });
        }).catch(() => {
          this.$message.warning('取消删除');
        });
      } else {
        this.$message.warning('请选择需要删除的数据')
      }
    },
    handleSizeChange(val) {
      this.inDetailPagination.size = val;
      this.getInDetailPlan(this.currentChangeRow.id)
    },
    handleCurrentChange(val) {
      this.inDetailPagination.current = val;
      this.getInDetailPlan(this.currentChangeRow.id)
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      selectUserCondition().then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      });
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    departId: {
      handler(newId, oldId) {
        if (this.isDepartment) {
          this.getYearPlanList(newId);
        } else {
          this.getInDetailPlan('')
        }
      }
    },
    currentRowId: {
      handler(newId, oldId) {
        if (newId) {
          console.log('newId', newId);
          this.inDetailPagination.current = 1
          this.getInDetailPlan(this.currentChangeRow.id)
        }
      }
    }
  }
}
</script>
<style scoped>
.flex_column {
  display: flex;
  height: 80vh;
  flex-direction: column;
  overflow: auto;
  justify-content: space-between;
}
.search {
  width: 150px;
  margin: 0 16px;
}
.title {
  position: relative;
  font-size: 16px;
  color: #333;
  font-weight: 400;
  padding-left: 10px;
  margin-bottom: 10px;
}
.title::before {
  position: absolute;
  left: 0;
  top: 4px;
  content: '';
  width: 4px;
  height: 16px;
  background-color: #3A7BFA;
  border-radius: 2px;
}
</style>
src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,344 @@
<!-- å¥–惩记录 -->
<template>
  <div>
    <div class="view">
      <div style="display: flex;justify-content: space-between;">
        <el-form :model="search" ref="page" size="small" :inline="true">
          <el-form-item label="姓名">
            <el-input v-model="search.userName" clearable placeholder="请输入关键字" size="small" style="width: 20vh;"></el-input>
          </el-form-item>
          <el-form-item 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: 100%"
              type="daterange"
              unlink-panels
              value-format="yyyy-MM-dd 00:00:00">
            </el-date-picker>
          </el-form-item>
          <el-form-item>
            <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">查询</el-button>
          </el-form-item>
        </el-form>
        <div>
          <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">导出</el-button>
          <el-button size="small" type="primary" @click="addRow">新增</el-button>
        </div>
      </div>
    </div>
    <div class="table">
      <el-table :data="tableData" v-loading="tableLoading" height="66.5vh" 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" align="center">
          <template v-slot="scope">
            <el-button size="small" type="text" @click="editForm(scope.row)">编辑</el-button>
            <el-button size="small" type="text" style="color: #f56c6c" @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"
                     background
                     style="margin-top: 10px"
                     @size-change="handleSizeChange"
                     @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    <el-dialog
      :visible.sync="dialogVisible"
      title="奖惩记录"
      width="50%"
      @open="getUserList">
      <div style="height: 40vh">
        <el-form ref="form" :model="form" :rules="rules" label-width="120px">
          <el-col :span="12">
            <el-form-item label="员工编号">
              <el-input v-model="form.account" disabled size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="员工姓名" prop="userId">
              <el-select v-model="form.userId" placeholder="请选择" size="small" style="width: 100%" value-key="id"
                         @change="selectUserChange" :disabled="!isDepartment">
                <el-option v-for="item in responsibleOptions" :key="item.id" :label="item.name" :value="item.id">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩级别" prop="rewardPunishLevel">
              <el-input v-model="form.rewardPunishLevel" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩名称" prop="rewardPunishName">
              <el-input v-model="form.rewardPunishName" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩时间" prop="rewardPunishTime">
              <el-date-picker
                v-model="form.rewardPunishTime"
                format="yyyy-MM-dd HH:mm:ss"
                placeholder="选择日期"
                size="small"
                style="width: 100%"
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss">
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="奖惩单位" prop="rewardPunishWorkUnit">
              <el-input v-model="form.rewardPunishWorkUnit" size="small"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="奖惩内容">
              <el-input v-model="form.rewardPunishContent" :rows="2" size="small" type="textarea"></el-input>
            </el-form-item>
          </el-col>
        </el-form>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="saveOrUpdate">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  addOrUpdateRewardPunishment, deleteRewardPunishment,
  rewardPunishmentExport,
  rewardPunishmentPage
} from "@/api/cnas/personal/personRewardPunishmentRecord";
import {selectUserCondition} from "@/api/system/user";
import {delCustomById} from "@/api/system/customer";
export default {
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      tableData: [],
      tableLoading: false,
      search: {
        size: 20,
        current: 1,
        total: 0,
        userName: '',
        searchTimeList: []
      },
      form: {},
      dialogVisible: false,
      outLoading: false,
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
            picker.$emit('pick', [start, end]);
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
            picker.$emit('pick', [start, end]);
          }
        }, {
          text: '最近三个月',
          onClick(picker) {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
            picker.$emit('pick', [start, end]);
          }
        }]
      },
      rules: {
        userId: [{
          required: true, message: '请选择员工', trigger: 'change'
        }],
        rewardPunishLevel: [{
          required: true, message: '请输入奖惩级别', trigger: 'blur'
        }],
        rewardPunishName: [{
          required: true, message: '请输入奖惩名称', trigger: 'blur'
        }],
        rewardPunishTime: [{
          required: true, message: '请输入奖惩时间', trigger: 'blur'
        }],
        rewardPunishWorkUnit: [{
          required: true, message: '请输入奖惩单位', trigger: 'blur'
        }]
      },
      responsibleOptions: []
    };
  },
  mounted() {
    this.getPersonnelTraining(this.departId);
  },
  methods: {
    handleSizeChange(val) {
      this.search.size = val
      this.getPersonnelTraining(this.departId);
    },
    handleCurrentChange(val) {
      this.search.current = val
      this.getPersonnelTraining(this.departId);
    },
    async getPersonnelTraining() {
      const 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],
      }
      this.tableLoading = true
      rewardPunishmentPage(params).then(res => {
        this.tableLoading = false
        this.tableData = res.data.records
        this.search.total = res.data.total
      }).catch(err => {
        this.tableLoading = false
      })
    },
    addRow () {
      this.dialogVisible = true
      if (!this.isDepartment) {
        this.form.userId = this.departId
        this.selectUserChange(this.form.userId)
      }
    },
    handleDown(){
      this.outLoading = true
      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]
      }).then(res => {
        this.outLoading = false
        const blob = new Blob([res], {
          type: 'application/force-download'
        })
        this.$download.saveAs(blob, '奖惩记录.xlsx')
        this.$message.success('导出成功')
      })
    },
    // èŽ·å–è´Ÿè´£äººä¿¡æ¯æŽ¥å£
    getUserList() {
      selectUserCondition().then(res => {
        if (res.code == 200) {
          this.responsibleOptions = res.data
        }
      });
    },
    selectUserChange(val) {
      const index = this.responsibleOptions.findIndex(item => item.id === val)
      if (index > -1) {
        this.form.userName = this.responsibleOptions[index].name
        this.form.account = this.responsibleOptions[index].account
      }
    },
    // æ‰“开表单弹框
    editForm(row) {
      this.dialogVisible = true
      this.form = {...row};
    },
    // æäº¤è¡¨å•数据
    saveOrUpdate() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          addOrUpdateRewardPunishment(this.form).then(res => {
            this.dialogVisible = false
            this.$message.success("操作成功")
            this.getPersonnelTraining(this.departId);
          })
        }
      })
    },
    deleteRow(row) {
      this.$confirm('是否删除当前数据?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        deleteRewardPunishment({id: row.id}).then(res => {
          if (res.code === 500) {
            return
          }
          this.$message.success('删除成功')
          this.getPersonnelTraining(this.departId);
        }).catch(e => {
          this.$message.error('删除失败')
        })
      }).catch(() => {})
    }
  },
  watch: {
    // ç›‘听点击el-tree的数据,进行数据刷新
    departId: {
      handler(newId, oldId) {
        this.getPersonnelTraining(newId);
      }
    },
    dialogVisible(newVal) {
      if (newVal === false) {
        this.form = {}
        this.$refs['form'].resetFields()
      }
    }
  }
};
</script>
src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,303 @@
<!-- åŸ¹è®­è®°å½• -->
<template>
  <div>
    <div class="flex_table">
      <div v-if="isDepartment" style="width: 49%">
        <div class="title">
          <span style="font-weight: bold">年度计划</span>
        </div>
        <div style="display: flex;justify-content: space-between;">
          <el-form :model="trainingPagination" ref="trainingPagination" size="small" :inline="true">
            <el-form-item label="姓名">
              <el-input v-model="trainingPagination.userName" class="search" clearable placeholder="请输入" size="small"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">查询</el-button>
            </el-form-item>
          </el-form>
        </div>
        <lims-table :tableData="trainingTableData" :column="trainingColumn"
                    ref="trainingTableData"
                    :currentChange="currentChange" :highlightCurrentRow="true"
                    @pagination="pagination" :height="'calc(100vh - 22em)'"
                    :page="trainingPagination" :tableLoading="trainingLoading"></lims-table>
      </div>
      <div :style="`width: ${isDepartment ? '49%' : '100%'};`">
        <div class="title">
          <span style="font-weight: bold">年度计划明细</span>
        </div>
        <div style="display: flex;justify-content: space-between;">
          <el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
            <el-form-item label="年份">
              <el-date-picker
                v-model="searchForm.trainingDate"
                clearable
                format="yyyy"
                placeholder="选择年"
                size="small"
                type="year"
                value-format="yyyy">
              </el-date-picker>
            </el-form-item>
            <el-form-item>
              <el-button size="small" type="primary" @click="queryPersonnelDetailsPage(currentChangeRow.userId)">查询</el-button>
            </el-form-item>
          </el-form>
          <div>
            <el-button size="small" type="primary" @click="openDownloadDia(currentChangeRow)">导出</el-button>
          </div>
        </div>
        <lims-table :tableData="trainingPersonTableData" :column="trainingPersonColumn"
                    :height="'calc(100vh - 22em)'" @pagination="pagination1"
                    :page="trainingPersonPagination" :tableLoading="trainingPersonLoading"></lims-table>
      </div>
    </div>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import {
  exportTrainingRecord,
  queryPersonnelDetails,
  trainingSelectTrainingRecord
} from "@/api/cnas/personal/personTrainingRecord";
export default {
  components: {limsTable},
  props: {
    departId: {
      type: Number,
      default: () => {
        return null;
      }
    },
    isDepartment: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      outLoading: false,
      trainingForm: {},
      trainingColumn: [
        {
          label: '员工编号',
          prop: 'account',
          width: '100'
        }, {
          label: '姓名',
          prop: 'name'
        }, {
          label: '所在部门',
          prop: 'departLimsName',
          width: '150'
        }, {
          label: '职称',
          prop: 'professionalTitle'
        }, {
          label: '最高学历',
          prop: 'officialAcademicRedentials',
          width: '100'
        }, {
          label: '入单位时间',
          prop: 'unitTime',
          width: '150'
        },
        // {
        //   fixed: 'right',
        //   dataType: 'action',
        //   width: 80,
        //   label: '操作',
        //   operation: [
        //     {
        //       name: '导出',
        //       type: 'text',
        //       clickFun: (row) => {
        //         this.openDownloadDia(row)
        //       }
        //     }
        //   ]
        // }
      ],
      trainingTableData: [],
      trainingLoading: false,
      trainingPagination: {
        size: 20,
        total: 0,
        current: 1,
        userName: null
      },
      searchForm: {
        trainingDate: ''
      },
      trainingPersonColumn: [
        {
          label: '培训日期',
          prop: 'trainingDate'
        }, {
          label: '培训内容',
          prop: 'trainingContent'
        }, {
          label: '培训课时',
          prop: 'educationBackground'
        }, {
          label: '课时',
          prop: 'classHour'
        }, {
          label: '培训结果',
          prop: 'examinationResults',
        }, {
          label: '备注',
          prop: 'remarks'
        }
      ],
      trainingPersonTableData: [],
      trainingPersonLoading: false,
      trainingPersonPagination: {
        size: 20,
        current: 1,
        total: 0
      },
      currentChangeRow: '',
    };
  },
  mounted() {
    this.getPersonnelTraining(this.departId);
  },
  methods: {
    // exportExcel() {
    //   this.outLoading = true;
    //   const name = this.isDepartment ? 'departmentId' : 'userId';
    //   this.$axios.get(this.$api.personal.personTrackRecordExport + `&${name}=` + this.departId, { responseType: 'blob' }).then(res => {
    //     this.outLoading = false;
    //     this.$message.success('导出成功');
    //     const blob = new Blob([res], { type: 'application/octet-stream' });
    //     const url = URL.createObjectURL(blob);
    //     const link = document.createElement('a');
    //     link.href = url;
    //     link.download = '培训记录.xlsx';
    //     link.click();
    //   }).catch(err => {
    //     this.outLoading = false;
    //   })
    // },
    // æŸ¥è¯¢
    refreshTable() {
      this.getPersonnelTraining(this.departId);
    },
    // åŸ¹è®­è®°å½•导出
    openDownloadDia (row) {
      let date = this.searchForm.trainingDate
      if (!date) {
        date = this.$moment().format('YYYY')
      }
      exportTrainingRecord({userId: row.userId, trainingDate: date}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '培训记录导出.docx');
      })
    },
    // èŽ·å–å®žéªŒå®¤-培训计划列表信息
    getPersonnelTraining(departId) {
      const params = {
        departmentId: departId,
        size: this.trainingPagination.size,
        current: this.trainingPagination.current,
        userName: this.trainingPagination.userName,
      }
      this.trainingLoading = true
      trainingSelectTrainingRecord(params).then(res => {
        this.trainingLoading = false
        this.trainingTableData = res.data.records;
        this.trainingPagination.total = res.data.total;
        if (this.trainingTableData.length > 0) {
          this.$refs.trainingTableData.setCurrentRow(this.trainingTableData[0])
        }
      }).catch(err => {
        this.trainingLoading = false
      })
    },
    // èŽ·å–ä¸ªäºº-培训计划列表信息
    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 = ''
      }
      const params = {
        userId: userId,
        size: this.trainingPersonPagination.size,
        current: this.trainingPersonPagination.current,
        trainingDate: this.searchForm.trainingDate,
      }
      this.trainingPersonLoading = true
      queryPersonnelDetails(params).then(res => {
        this.trainingPersonLoading = false
        this.trainingPersonTableData = res.data.records;
        this.trainingPersonPagination.total = res.data.total;
      }).catch(err => {
        this.trainingPersonLoading = false
      })
    },
    // åˆ†é¡µ
    pagination(page) {
      this.trainingPagination.size = page.limit;
      this.getPersonnelTraining(this.departId);
    },
    // åˆ†é¡µ
    pagination1(page) {
      this.trainingPersonPagination.size = page.limit;
      this.queryPersonnelDetailsPage(this.currentChangeRow.userId);
    },
  },
  watch: {
    departId: {
      handler(newId, oldId) {
        if (this.isDepartment) {
          this.getPersonnelTraining(newId);
        } else {
          this.queryPersonnelDetailsPage(newId)
        }
      }
    }
  }
};
</script>
<style scoped>
.flex_table {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
.search {
  width: 150px;
}
.title {
  position: relative;
  font-size: 16px;
  color: #333;
  font-weight: 400;
  padding-left: 10px;
  margin-bottom: 10px;
}
.title::before {
  position: absolute;
  left: 0;
  top: 4px;
  content: '';
  width: 4px;
  height: 16px;
  background-color: #3A7BFA;
  border-radius: 2px;
}
</style>
src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,138 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="viewDeviceDialog" title="查看设备" width="80%" @close="closeDia">
      <div style="text-align: right;margin-bottom: 10px">
        <el-button size="small" type="primary" @click="addRow">添加</el-button>
        <el-button size="small" type="danger" @click="clearTable">清空</el-button>
      </div>
      <div>
        <el-table :data="machineAttachmentList" border height="500" style="width: 100%">
          <el-table-column header-align="center" label="名称" prop="machineName" width="200">
            <template slot="header" slot-scope="scope">
              <p>名称</p>
            </template>
            <template slot-scope="scope">
              <el-select v-model="scope.row.machineName"
                         class="table_input"
                         clearable
                         filterable
                         placeholder="设备名称"
                         size="small" @change="(val)=>changeMachineName(val, scope.$index)">
                <el-option v-for="item in equipOptions" :key="item.value"  :label="item.label" :value="item.value">
                  {{item.label + item.value}}
                </el-option>
              </el-select>
            </template>
          </el-table-column>
          <el-table-column header-align="center" label="型号规格" prop="machineSpecification" width="180">
            <template slot="header" slot-scope="scope">
              <p>型号规格</p>
            </template>
            <template slot-scope="{row}">
              <el-input v-model="row.machineSpecification" size="small"/>
            </template>
          </el-table-column>
          <el-table-column header-align="center" label="测量范围" prop="machineMeasuringRange">
            <template slot="header" slot-scope="scope">
              <p>测量范围</p>
            </template>
            <template slot-scope="{row}">
              <el-input v-model="row.machineMeasuringRange" size="small" type="textarea"/>
            </template>
          </el-table-column>
          <el-table-column header-align="center" label="①扩展不确定度②最大允差③准确度等级" prop="other">
            <template slot="header" slot-scope="scope">
              <p>①扩展不确定度②最大允差③准确度等级</p>
            </template>
            <template slot-scope="{row}">
              <el-input v-model="row.other" size="small" type="textarea"/>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="handleDeviceInfo">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { deviceScopeSearch } from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'ViewDeviceDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      viewDeviceDialog: false,
      machineAttachmentList: [],
      equipOptions: [],
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(info) {
      this.viewDeviceDialog = true
      this.machineAttachmentList = info.machineAttachmentList
      this.getEquipOptions()
    },
    // å¢žåŠ è¡¨æ ¼è¡Œæ•°æ®
    addRow () {
      this.machineAttachmentList.push({
        machineName: '',
        machineSpecification: '',
        machineMeasuringRange: '',
        other: '',
      })
    },
    // æ¸…空表格数据
    clearTable () {
      this.machineAttachmentList = []
    },
    // é€‰æ‹©è®¾å¤‡çš„回调
    changeMachineName (val, index) {
      const index1 = this.equipOptions.findIndex(item => item.value === val);
      if (index1 !== -1) {
        this.machineAttachmentList[index].deviceId = this.equipOptions[index1].id;
        this.machineAttachmentList[index].machineName = this.equipOptions[index1].deviceName;
      }
      this.machineAttachmentList[index].machineSpecification = val
    },
    // æäº¤è®¾å¤‡ä¿¡æ¯
    handleDeviceInfo () {
      if (this.machineAttachmentList.length === 0) {
        this.$message.warning('请添加信息')
        return
      }
      this.viewDeviceDialog = false
      this.$emit('handleDeviceInfo', this.machineAttachmentList)
    },
    closeDia () {
      this.viewDeviceDialog = false
      this.$emit('closDeviceDia')
    },
    // èŽ·å–æ‰€æœ‰è®¾å¤‡
    getEquipOptions() {
      this.equipOptions = []
      deviceScopeSearch({status:'0'}).then(res => {
        if (res.code === 200 && res.data) {
          this.equipOptions = res.data.map(m => {
            m.value = m.managementNumber
            m.label = m.deviceName
            return m
          })
        }
      }).catch(error => {
        console.error(error)
      })
    },
  }
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,172 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="附件上传" width="80%" @closed="closeFilesLook">
      <div style="display: flex;justify-content: space-between;">
        <el-upload ref='upload'
                   :action="fileAction"
                   :auto-upload="true"
                   :before-upload="fileBeforeUpload" :data="{methodVerifyId: info.methodVerifyId}"
                   :headers="uploadHeader"
                   :on-error="onError"
                   :on-success="handleSuccessUp"
                   :show-file-list="false"
                   accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
          <el-button size="small" style="height: 38px" type="primary">附件上传</el-button>
        </el-upload>
      </div>
      <div>
        <lims-table
          ref="yearTable"
          :column="columnData"
          :height="'calc(100vh - 47em)'"
          :highlightCurrentRow="true"
          :table-data="tableData"
          :table-loading="tableLoading"
          style="margin-top: 0.5em;">
        </lims-table>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from '@/components/Table/lims-table.vue'
import file from "@/utils/file";
import { delVerifyMethodFileList, getVerifyMethodFileList } from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'ViewTestRecord',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { limsTable },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delete(row)
              }
            }
          ]
        }
      ],
      tableData: [],
      info: {}
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      if (this.info === undefined) {
        this.info = {
          methodVerifyId: ''
        }
      }
      this.searchTableList()
    },
    // æŸ¥è¯¢é™„件列表
    searchTableList () {
      this.tableLoading = true
      getVerifyMethodFileList({methodVerifyId:this.info.methodVerifyId}).then(res => {
        this.tableLoading = false
        if (res.code === 200){
          this.tableData = res.data
        }
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    closeFilesLook () {
      this.filesDialogVisible = false
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
    // åˆ é™¤
    delete (row) {
      this.tableLoading = true
      delVerifyMethodFileList({methodFileId:row.methodFileId}).then(res => {
        this.tableLoading = false
        if (res.code === 200){
          this.$message.success('删除成功')
          this.searchTableList()
        }
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    // ä¸Šä¼ éªŒè¯
    fileBeforeUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    onError(err, file, fileList,type) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response, ) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchTableList()
      }
    },
  },
  computed: {
    fileAction() {
      return this.javaApi + '/processMethodVerify/uploadVerifyMethodFile'
    }
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,123 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="查看校准证书" width="80%" @closed="closeFilesLook">
      <div>
        <limsTable
          ref="yearTable"
          :column="columnData"
          :height="'calc(100vh - 47em)'"
          :highlightCurrentRow="true"
          :table-data="tableData"
          :table-loading="tableLoading"
          style="margin-top: 0.5em;">
        </limsTable>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="lookDialogVisible"
      fullscreen
      title="查看附件" top="5vh" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}"
                   :fileUrl="javaApi+'/img/'+currentInfo.fileUrl" style="max-height: 90vh;overflow-y: auto;"/>
    </el-dialog>
  </div>
</template>
<script>
import filePreview from '@/views/tool/file-preview.vue';
import limsTable from '@/components/Table/lims-table.vue'
import file from '@/utils/file';
export default {
  name: 'calibrationsFileDia',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { limsTable, filePreview },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          label: '设备名称',
          prop: 'deviceName',
          minWidth: '150px'
        },
        {
          label: '设备编号',
          prop: 'managementNumber',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '预览',
              type: 'text',
              clickFun: (row) => {
                this.handleLook(row)
              }
            },
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
          ]
        }
      ],
      tableData: [],
      info: {},
      currentInfo:{},
      lookDialogVisible: false,
    };
  },
  mounted() {
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      this.tableData = this.info.calibrationsFileList
    },
    closeFilesLook () {
      this.filesDialogVisible = false
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row){
      this.currentInfo = row
      this.lookDialogVisible = true
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
  }
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,456 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false"
               :title="operationType === 'edit' ? '编辑' : '新增'"
               :visible.sync="formDia"
               width="90%" @close="closeDia">
      <div v-if="operationType === 'edit'" style="text-align: right">
        <el-button :disabled="form.confirmDate !== '' && form.confirmDate !== null && form.confirmDate !== undefined" size="medium" type="primary" @click="validation">验证确认</el-button>
      </div>
      <table border="1" cellspacing="10" class="tables">
        <tr>
          <td>
            <p>标准方法</p>
          </td>
          <td>
            <p>验证原因</p>
          </td>
          <td>
            <p>主要技术变化</p>
          </td>
          <td>
            <p>涉及方面</p>
          </td>
          <td>
            <p>标准要求</p>
          </td>
          <td>
            <p>准备情况</p>
          </td>
          <td>
            <p>是否满足</p>
          </td>
          <td>
            <p>备注</p>
          </td>
        </tr>
        <tr>
          <td rowspan="9">
            <el-input v-model="form.methodName" :rows="6"
                      placeholder="请输入内容"
                      size="small"
                      type="textarea">
            </el-input>
          </td>
          <td rowspan="9">
            <el-input v-model="form.verifyReason" :rows="6"
                      placeholder="请输入内容"
                      size="small"
                      type="textarea">
            </el-input>
          </td>
          <td rowspan="9">
            <el-input v-model="form.technologyChange" :rows="6"
                      placeholder="请输入内容"
                      size="small"
                      type="textarea">
            </el-input>
          </td>
        </tr>
        <tr>
          <td>人:</td>
          <td>
            <el-input v-model="form.personRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.personReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.personIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewWorkPermit">查看上岗证</el-link>
          </td>
        </tr>
        <tr>
          <td>机:</td>
          <td>
            <el-input v-model="form.machineRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.machineReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.machineIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewDevice">查看设备</el-link>
          </td>
        </tr>
        <tr>
          <td>料:</td>
          <td>
            <el-input v-model="form.materialRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.materialReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.materialIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.materialRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td>法:</td>
          <td>
            <el-input v-model="form.methodRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.methodReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.methodIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewTestRecord">查看检测记录</el-link>
          </td>
        </tr>
        <tr>
          <td>环:</td>
          <td>
            <el-input v-model="form.environmentRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.environmentReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.environmentIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.traceabilityRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td>测量溯源性:</td>
          <td>
            <el-input v-model="form.traceabilityRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.traceabilityReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.traceabilityIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewCalibrationsFileDia">查看校准证书</el-link>
          </td>
        </tr>
        <tr>
          <td>样品管理需求:</td>
          <td>
            <el-input v-model="form.managementRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.managementReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.managementIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.managementRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td>其他:</td>
          <td>
            <el-input v-model="form.otherRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.otherReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.otherIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.otherRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td colspan="3">
            <p>是否引用此标准开展检测:</p>
          </td>
          <td colspan="3">可以引用此标准开展检测</td>
          <td>
            <p>确认时间:</p>
          </td>
          <td>{{form.confirmDate}}</td>
        </tr>
        <tr>
          <td colspan="3">
            <p>参加确认人签名:</p>
          </td>
          <td colspan="5">
            <el-select v-model="form.confirmUser" multiple placeholder="请选择" size="small" style="width: 100%" :multiple-limit="5">
              <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </td>
        </tr>
      </table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button :loading="editLoad" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
    <ViewDeviceDialog v-if="viewDeviceDialog" ref="viewDeviceDialog" @closDeviceDia="closDeviceDia" @handleDeviceInfo="handleDeviceInfo"></ViewDeviceDialog>
    <ViewTestRecord v-if="viewTestRecordDialog" ref="viewTestRecordDialog"></ViewTestRecord>
    <ViewWorkPermitDia v-if="viewWorkPermitDia" ref="viewWorkPermitDia"></ViewWorkPermitDia>
    <calibrations-file-dia v-if="calibrationsFileDia" ref="calibrationsFileDia"></calibrations-file-dia>
  </div>
</template>
<script>
import { dateFormat } from '@/utils/date'
import ViewTestRecord from '../component/ViewTestRecord.vue';
import ViewDeviceDialog from '../component/ViewDeviceDialog.vue';
import ViewWorkPermitDia from '../component/viewWorkPermitDia.vue';
import CalibrationsFileDia from '../component/calibrationsFileDia.vue';
import {
  addMethodVerify, deviceScopeSearch,
  getMethodVerifyOne,
  selectUserCondition,
  updateMethodVerify
} from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'formDIaChange',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { CalibrationsFileDia, ViewWorkPermitDia, ViewDeviceDialog, ViewTestRecord },
  props: {
    operationType: {
      type: String,
      default: () => ''
    }
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      form: {
        methodName: '',
        verifyReason: '',
        technologyChange: '',
        personRequirements: '',
        personReadiness: '',
        personIsSatisfied: '',
        personRemark: '',
        machineRequirements: '',
        machineReadiness: '',
        machineIsSatisfied: '',
        materialRequirements: '',
        materialReadiness: '',
        materialIsSatisfied: '',
        materialRemark: '',
        methodRequirements: '',
        methodReadiness: '',
        methodIsSatisfied: '',
        environmentRequirements: '',
        environmentReadiness: '',
        environmentIsSatisfied: '',
        traceabilityRequirements: '',
        traceabilityReadiness: '',
        traceabilityIsSatisfied: '',
        traceabilityRemark: '',
        managementRequirements: '',
        managementReadiness: '',
        managementIsSatisfied: '',
        managementRemark: '',
        otherRequirements: '',
        otherReadiness: '',
        otherIsSatisfied: '',
        otherRemark: '',
        machineAttachmentList: []
      },
      editLoad: false,
      info: {
        methodVerifyId: ''
      },
      userList: [],
      viewDeviceDialog: false,
      viewTestRecordDialog: false,
      viewWorkPermitDia: false,
      calibrationsFileDia: false,
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.formDia = true
      this.info = row
      this.getUserList()
      if (this.operationType === 'edit') {
        this.searchInfo(row)
      }
    },
    // æŸ¥è¯¢è¯¦æƒ…信息
    searchInfo (row) {
      getMethodVerifyOne({methodVerifyId:row.methodVerifyId}).then(res => {
        if (res.code === 200) {
          this.form = {...res.data}
          if (this.form.confirmUser) {
            this.form.confirmUser = this.form.confirmUser.split(',').map(Number)
          }
        }
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // æäº¤
    handleEdit() {
      this.editLoad = true
      const processMethodSearchNews = this.HaveJson(this.form)
      processMethodSearchNews.confirmUser = processMethodSearchNews.confirmUser && processMethodSearchNews.confirmUser.join(',')
      processMethodSearchNews.operationType = 0
      if (this.operationType === 'edit') {
        this.editInfo(processMethodSearchNews)
      } else {
        this.addInfo(processMethodSearchNews)
      }
    },
    // æŸ¥çœ‹ä¸Šå²—证
    viewWorkPermit () {
      this.viewWorkPermitDia = true
      this.$nextTick(() => {
        this.$refs.viewWorkPermitDia.openDia(this.form)
      })
    },
    // æŸ¥çœ‹æ ¡å‡†è¯ä¹¦
    viewCalibrationsFileDia () {
      this.calibrationsFileDia = true
      this.$nextTick(() => {
        this.$refs.calibrationsFileDia.openDia(this.form)
      })
    },
    // æŸ¥çœ‹è®¾å¤‡
    viewDevice () {
      this.viewDeviceDialog = true
      this.$nextTick(() => {
        this.$refs.viewDeviceDialog.openDia(this.form)
      })
    },
    // å…³é—­è®¾å¤‡å¼¹æ¡†
    closDeviceDia () {
      this.viewDeviceDialog = false
    },
    // æäº¤è®¾å¤‡ä¿¡æ¯
    handleDeviceInfo (machineAttachmentList) {
      this.viewDeviceDialog = false
      this.form.machineAttachmentList = machineAttachmentList
    },
    // æŸ¥çœ‹æ£€æµ‹è®°å½•
    viewTestRecord () {
      this.viewTestRecordDialog = true
      this.$nextTick(() => {
        this.$refs.viewTestRecordDialog.openDia(this.info)
      })
    },
    // æäº¤ç¼–辑
    editInfo (processMethodSearchNews) {
      updateMethodVerify(processMethodSearchNews).then(res => {
        this.editLoad = false
        if (res.code === 200){
          this.$message.success('操作成功')
          this.closeDia()
        }
      }).catch(err => {
        console.log('err---', err);
        this.editLoad = false
      })
    },
    // æäº¤æ–°å¢ž
    addInfo (processMethodSearchNews) {
      addMethodVerify(processMethodSearchNews).then(res => {
        this.editLoad = false
        if (res.code === 200) {
          this.$message.success('操作成功')
          this.closeDia()
        }
      }).catch(err => {
        console.log('err---', err);
        this.editLoad = false
      })
    },
    // éªŒè¯ç¡®è®¤
    validation () {
      deviceScopeSearch({methodVerifyId:this.info.methodVerifyId}).then(res => {
        if (res.code === 200){
          this.form.confirmDate = dateFormat(new Date())
        }
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // å…³é—­å¼¹æ¡†
    closeDia() {
      this.formDia = false
      this.$emit('closeDia');
    },
    getUserList(){
      selectUserCondition().then(res => {
        if (res.code === 200) {
          this.userList = res.data
        }
      })
    },
  }
};
</script>
<style scoped>
>>>.el-dialog {
  margin-top: 2vh !important;
}
>>>.el-dialog__body {
  max-height: 720px;
  overflow-y: auto;
}
.tables {
  table-layout: fixed;
  width: 100%;
  margin-top: 10px;
}
.tables td {
  height: 34px;
  width: 100px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
  padding: 4px;
}
</style>
src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="查看上岗证" width="80%" @closed="closeFilesLook">
      <div>
        <limsTable
          ref="yearTable"
          :column="columnData"
          :height="'calc(100vh - 400px)'"
          :highlightCurrentRow="true"
          :table-data="tableData"
          :table-loading="tableLoading"
          style="margin-top: 0.5em;">
        </limsTable>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="lookDialogVisible"
      fullscreen
      title="查看附件" top="5vh" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}"
                   :fileUrl="javaApi+'/img/'+currentInfo.fileUrl" style="max-height: 90vh;overflow-y: auto;"/>
    </el-dialog>
  </div>
</template>
<script>
import file from '@/utils/file';
import filePreview from '@/views/tool/file-preview.vue';
import limsTable from '@/components/Table/lims-table.vue'
export default {
  name: 'viewWorkPermitDia',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { filePreview, limsTable },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          label: '持有人',
          prop: 'userName',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '预览',
              type: 'text',
              clickFun: (row) => {
                this.handleLook(row)
              }
            },
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
          ]
        }
      ],
      tableData: [],
      info: {},
      currentInfo:{},
      lookDialogVisible: false,
    };
  },
  mounted() {
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      this.tableData = this.info.workFileList
    },
    closeFilesLook () {
      this.filesDialogVisible = false
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row){
      this.currentInfo = row
      this.lookDialogVisible = true
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,201 @@
<template>
  <div class="capacity-scope">
    <div class="search">
      <div>
        <el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
          <el-form-item label="标准方法" prop="methodName">
            <el-input size="small" placeholder="请输入" clearable v-model="searchForm.methodName"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="searchList">查 è¯¢</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetSearchForm">重 ç½®</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div>
        <el-button size="medium" type="primary" @click="openFormDia('add')">新 å¢ž</el-button>
      </div>
    </div>
    <div class="table">
      <div>
        <TableCard :showForm="false" :showTitle="false">
          <template v-slot:table>
            <lims-table :tableData="tableData" :column="tableColumn" :height="'calc(100vh - 250px)'" @pagination="pagination"
                        :page="page" :tableLoading="tableLoading"></lims-table>
          </template>
        </TableCard>
      </div>
    </div>
    <formDIaChange v-if="formDIa" ref="formDIa" :operationType="operationType" @closeDia="closeDia"></formDIaChange>
  </div>
</template>
<script>
import TableCard from '@/views/CNAS/externalService/serviceAndSupplyPro/component/index.vue';
import formDIaChange from './component/formDIaChange.vue';
import limsTable from '@/components/Table/lims-table.vue'
import {
  delMethodVerify,
  exportMethodVerify,
  pagesMethodVerify
} from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'a7-changes-standard-methods',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { limsTable, formDIaChange, TableCard },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      searchForm: {
        methodName: '',
        operationType: 0,
      },
      options: [
        { label: '上半年', value: '1' },
        { label: '下半年', value: '2' },
      ],
      tableColumn: [
        {
          label: '标准方法',
          prop: 'methodName',
          minWidth: '100'
        },
        {
          label: '验证原因',
          prop: 'verifyReason',
          minWidth: '100'
        },
        {
          label: '主要技术变化',
          prop: 'technologyChange',
          minWidth: '100'
        },
        {
          dataType: 'action',
          minWidth: '60',
          label: '操作',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.openFormDia('edit', row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteRow(row);
              },
            }
          ]
        }
      ],
      tableData: [],
      tableLoading: false,
      page: {
        size: 10,
        current: 1,
        total: 0,
      },
      formDIa: false,
      operationType: '',
    };
  },
  mounted() {
    this.searchList()
  },
  // æ–¹æ³•集合
  methods: {
    // æŸ¥è¯¢åˆ—表
    searchList() {
      const entity = {
        methodName: this.searchForm.methodName,
        operationType: this.searchForm.operationType,
      }
      this.tableLoading = true
      pagesMethodVerify({... this.page,...entity}).then(res => {
        this.tableLoading = false
        if (res.code === 200){
          this.tableData = res.data.records
          this.page.total = res.data.total
        }
      }).catch(err => {
        console.log('err---', err);
        this.tableLoading = false
      })
    },
    // åˆ é™¤
    deleteRow (row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        delMethodVerify({methodVerifyId:row.methodVerifyId}).then(res => {
          this.tableLoading = false
          if (res.code === 200){
            this.$message.success('删除成功')
            this.searchList()
          }
        }).catch(err => {
          this.tableLoading = false
          console.log('err---', err);
        })
      })
    },
    // é‡ç½®æŸ¥è¯¢æ¡ä»¶
    resetSearchForm() {
      this.searchForm.methodName = '';
      this.searchList()
    },
    openFormDia (type, row) {
      this.formDIa = true
      this.operationType = type
      this.$nextTick(() => {
        this.$refs.formDIa.openDia(row)
      })
    },
    // å…³é—­å¼¹æ¡†
    closeDia () {
      this.formDIa = false
      this.searchList()
    },
    // å¯¼å‡º
    downLoadPost(row) {
      this.outLoading = true
      exportMethodVerify({methodVerifyId:row.methodVerifyId}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '标准(方法)确认记录.docx')
        this.$message.success('导出成功')
      })
    },
    // åˆ†é¡µåˆ‡æ¢
    pagination(page) {
      this.page.size = page.limit
      this.searchList();
    },
  }
};
</script>
<style scoped>
.search {
  height: 46px;
  display: flex;
  justify-content: space-between;
}
</style>
src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,148 @@
<template>
  <div>
    <el-dialog :visible.sync="formDia" title="编辑" width="80%" @close="closeDia">
      <el-form ref="form" :model="form" :rules="formRules" label-width="auto">
        <el-col :span="8">
          <el-form-item label="标准名称:" prop="methodName">
            <el-input v-model="form.methodName" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="标准号:" prop="standardNo">
            <el-input v-model="form.standardNo" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="文件编号:" prop="fileNo">
            <el-input v-model="form.fileNo" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="是否是新标准:" prop="isNewStandard">
            <el-radio-group v-model="form.isNewStandard">
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="查新记录来源:" prop="searchNewSource">
            <el-radio-group v-model="form.searchNewSource">
              <el-radio :label="0">标准网</el-radio>
              <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 label="备注:" prop="remark">
            <el-select v-model="form.remark"
                       clearable size="small">
              <el-option :value="0" label="作废"></el-option>
              <el-option :value="1" label="替换"></el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col v-if="form.isNewStandard == 1" :span="8">
          <el-form-item label="新标准名称:" prop="newMethodName">
            <el-input v-model="form.newMethodName" size="small"></el-input>
          </el-form-item>
        </el-col>
        <el-col v-if="form.isNewStandard == 1" :span="8">
          <el-form-item label="新标准号:" prop="newStandardNo">
            <el-input v-model="form.newStandardNo" size="small"></el-input>
          </el-form-item>
        </el-col>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button :loading="editLoad" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  updateMethodSearchNew
} from '@/api/cnas/process/method/standardNoveltyRetrieval'
export default {
  name: 'FormDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      form: {
        methodName: '',
        standardNo: '',
        isNewStandard: '',
        newMethodName: '',
        newStandardNo: '',
        searchNewSource: '',
        remark: '',
        fileNo: '',
      },
      formRules: {
        methodName: [{required: true, message: '请填写标准名称',trigger: 'blur'}],
        standardNo: [{required: true, message: '请填写标准号',trigger: 'blur'}],
        isNewStandard: [{required: true, message: '请选择是否是新标准',trigger: 'change'}],
        newMethodName: [{required: false, message: '请填写新标准名称',trigger: 'blur'}],
        newStandardNo: [{required: false, message: '请填写新标准号',trigger: 'blur'}],
        searchNewSource: [{required: true, message: '请选择查新记录来源',trigger: 'change'}],
        fileNo: [{required: true, message: '请填写文件号',trigger: 'blur'}],
      },
      editLoad: false,
      info: {},
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.formDia = true
      this.form = {...row}
    },
    handleEdit() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          this.editLoad = true
          const processMethodSearchNews = this.HaveJson(this.form)
          delete processMethodSearchNews.createTime
          updateMethodSearchNew(processMethodSearchNews).then(res => {
            this.editLoad = false
            if (res.code === 200){
              this.$message.success('操作成功')
              this.closeDia()
            }
          }).catch(err => {
            console.log('err---', err);
            this.editLoad = false
          })
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    closeDia() {
      this.$refs.form.resetFields();
      this.formDia = false
      this.$emit('closeEditDia');
    },
  }
};
</script>
<style scoped>
.form-info {
  display: inline-block;
  max-height: 600px;
  overflow-y: auto;
}
>>>.el-dialog {
  margin: 6vh auto 50px !important;
}
</style>
src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,131 @@
<template>
  <div>
    <el-dialog :visible.sync="formDia" title="新增" width="80%" @close="closeDia">
      <el-form ref="form" :model="form" :rules="formRules" label-width="auto">
        <el-button size="small" type="primary" @click="addBtn">添加一条</el-button>
        <div class="form-info">
          <div v-for="(items,index) in form.taskRel" :key="index">
            <el-col :span="12">
              <el-form-item :prop="`taskRel.${index}.newMethodName`" :rules="{required: true, message: '请填写标准名称',trigger: 'blur',}" label="新标准名称:">
                <el-input v-model="items.newMethodName" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :prop="`taskRel.${index}.newStandardNo`" :rules="{required: true,message: '请填写标准号',trigger: 'blur',}" label="新标准号:">
                <el-input v-model="items.newStandardNo" size="small"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item :prop="`taskRel.${index}.searchNewSource`" :rules="{required: true,message: '请选择查新记录来源',trigger: 'change',}" label="查新记录来源:">
                <el-radio-group v-model="items.searchNewSource">
                  <el-radio :label="0">标准网</el-radio>
                  <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="`taskRel.${index}.remark`" :rules="{required: false,message: '请选择备注',trigger: 'change',}" label="备注:">
                <el-select v-model="items.remark" :prop="`taskRel.${index}.remark`"
                           :rules="{required: false,message: '请选择备注',trigger: 'change',}"
                           clearable size="small">
                  <el-option :value="0" label="作废"></el-option>
                  <el-option :value="1" label="替换"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-button v-if="index !== 0" circle icon="el-icon-delete" size="small" type="danger" @click="deleteHeaderRow(index)"></el-button>
            </el-col>
            <el-col :span="24">
              <el-divider></el-divider>
            </el-col>
          </div>
        </div>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button :loading="editLoad" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { addMethodSearchNew } from '@/api/cnas/process/method/standardNoveltyRetrieval'
export default {
  name: 'FormDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      form: {
        taskRel: [
          {
            newMethodName: '',
            newStandardNo: '',
            searchNewSource: '',
            remark: '',
          }
        ]
      },
      formRules: {},
      editLoad: false,
      info: {},
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia (row) {
      this.formDia = true
    },
    // æ·»åŠ ä¸€æ¡
    addBtn() {
      this.form.taskRel.push({ newMethodName: '', newStandardNo:'', searchNewSource: '', remark: ''});
    },
    // åˆ é™¤ä¸€æ¡
    deleteHeaderRow (index) {
      this.form.taskRel.splice(index, 1);
    },
    handleEdit () {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          this.editLoad = true
          addMethodSearchNew(this.form.taskRel).then(res => {
            this.editLoad = false
            if (res.code === 201) return
            this.$message.success('操作成功')
            this.closeDia()
          }).catch(err => {
            console.log('err---', err);
            this.editLoad = false
          })
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    closeDia () {
      this.$refs.form.resetFields();
      this.formDia = false
      this.$emit('closeDia');
    },
  }
};
</script>
<style scoped>
.form-info {
  display: inline-block;
  max-height: 42em;
  overflow-y: auto;
}
>>>.el-dialog {
  margin: 6vh auto 50px !important;
}
</style>
src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,729 @@
<template>
  <div class="capacity-scope">
    <div class="search">
      <div>
        <el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
          <el-form-item label="标准号" prop="standardNo">
            <el-input size="small" placeholder="请输入" clearable v-model="searchForm.standardNo"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="searchList">查 è¯¢</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetSearchForm">重 ç½®</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div>
        <el-button size="medium" type="primary" @click="openApprovalDialog1">建 æ¡£</el-button>
        <el-upload ref='upload' :action="action"
                             :before-upload="beforeUpload" :headers="headers" :on-error="onError"
                             :on-success="handleSuccessUp" :show-file-list="false" accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'
                             style="display: inline-block; margin-left: 10px;">
                    <el-button :loading="upLoading" size="medium" type="primary">导入</el-button>
        </el-upload>
        <el-button size="medium" style="margin-left: 10px;" type="primary" @click="openFormDia">新 å¢ž</el-button>
      </div>
    </div>
    <div>
      <div class="table">
        <div class="table-tab">
          <el-radio-group v-model="tabIndex" @input="searchList">
            <el-radio-button label="0">今年标准记录</el-radio-button>
            <el-radio-button label="1">历史档案</el-radio-button>
          </el-radio-group>
        </div>
        <div v-if="tabIndex === '0'">
          <TableCard :showForm="false" :showTitle="false">
            <template v-slot:table>
              <lims-table
                :column="tableColumn"
                :height="'calc(100vh - 26em)'"
                :table-data="tableData"
                :table-loading="tableLoading"
                :page="page"
                @pagination="pagination">
              </lims-table>
            </template>
          </TableCard>
        </div>
        <div v-if="tabIndex === '1'">
          <TableCard :showForm="false" :showTitle="false">
            <template v-slot:table>
              <lims-table
                :column="oldTableColumn"
                :height="'calc(100vh - 20em)'"
                :table-data="oldTableData"
                :table-loading="oldTableLoading"
                :page="oldPage"
                @pagination="oldPagination">
              </lims-table>
            </template>
          </TableCard>
        </div>
      </div>
      <!--      åŽ†å²æ¡£æ¡ˆæ‰¹å‡†å¼¹æ¡†-->
      <el-dialog :visible.sync="approvalDialog" title="批准" width="30%" @close="approvalDialog = false">
        <span>
          æ‰¹å‡†å¤‡æ³¨ï¼š
          <el-input v-model="qualityRemark" type="textarea"></el-input>
        </span>
        <span slot="footer" class="dialog-footer">
          <el-button :loading="approvalLoading" @click="handleApproval(0)">不批准</el-button>
          <el-button :loading="approvalLoading" type="primary" @click="handleApproval(1)">批 å‡†</el-button>
        </span>
      </el-dialog>
      <el-dialog :visible.sync="approvalDialog1" title="建档" width="30%" @close="approvalDialog1 = false">
        <span>
          æ¡£æ¡ˆåç§°ï¼š
          <el-input v-model="archivedName" type="textarea"></el-input>
        </span>
        <span slot="footer" class="dialog-footer">
          <el-button :loading="approvalLoading" @click="approvalDialog1 = false, archivedName = ''">取 æ¶ˆ</el-button>
          <el-button :loading="approvalLoading" type="primary" @click="handleApproval1()">ç¡® å®š</el-button>
        </span>
      </el-dialog>
      <FormDialog v-if="formDialog" ref="formDialog" @closeDia="closeDia"></FormDialog>
      <EditFormDia v-if="editFormDialog" ref="editFormDialog" @closeEditDia="closeEditDia"></EditFormDia>
      <el-dialog :visible.sync="viewRocordDia" title="详情" width="80%" @close="approvalDialog = false">
        <TableCard :showForm="false" :showTitle="false">
          <template v-slot:table>
            <limsTable
              :column="tableColumn1"
              :height="'calc(100vh - 26em)'"
              :table-data="tableData1"
              :table-loading="tableLoading1"
              style="padding: 0 15px;margin-bottom: 16px"
              :page="page1"
              @pagination="pagination1">
            </limsTable>
          </template>
        </TableCard>
      </el-dialog>
    </div>
  </div>
</template>
<script>
import limsTable from '@/components/Table/lims-table.vue'
import TableCard from '@/views/CNAS/externalService/serviceAndSupplyPro/component/index.vue';
import FormDialog from './component/FormDialog.vue';
import EditFormDia from './component/EditFormDia.vue';
import {
  addSearchNewArchived, exportMethodSearchNew,
  pageMethodSearchNew, pageSearchNewArchived, pageSearchNewBackups, ratifySearchNewArchivedr
} from '@/api/cnas/process/method/standardNoveltyRetrieval'
export default {
  name: 'a7-standard-novelty-retrieval',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {
    FormDialog,
    TableCard,
    limsTable,
    EditFormDia
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      searchForm: {
        year: '',
        standardNo: '',
      },
      options: [
        {label: '上半年', value: '1'},
        {label: '下半年', value: '2'},
      ],
      tableColumn: [
        {
          label: '标准名称',
          prop: 'methodName',
          minWidth: '100'
        },
        {
          label: '标准号',
          prop: 'standardNo',
          minWidth: '100'
        },
        {
          label: '文件编号',
          prop: 'fileNo',
          minWidth: '100'
        },
        {
          dataType: 'tag',
          label: '是否是新标准',
          prop: 'isNewStandard',
          minWidth: '100',
          formatData: (params) => {
            if (params == 0) {
              return '否';
            } else if (params == 1) {
              return '是';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'danger';
            } else if (params == 1) {
              return 'success';
            } else {
              return null
            }
          }
        },
        {
          label: '新标准名称',
          prop: 'newMethodName',
          minWidth: '100'
        },
        {
          label: '新标准号',
          prop: 'newStandardNo',
          minWidth: '100'
        },
        {
          dataType: 'tag',
          label: '查询记录来源',
          prop: 'searchNewSource',
          minWidth: '100',
          formatData: (params) => {
            if (params == 0) {
              return '标准网';
            } else if (params == 1) {
              return '委托情报';
            } else if (params == 2) {
              return '标准数';
            } else if (params == 3) {
              return '其他';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'success';
            } else if (params == 1) {
              return 'danger';
            } else if (params == 2) {
              return 'warning';
            } else if (params == 3) {
              return 'info';
            } else {
              return null
            }
          }
        },
        {
          dataType: 'tag',
          label: '备注',
          prop: 'remark',
          minWidth: '100',
          formatData: (params) => {
            if (params == 0) {
              return '作废';
            } else if (params == 1) {
              return '替换';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'danger';
            } else if (params == 1) {
              return 'success';
            } else {
              return null
            }
          }
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.openEditFormDia(row);
              },
            },
          ]
        }
      ],
      tableColumn1: [
        {
          label: '标准名称',
          prop: 'methodName',
          minWidth: '100'
        },
        {
          label: '标准号',
          prop: 'standardNo',
          minWidth: '100'
        },
        {
          label: '文件编号',
          prop: 'fileNo',
          minWidth: '100'
        },
        {
          dataType: 'tag',
          label: '是否是新标准',
          prop: 'isNewStandard',
          minWidth: '100',
          formatData: (params) => {
            if (params == 0) {
              return '否';
            } else if (params == 1) {
              return '是';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'danger';
            } else if (params == 1) {
              return 'success';
            } else {
              return null
            }
          }
        },
        {
          label: '新标准名称',
          prop: 'newMethodName',
          minWidth: '100'
        },
        {
          label: '新标准号',
          prop: 'newStandardNo',
          minWidth: '100'
        },
        {
          dataType: 'tag',
          label: '查询记录来源',
          prop: 'searchNewSource',
          minWidth: '100',
          formatData: (params) => {
            if (params == 0) {
              return '标准网';
            } else if (params == 1) {
              return '委托情报';
            } else if (params == 2) {
              return '标准数';
            } else if (params == 3) {
              return '其他';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'success';
            } else if (params == 1) {
              return 'danger';
            } else if (params == 2) {
              return 'warning';
            } else if (params == 3) {
              return 'info';
            } else {
              return null
            }
          }
        },
        {
          dataType: 'tag',
          label: '备注',
          prop: 'remark',
          minWidth: '100',
          formatData: (params) => {
            if (params == 0) {
              return '作废';
            } else if (params == 1) {
              return '替换';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'danger';
            } else if (params == 1) {
              return 'success';
            } else {
              return null
            }
          }
        }
      ],
      tableData: [],
      tableData1: [],
      tableLoading: false,
      tableLoading1: false,
      page: {
        size: 10,
        current: 1,
        total: 0
      },
      page1: {
        size: 10,
        current: 1,
        total: 0
      },
      oldPage: {
        size: 10,
        current: 1,
        total: 0,
      },
      oldTableColumn: [
        {
          label: '存档名称',
          prop: 'archivedName',
          minWidth: '100'
        },
        {
          label: '编制人',
          prop: 'writeName',
          minWidth: '100'
        },
        {
          label: '编制时间',
          prop: 'writeTime',
          minWidth: '100'
        },
        {
          label: '批准人',
          prop: 'ratifyName',
          minWidth: '100'
        },
        {
          label: '批准信息',
          prop: 'ratifyRemark',
          minWidth: '100'
        },
        {
          dataType: 'tag',
          label: '批准状态',
          prop: 'ratifyStatus',
          minWidth: '100',
          formatData: (params) => {
            if (params == 0) {
              return '不通过';
            } else if (params == 1) {
              return '通过';
            } else {
              return null
            }
          },
          formatType: (params) => {
            if (params == 0) {
              return 'danger';
            } else if (params == 1) {
              return 'success';
            } else {
              return null
            }
          }
        },
        {
          label: '批准时间',
          prop: 'ratifyTime',
          minWidth: '100'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          operation: [
            {
              name: '批准',
              type: 'text',
              clickFun: (row) => {
                this.openApprovalDialog(row);
              },
              disabled: (row) => {
                if (row.ratifyStatus === 1) {
                  return true
                } else {
                  return false
                }
              },
            },
            {
              name: '查看',
              type: 'text',
              clickFun: (row) => {
                this.openViewDia(row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.handleOut(row);
              },
            }
          ]
        }
      ],
      oldTableData: [],
      oldTableLoading: false,
      tabIndex: '0',
      formDialog: false,
      editFormDialog: false,
      upLoading:false,
      outLoading:false,
      ratifyInfo: {
        writeUserId: '',
        ratifyUserId: '',
        writeDate: '',
        ratifyDate: '',
      },
      userList: [],
      approvalDialog: false,
      approvalDialog1: false,
      viewRocordDia: false,
      approvalLoading: false,
      qualityRemark: '',
      archivedName: '',
      archivedId: '',
    };
  },
  mounted() {
    this.searchList()
  },
  // æ–¹æ³•集合
  methods: {
    // æŸ¥è¯¢åˆ—表
    searchList () {
      let params = {}
      if (this.tabIndex === '0') {
        params = {
          entity: {
            standardNo: this.searchForm.standardNo,
          },
          page: this.page
        }
      } else {
        params = {
          entity: {},
          page: this.oldPage
        }
      }
      if (this.tabIndex === '0') {
        this.tableLoading = true
        pageMethodSearchNew({...params.oldPage,...params.entity}).then(res => {
          this.tableLoading = false
          if (res.code === 200){
            this.tableData = res.data.records
            this.page.total = res.data.total
          }
        }).catch(err => {
          console.log('err---', err);
          this.tableLoading = false
        })
      } else {
        this.oldTableLoading = true
        pageSearchNewArchived({
          ...params.page,...params.entity
        }).then(res => {
          this.oldTableLoading = false
          if (res.code === 200){
            console.log('res>>>>>>>>>>>>',res)
            this.oldTableData = res.data.records
            this.oldPage.total = res.data.total
          }
        }).catch(err => {
          console.log('err---', err);
          this.oldTableLoading = false
        })
      }
    },
    // æ‰“开历史档案详情弹框
    openViewDia (row) {
      this.archivedId = row.archivedId
      this.viewRocordDia = true
      this.pageSearchNewBackups()
    },
    pageSearchNewBackups () {
      const entity = {
        archivedId: this.archivedId,
      }
      this.tableLoading1 = true
      pageSearchNewBackups({...this.page1,...entity}).then(res => {
        this.tableLoading1 = false
        if (res.code === 200){
          this.tableData1 = res.data.records
          this.page1.total = res.data.total
        }
      }).catch(err => {
        console.log('err---', err);
        this.tableLoading1 = false
      })
    },
    // æ‰“开批准弹框
    openApprovalDialog (row) {
      this.approvalDialog = true
      this.archivedId = row.archivedId
    },
    // æ‰“开批准弹框
    openApprovalDialog1 (row) {
      this.approvalDialog1 = true
      this.archivedId = row.archivedId
    },
    // æäº¤æ‰¹å‡†
    handleApproval (status) {
      this.approvalLoading = true
      let internalReport = {
        archivedId: this.archivedId,
        ratifyStatus: status,
        ratifyRemark: this.ratifyRemark
      }
      ratifySearchNewArchivedr(internalReport).then(res => {
        if (res.code === 200) {
          this.$message.success('提交成功!');
          this.approvalDialog = false
          this.searchList()
        }
        this.approvalLoading = false
      }).catch(() => {
        this.approvalLoading = false
      })
    },
    // æäº¤æ‰¹å‡†
    handleApproval1 (status) {
      this.approvalLoading = true
      let internalReport = {
        archivedName: this.archivedName,
      }
      addSearchNewArchived(internalReport).then(res => {
        if (res.code === 200) {
          this.$message.success('提交成功!');
          this.approvalDialog1 = false
          this.searchList()
        }
        this.approvalLoading = false
      }).catch(() => {
        this.approvalLoading = false
      })
    },
    // é‡ç½®æŸ¥è¯¢æ¡ä»¶
    resetSearchForm () {
      this.searchForm.standardNo = '';
      this.searchList()
    },
    // æ“ä½œæ–°å¢žæ¡†
    openFormDia (row) {
      this.formDialog = true
      this.$nextTick(() => {
        this.$refs.formDialog.openDia(row)
      })
    },
    // å…³é—­æ–°å¢žå¼¹æ¡†
    closeDia () {
      this.formDialog = false
      this.searchList()
    },
    // æ‰“开修改弹框
    openEditFormDia (row) {
      this.editFormDialog = true
      this.$nextTick(() => {
        this.$refs.editFormDialog.openDia(row)
      })
    },
    //
    closeEditDia () {
      this.editFormDialog = false
      this.searchList()
    },
    // å¯¼å‡º
    handleOut (row) {
      this.outLoading = true
      exportMethodSearchNew({archivedId:row.archivedId}).then(res => {
        const blob = new Blob([res],{ type: 'application/octet-stream' });
        this.$download.saveAs(blob, '标准查新导出.xlsx')
        this.$message.success('导出成功')
      })
    },
    // å¯¼å…¥
    beforeUpload(file) {
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        return false;
      } else {
        this.upLoading = true;
        return true;
      }
    },
    onError(err, file, fileList) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchList()
      }
    },
    // åˆ†é¡µ
    pagination(page){
      this.page.size = page.limit
      this.searchList();
    },
    pagination1(page){
      this.page1.size = page.limit
      this.pageSearchNewBackups();
    },
    oldPagination(page){
      this.oldPage.size = page.limit
      this.searchList();
    },
    //
    getUserList(){
      this.$axios.post(this.$api.user.selectUserList, {
        page: {current: -1, size: -1,},
        entity: {name: null}
      }, {
        headers: {
          'Content-Type': 'application/json'
        }
      }).then(res => {
        if (res.code === 201) {
          return
        }
        this.userList = res.data.body.records
      })
    },
  },
  // ç”¨äºŽä¸Šä¼ æ–‡ä»¶çš„信息
  computed: {
    headers() {
      return {
        'token': sessionStorage.getItem('token')
      }
    },
    action() {
      return this.javaApi + '/processMethodSearchNew/importMethodSearchNew'
    }
  },
};
</script>
<style scoped>
.search {
  height: 46px;
  display: flex;
  justify-content: space-between;
}
.table-tab {
  margin-bottom: 10px;
}
</style>
src/views/business/inspectionTask/index.vue
@@ -572,10 +572,11 @@
    this.getDicts("inspection_task_state").then((response) => {
      this.inspectionTaskState = this.dictToValue(response.data);
    });
    this.refreshTable();
  },
  mounted() {
    this.queryParams.userId = this.userId;
    this.refreshTable();
  },
  methods: {
    getList() {
src/views/business/inspectionTask/inspection.vue
@@ -2899,7 +2899,7 @@
      }
    },
    goback() {
      this.$tab.closeOpenPage({ path: "/business/inspectionTask" });
      this.$router.go(-1)
    }
  },
};
src/views/business/materialOrder/index.vue
@@ -72,30 +72,38 @@
        </div>
        <!--待下单-->
        <div class="table">
          <lims-table :tableData="tableData" :column="column" v-if="tabIndex === 0" @pagination="pagination"
            :height="'calc(100vh - 290px)'" key="tableData" :page="page" :tableLoading="tableLoading"></lims-table>
          <lims-table :tableData="tableData" :column="column"
                      v-if="tabIndex === 0" @pagination="pagination"
                      :rowClassName="changeRowClass"
                      :height="'calc(100vh - 290px)'" key="tableData"
                      :page="page" :tableLoading="tableLoading"></lims-table>
        </div>
        <!--检验中-->
        <div class="table">
          <lims-table :tableData="tableData1" :column="column1" v-if="tabIndex === 1" :isSelection="true"
            :handleSelectionChange="selectMethod" @pagination="pagination1" :height="'calc(100vh - 290px)'"
            key="tableData1" :page="page1" :tableLoading="tableLoading1"></lims-table>
          <lims-table :tableData="tableData1" :column="column1"
                      v-if="tabIndex === 1" :isSelection="true"
                      :rowClassName="changeRowClass"
                      :handleSelectionChange="selectMethod" @pagination="pagination1" :height="'calc(100vh - 290px)'"
                      key="tableData1" :page="page1" :tableLoading="tableLoading1"></lims-table>
        </div>
        <!--已检验-->
        <div class="table">
          <lims-table :tableData="tableData2" :column="column2" v-if="tabIndex === 2" :isSelection="true"
                      :rowClassName="changeRowClass"
            :handleSelectionChange="selectMethod" @pagination="pagination2" :height="'calc(100vh - 290px)'"
            key="tableData2" :page="page2" :tableLoading="tableLoading2"></lims-table>
        </div>
        <!--全部-->
        <div class="table">
          <lims-table :tableData="tableData3" :column="column3" v-if="tabIndex === 3" :isSelection="true"
                      :rowClassName="changeRowClass"
            :handleSelectionChange="selectMethod" @pagination="pagination3" :height="'calc(100vh - 290px)'"
            key="tableData3" :page="page3" :tableLoading="tableLoading3"></lims-table>
        </div>
        <!--季度检验-->
        <div class="table">
          <lims-table :tableData="tableData4" :column="column4" v-if="tabIndex === 4" :isSelection="true"
                      :rowClassName="changeRowClass"
            :handleSelectionChange="selectMethod" @pagination="pagination4" :height="'calc(100vh - 290px)'"
            key="tableData4" :page="page4" :tableLoading="tableLoading4"></lims-table>
        </div>
@@ -1108,6 +1116,12 @@
    selectMethod(val) {
      this.multipleSelection = val
    },
    changeRowClass({row, rowIndex}) {
      if (row.isFirst == 1) {
        return 'highlight-danger-row-border'
      }
      return ''
    },
  },
}
</script>
src/views/business/productOrder/components/add.vue
@@ -933,7 +933,7 @@
        this.getCompanyList()
      },
      getCompanyList () {
        selectCustomPageList().then(res => {
        selectCustomPageList({...this.page1}).then(res => {
          this.tableLoading1 = false
          if (res.code === 200) {
            this.tableData1 = res.data.records
src/views/business/rawMaterialInspection/index.vue
@@ -549,7 +549,7 @@
    // å¾…报检、待下单查询
    getWarehouseSubmitApi () {
      this.tableLoading = true
      const params = {...this.componentData, isInspect: this.tabIndex, state: this.tabIndex === 0 ? null : 0}
      const params = {...this.componentData, isInspect: this.tabIndex, state: this.tabIndex === 0 ? null : 0, ...this.page}
      getWarehouseSubmit(params).then(res => {
        this.tableLoading = false
        if (res.code === 200) {
@@ -563,7 +563,7 @@
    // å·²å®Œæˆéƒ¨æŸ¥è¯¢
    getIfsByFinishList () {
      this.tableLoading1 = true
      getIfsByFinish({...this.componentData}).then(res => {
      getIfsByFinish({...this.componentData, ...this.page1}).then(res => {
        this.tableLoading1 = false
        if (res.code === 200) {
          this.tableData1 = res.data.records
@@ -576,7 +576,7 @@
    // å…¨éƒ¨æŸ¥è¯¢
    getIfsByAllList () {
      this.tableLoading1 = true
      getIfsByAll({...this.componentData}).then(res => {
      getIfsByAll({...this.componentData, ...this.page1}).then(res => {
        this.tableLoading1 = false
        if (res.code === 200) {
          this.tableData1 = res.data.records
src/views/standard/model/index.vue
@@ -112,7 +112,7 @@
              type: "text",
              clickFun: (row) => {
                this.title = "编辑";
                this.copyForm = row;
                this.copyForm = this.HaveJson(row);
                this.isShowCopyTem = true;
              },
              showHide: (row) => {
src/views/tool/file-preview.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,238 @@
<template>
  <div>
    <div v-if="isImage">
      <img :src="imgUrl" alt="Image Preview" />
    </div>
    <div v-if="isPdf">
      <object :data="fileUrl" type="application/pdf" width="100%" height="750px">
        <p>您的浏览器不支持 PDF é¢„览。<a :href="fileUrl">下载 PDF æ–‡ä»¶</a></p>
      </object>
    </div>
    <div v-if="isDoc">
      <p v-if="!isDocShow">文档无法直接预览,请下载查看。</p>
      <a :href="fileUrl" v-if="!isDocShow">下载文件</a>
      <vue-office-docx v-else
                       :src="fileUrl"
                       style="height: 100vh;"
                       @rendered="renderedHandler"
                       @error="errorHandler"
      />
    </div>
    <div v-if="isXls">
      <p v-if="!isDocShow">文档无法直接预览,请下载查看。</p>
      <a :href="fileUrl" v-if="!isDocShow">下载文件</a>
      <vue-office-excel v-else
                        :src="fileUrl"
                        :options="options"
                        style="height: 100vh;"
                        @rendered="renderedHandler"
                        @error="errorHandler"
      />
    </div>
    <div v-if="isZipOrRar">
      <p>压缩文件无法直接预览,请下载查看。</p>
      <a :href="fileUrl">下载文件</a>
    </div>
    <div v-if="isCsv">
      <p v-if="csvList.length==0">CSV æ–‡ä»¶æ— æ³•直接预览,请下载查看。</p>
      <a :href="fileUrl" v-if="csvList.length==0">下载文件</a>
      <el-tabs type="border-card" v-if="csvList.length>0" tab-position="bottom">
        <el-tab-pane :label="item.sheetName" v-for="(item,index) in csvList" :key="index">
          <el-table :data="item.tableData" height="75vh">
            <el-table-column :label="m.label" :prop="m.prop" v-for="(m,i) in item.column" :key="i" min-width="120px" show-overflow-tooltip>
              <template slot-scope="scope" slot="header">
                <div>
                  <el-tooltip  :content="m.label" placement="top">
                    <div class="oneLine">
                      <span>{{m.label}}</span>
                    </div>
                  </el-tooltip>
                </div>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </div>
    <div v-if="!isSupported">
      <p>不支持的文件格式</p>
    </div>
  </div>
</template>
<script>
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'
import VueOfficeExcel from '@vue-office/excel'
//引入相关样式
import '@vue-office/excel/lib/index.css'
export default {
  components: {
    VueOfficeDocx,
    VueOfficeExcel,
  },
  props: {
    fileUrl: {
      type: String,
      required: true
    },
    currentFile: {
      type: Object,
      required: true
    },
  },
  data(){
    return {
      isDocShow:true,
      options:{
        xls: false,       //预览xlsx文件设为false;预览xls文件设为true
        minColLength: 0,  // excel最少渲染多少列,如果想实现xlsx文件内容有几列,就渲染几列,可以将此值设置为0.
        minRowLength: 0,  // excel最少渲染多少行,如果想实现根据xlsx实际函数渲染,可以将此值设置为0.
        widthOffset: 10,  //如果渲染出来的结果感觉单元格宽度不够,可以在默认渲染的列表宽度上再加 Npx宽
        heightOffset: 10, //在默认渲染的列表高度上再加 Npx高
        beforeTransformData: (workbookData) => {return workbookData}, //底层通过exceljs获取excel文件内容,通过该钩子函数,可以对获取的excel文件内容进行修改,比如某个单元格的数据显示不正确,可以在此自行修改每个单元格的value值。
        transformData: (workbookData) => {return workbookData}, //将获取到的excel数据进行处理之后且渲染到页面之前,可通过transformData对即将渲染的数据及样式进行修改,此时每个单元格的text值就是即将渲染到页面上的内容
      },
      csvList:[],//csv文件数据
      imgUrl:''
    }
  },
  computed: {
    isImage() {
      let state = /\.(jpg|jpeg|png|gif)$/i.test(this.fileUrl)
      this.imgUrl = this.fileUrl
      if(state){
        this.imgUrl = this.fileUrl.replaceAll('word', 'img')
      }
      return state;
    },
    isPdf() {
      return /\.pdf$/i.test(this.fileUrl);
    },
    isDoc() {
      return /\.(doc|docx)$/i.test(this.fileUrl);
    },
    isXls(){
      let state = /\.(xls|xlsx)$/i.test(this.fileUrl)
      if(state){
        if(/\.(xlsx)$/i.test(this.fileUrl)){
          this.options.xls = false
        }else{
          this.options.xls = true
        }
      }
      return state;
    },
    isZipOrRar() {
      return /\.(zip|rar)$/i.test(this.fileUrl);
    },
    isCsv() {
      let state = /\.csv$/i.test(this.fileUrl)
      if(state){
        this.loadCSVData();
        // this.main()
      }
      return state;
    },
    isSupported() {
      return this.isImage || this.isPdf || this.isDoc || this.isZipOrRar || this.isCsv||this.isXls;
    }
  },
  methods:{
    renderedHandler() {
      console.log("渲染完成")
      this.isDocShow = true
      this.resetStyle()
    },
    errorHandler() {
      console.log("渲染失败")
      this.isDocShow = false
    },
    async loadCSVData() {
      this.$axios.post(this.$api.insOrderPlan.preview, {
        id: this.currentFile.id,
      }).then( res => {
        let arr = res.data
        arr = arr.map(m=>{
          let obj = {
            sheetName:m.sheetName,
            tableData:[],
            column:[]
          }
          obj.tableData = this.formatCSVToTable(m.content.replaceAll('null',' '))
          // .replaceAll('MIN','=MIN').replaceAll('MAX','=MAX').replaceAll('AVERAGE','=AVERAGE')
          for (let item in obj.tableData[0]) {
            obj.column.push({
              label: item,
              prop: item,
            })
          }
          return obj
        })
        this.csvList = arr
      }).catch( err => {
        console.log(err)
      })
    },
    formatCSVToTable(str){
      const result = [];
      const jsonObj = str.split("\n");
      let arrHeader = [];
      for (const i in jsonObj) {
        if (typeof jsonObj[i] === 'string' && jsonObj[i].length > 0) {
          const row = `${jsonObj[i]}`;
          if (row.trim().length > 0) {
            const kv = jsonObj[i].split(',');
            if (i == 0) {
              // èŽ·å–column表头
              arrHeader = kv;
            } else {
              const obj = {};
              for (let index = 0; index < arrHeader.length; index++) {
                // ç»„装表格数据
                const name = String(arrHeader[index]);
                if (!arrHeader[index]) continue
                if (!obj[name]) {
                  try {
                    if (kv[index]) {
                      obj[name] = String(kv[index]);
                    } else {
                      obj[name] = '';
                    }
                  } catch (err) {
                    obj[name] = '';
                  }
                }
              }
              result.push(obj);
            }
          }
        }
      }
      return result
    },
    resetStyle(){
      const elements = document.querySelectorAll('[style*="pt"]');
      for (const element of elements) {
        const style = element.getAttribute('style');
        if (!!style) {
          element.setAttribute('style', style.replace(/pt/g, 'px'));
        }
      }
    },
  }
}
</script>
<style scoped>
img {
  max-width: 100%;
}
.oneLine {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>