manageObject.vue 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916
  1. <script setup lang="ts">
  2. defineOptions({
  3. name: "evaluateChangeManageObject"
  4. });
  5. import { getState, getStateType, assessmentStatus } from "@/config/tag";
  6. import { ref, reactive, onMounted, watch, computed } from "vue";
  7. import {
  8. getAssessmentQuotaDetails,
  9. delAssessmentObject,
  10. getAssessmentObjectDetails,
  11. postAddAssessmentObject,
  12. updateAssessmentQuotaDetails,
  13. alterFinishValue,
  14. automaticCollection,
  15. setTableHeader,
  16. delBatchDelScoreInfoVO,
  17. getAssessmentDetails
  18. } from "@/api/assessment";
  19. import editIndex from "./editIndex.vue";
  20. import { getTemplateInfoAllList } from "@/api/templateInfo";
  21. import { useRouter } from "vue-router";
  22. import iconEdit from "@/assets/公式计算.png";
  23. import { ElMessage, ElMessageBox } from "element-plus";
  24. import {
  25. treeDept,
  26. postListTreeWithUserApi,
  27. postListTree
  28. } from "@/api/department";
  29. import { Search } from "@element-plus/icons-vue";
  30. import messagePerson from "./message.vue";
  31. import dayjs from "dayjs";
  32. // 人员,医疗组,负责人
  33. import {
  34. postUserList,
  35. postOrganizationUserPage,
  36. getLeaderList
  37. } from "@/api/userSetting";
  38. // 获取医疗组的数据
  39. import { postPageGroup } from "@/api/userGroup";
  40. const $props = defineProps({
  41. message: {
  42. type: Object
  43. }
  44. });
  45. const valSelection = ref(false);
  46. const messageData = ref({});
  47. const initParams = reactive({
  48. params: {
  49. pageNumber: 1,
  50. pageSize: 10,
  51. userName: "",
  52. modelName: "",
  53. quotaName: "",
  54. assessmentId: "",
  55. orderField: "",
  56. orderType: ""
  57. },
  58. objParams: {
  59. pageNumber: 1,
  60. pageSize: 10,
  61. userName: "",
  62. modelName: "",
  63. quotaName: "",
  64. assessmentId: "",
  65. orderField: "",
  66. orderType: ""
  67. },
  68. indexParams: {
  69. pageNumber: 1,
  70. pageSize: 10,
  71. userName: "",
  72. modelName: "",
  73. quotaName: "",
  74. assessmentId: "",
  75. orderField: "",
  76. orderType: ""
  77. },
  78. tmpParams: {
  79. page: 1,
  80. pageSize: 100
  81. },
  82. total: 0,
  83. total1: 0,
  84. list: [],
  85. Indexlist: [],
  86. tmpList: []
  87. });
  88. const state = reactive({
  89. tableType: 0
  90. });
  91. // 转换函数 --- 人员
  92. const convertDepartmentDataRecursive_Person = data => {
  93. return data.map(department => {
  94. const { userNameNew, userCodeNew, children } = department;
  95. return {
  96. value: userCodeNew,
  97. label: userNameNew,
  98. children:
  99. children.length > 0
  100. ? children.map(
  101. child => convertDepartmentDataRecursive_Person([child])[0]
  102. )
  103. : []
  104. };
  105. });
  106. };
  107. // 转换函数 --- 部门
  108. const convertDepartmentDataRecursive = data => {
  109. return data.map(department => {
  110. const { deptCode, deptName, childrenRes } = department;
  111. return {
  112. value: deptCode,
  113. label: deptName,
  114. children:
  115. childrenRes.length > 0
  116. ? childrenRes.map(child => convertDepartmentDataRecursive([child])[0])
  117. : []
  118. };
  119. });
  120. };
  121. const dpetTree = ref([]);
  122. onMounted(async () => {
  123. Object.assign(messageData.value, $props.message);
  124. console.log("传递的值", $props.message);
  125. switch (messageData.value.assessmentType) {
  126. case 0:
  127. initParams.assessmentType = "员工";
  128. break;
  129. case 1:
  130. initParams.assessmentType = "部门";
  131. break;
  132. case 2:
  133. initParams.assessmentType = "医疗组";
  134. break;
  135. case 3:
  136. initParams.assessmentType = "员工";
  137. }
  138. assessmentTypeApi(messageData.value.assessmentType);
  139. initParams.params.assessmentId = $props.message.id;
  140. initParams.objParams.assessmentId = $props.message.id;
  141. initParams.indexParams.assessmentId = $props.message.id;
  142. state.tableType = $props.message.assessmentType;
  143. await getAssessmentQuotaDetailsApi();
  144. await getTemplateInfoListApi();
  145. await getAssessmentObjectDetailsApi();
  146. });
  147. const treeDeptList = ref([]);
  148. const assessmentTypeApi = async value => {
  149. switch (value) {
  150. case 0:
  151. postListTreeWithUserApi();
  152. break;
  153. case 1:
  154. const { data, code } = await postListTree();
  155. dpetTree.value = convertDepartmentDataRecursive(data);
  156. break;
  157. case 2:
  158. const yiliao = await postPageGroup({
  159. pageNumber: 1,
  160. pageSize: 1000
  161. });
  162. treeDeptList.value = yiliao.data.records;
  163. break;
  164. case 3:
  165. const fuzhere = await getLeaderList({ type: "dept" });
  166. console.log(fuzhere);
  167. treeDeptList.value = fuzhere.data;
  168. }
  169. };
  170. // 查询考核信息详情(考核指标)前先调用此接口,插入类型是自动采集的完成值
  171. const alterFinishValueApi = async () => {
  172. const { code, msg } = await alterFinishValue(initParams.indexParams);
  173. if (code != 200) {
  174. // ElMessage.error(msg);
  175. }
  176. };
  177. // 指标分页查询
  178. const getAssessmentQuotaDetailsApi = async () => {
  179. const res = await getAssessmentQuotaDetails(initParams.indexParams);
  180. if (res.code === 200) {
  181. console.log("指标分页查询", res);
  182. initParams.Indexlist = res.data.records;
  183. initParams.total1 = res.data.totalRow;
  184. alterFinishValueApi();
  185. getAssessmentDetailsApi(); // 获取考核指标详情表头信息
  186. }
  187. };
  188. // 考核模板
  189. const modulesList = ref([]);
  190. const getTemplateInfoListApi = async () => {
  191. const { data = [], code } = await getTemplateInfoAllList();
  192. if (code == 200) {
  193. modulesList.value = data;
  194. }
  195. };
  196. const handleModulesSelect = val => {
  197. addPersonParams.assessmentModelId = val;
  198. modulesList.value.forEach(el => {
  199. if (el.id === val) {
  200. addPersonParams.assessmentModelName = el.tpName;
  201. }
  202. });
  203. };
  204. // 删除
  205. const delParams = reactive({
  206. assessmentId: "",
  207. objectAddVoList: []
  208. });
  209. // 被考核对象
  210. const addPersonParams = reactive({
  211. assessmentId: "",
  212. objectAddVoList: [],
  213. assessmentModelId: "",
  214. assessmentModelName: "",
  215. value1: [],
  216. modulesValue: ""
  217. });
  218. const addPersonParamsRules = reactive({
  219. value1: [
  220. {
  221. required: true,
  222. message: "请选择人员/科室/医疗组",
  223. trigger: "change"
  224. }
  225. ],
  226. modulesValue: [
  227. {
  228. required: true,
  229. message: "请选择考核模板",
  230. trigger: "change"
  231. }
  232. ]
  233. });
  234. // 添加被考核人
  235. const delAssessmentObjectApi = async () => {
  236. if (valSelection.value) {
  237. ElMessageBox.confirm(
  238. "该员工考核删除后不可恢复,请谨慎操作!",
  239. "确定删除该员工考核吗?",
  240. {
  241. confirmButtonText: "确定",
  242. cancelButtonText: "取消",
  243. type: "warning"
  244. }
  245. ).then(async () => {
  246. const { code, msg } = await delAssessmentObject(delParams);
  247. if (code === 200) {
  248. getAssessmentObjectDetailsApi();
  249. ElMessage.success("删除成功");
  250. } else {
  251. ElMessage.error(msg);
  252. }
  253. });
  254. } else {
  255. ElMessage.warning("请选择要删除的考核对象");
  256. }
  257. };
  258. // 批量选中
  259. const changeSelection = val => {
  260. if (val) {
  261. valSelection.value = true;
  262. delParams.objectAddVoList = [];
  263. delParams.assessmentId = messageData.value.id;
  264. addPersonParams.assessmentId = messageData.value.id;
  265. let assessmentObjectId;
  266. let assessmentObjectName;
  267. val.forEach((item, index) => {
  268. const obj = {
  269. assessmentObjectId: item.assessmentObjectId,
  270. assessmentObjectName: item.assessmentObjectName
  271. };
  272. // delParams.objectAddVoList.forEach((item1, index1) => {
  273. // if (index == index1) {
  274. // assessmentObjectId = item.assessmentObjectId;
  275. // assessmentObjectName = item.assessmentObjectName;
  276. delParams.objectAddVoList.push(obj);
  277. // }
  278. // });
  279. });
  280. }
  281. };
  282. const router = useRouter();
  283. const activeName = ref("first");
  284. // 批量导入
  285. const addsImport = () => {
  286. router.push({ name: "importIndex", query: { ...messageData.value } });
  287. };
  288. const publishShow = ref(true);
  289. const publish = () => {
  290. publishShow.value = false;
  291. ElMessage({
  292. message: "成功",
  293. type: "success"
  294. });
  295. };
  296. // 添加被考核人
  297. const dialogVisibleAdd = ref(false);
  298. const assessmentTypeRef = ref();
  299. const transformArrayFormat = data => {
  300. return data.assessmentObjectId
  301. ?.map((item, index) => {
  302. return {
  303. assessmentObjectId: item,
  304. assessmentObjectName: data.assessmentObjectName[index]
  305. };
  306. })
  307. .flat();
  308. };
  309. // 人员 ---- 部门
  310. function flattenTree(data) {
  311. let result = [];
  312. for (const item of data) {
  313. // 添加当前节点到结果数组
  314. result.push({ value: item.value, label: item.label });
  315. // 如果有子节点,递归处理子节点
  316. if (item.children && item.children.length > 0) {
  317. result = result.concat(flattenTree(item.children));
  318. }
  319. }
  320. return result;
  321. }
  322. // const handleNodeRreeSelect = data => {
  323. // let dataList;
  324. // if ($props.message.assessmentType == 1) {
  325. // if (Array.isArray([data])) {
  326. // dataList = flattenTree([data]);
  327. // dataList.map(item => {
  328. // addPersonParams?.objectAddVoList?.push({
  329. // assessmentObjectId: item.value,
  330. // assessmentObjectName: item.label
  331. // });
  332. // });
  333. // }
  334. // }
  335. // };
  336. const handleRreeSelect = () => {
  337. addPersonParams.objectAddVoList = [];
  338. const dataList = assessmentTypeRef.value.getCheckedNodes() || [];
  339. if ($props.message.assessmentType === 0) {
  340. dataList.forEach(item => {
  341. if (item.value.substring(0, 4) === "user") {
  342. addPersonParams.objectAddVoList.push({
  343. assessmentObjectId: item.value,
  344. assessmentObjectName: item.label
  345. });
  346. }
  347. });
  348. } else {
  349. dataList.forEach(item => {
  350. addPersonParams.objectAddVoList.push({
  351. assessmentObjectId: item.value,
  352. assessmentObjectName: item.label
  353. });
  354. });
  355. }
  356. };
  357. // 医疗 --- 医疗主任
  358. const handChange = data => {
  359. let gropList = [];
  360. treeDeptList.value.map(it => {
  361. data.map(id => {
  362. if ($props.message.assessmentType == 2) {
  363. if (it.groupCode == id) {
  364. gropList.push({
  365. assessmentObjectId: it.groupCode,
  366. assessmentObjectName: it.groupName
  367. });
  368. }
  369. }
  370. if ($props.message.assessmentType == 3) {
  371. if (it.userCode == id) {
  372. gropList.push({
  373. assessmentObjectId: it.userCode,
  374. assessmentObjectName: it.realName
  375. });
  376. }
  377. }
  378. });
  379. });
  380. addPersonParams.objectAddVoList = gropList;
  381. const list = ref({});
  382. const arr = treeDeptList.value.filter(item => {
  383. return addPersonParams.value1.includes(item.groupCode);
  384. });
  385. list.value.assessmentObjectId = arr.map(item => item.groupCode);
  386. list.value.assessmentObjectName = arr.map(item => item.groupName);
  387. // addPersonParams.objectAddVoList = transformArrayFormat(list);
  388. };
  389. const dialogVisibleAddShow = () => {
  390. dialogVisibleAdd.value = true;
  391. };
  392. // 跳转对应科室
  393. const GoView = row => {
  394. console.log(row, "路由跳转信息展示", messageData.value);
  395. const arr = {
  396. "0": "/draw/children/worker/workerDrak",
  397. "1": "/draw/children/department/departmentDrank",
  398. "2": "/draw/children/health/healthDrank",
  399. "3": "/draw/children/head/headDrank"
  400. };
  401. for (let key in arr) {
  402. if ($props.message.assessmentType == key) {
  403. router.push({
  404. path: arr[key],
  405. query: {
  406. assessmentId: messageData.value.id,
  407. assessmentModelId: row.assessmentModelId,
  408. assessmentObjectId: row.assessmentObjectId,
  409. assessmentName: row.assessmentModelName,
  410. assessmentModelName: row.assessmentModelName,
  411. // assessmentName: messageData.value.name,
  412. assessmentObjectName: row.assessmentObjectName
  413. }
  414. });
  415. return;
  416. }
  417. }
  418. };
  419. // 考核对象
  420. const objList = ref([]);
  421. const getAssessmentObjectDetailsApi = async () => {
  422. const { data, msg, code } = await getAssessmentObjectDetails(
  423. initParams.objParams
  424. );
  425. const res = await getAssessmentObjectDetails({
  426. pageNumber: 1,
  427. pageSize: 1000,
  428. assessmentId: initParams.objParams.assessmentId
  429. });
  430. if (res.code == 200) {
  431. // initParams.tmpList = res.data.records;
  432. initParams.tmpList = Array.from(
  433. new Map(
  434. res.data.records.map(item => [item.assessmentModelId, item])
  435. ).values()
  436. );
  437. }
  438. if (code === 200) {
  439. objList.value = data.records;
  440. initParams.total = data.totalRow;
  441. }
  442. };
  443. const handleSizeChange = (val: number) => {
  444. initParams.objParams.pageSize = val;
  445. getAssessmentObjectDetailsApi();
  446. };
  447. const handleCurrentChange = (val: number) => {
  448. initParams.objParams.pageNumber = val;
  449. getAssessmentObjectDetailsApi();
  450. };
  451. // 指标
  452. const handleSizeIndexChange = (val: number) => {
  453. initParams.indexParams.pageSize = val;
  454. getAssessmentQuotaDetailsApi();
  455. };
  456. const handleCurrentIndexChange = (val: number) => {
  457. initParams.indexParams.pageNumber = val;
  458. getAssessmentQuotaDetailsApi();
  459. };
  460. // 指标修改
  461. const updateAssessmentQuotaDetailsApi = async row => {
  462. try {
  463. const { msg, code } = await updateAssessmentQuotaDetails({ ...row });
  464. Object.assign(editVxe, {
  465. relationId: null,
  466. startValue: null,
  467. finalValue: null,
  468. dataSource: null,
  469. score: null,
  470. assessmentObjectId: null,
  471. assessmentModelId: null,
  472. id: null,
  473. dimId: null,
  474. assessmentId: null
  475. });
  476. if (code === 200) {
  477. ElMessage.success("修改成功");
  478. getAssessmentQuotaDetailsApi();
  479. } else {
  480. getAssessmentQuotaDetailsApi();
  481. }
  482. } catch (error) {
  483. // ElMessage.error(error.response.data.msg);
  484. getAssessmentQuotaDetailsApi();
  485. }
  486. };
  487. const tableVxeRef = ref();
  488. const editConfig = ref({
  489. trigger: "click",
  490. mode: "cell",
  491. showStatus: true,
  492. beforeEditMethod({ row, column }) {
  493. console.log("编辑123212132", column.title);
  494. // 完成值 挑战值 门槛值 增幅 降幅 上期完成值 上上期完成值 得分
  495. if (
  496. column.title == "目标值" ||
  497. column.title == "挑战值" ||
  498. column.title == "门槛值"
  499. ) {
  500. return true;
  501. } else {
  502. if (row.valueInput == 4 || row.valueInput == "4") {
  503. return false;
  504. } else {
  505. return true;
  506. }
  507. }
  508. }
  509. });
  510. const editVxe = reactive({
  511. relationId: null,
  512. startValue: null,
  513. finalValue: null,
  514. dataSource: null,
  515. score: null,
  516. assessmentObjectId: null,
  517. assessmentModelId: null,
  518. id: null,
  519. dimId: null,
  520. addValue: null,
  521. decValue: null,
  522. challengeValue: null,
  523. upperValue: null,
  524. agupperValue: null,
  525. assessmentId: null
  526. });
  527. // 编辑前面
  528. const editOpenEvent = data => {
  529. console.log("editOpenEvent", data);
  530. };
  531. const hangdleOpenClick = row => {
  532. Object.assign(editVxe, {
  533. relationId: null,
  534. startValue: null,
  535. finalValue: null,
  536. dataSource: null,
  537. score: null,
  538. assessmentObjectId: null,
  539. assessmentModelId: null,
  540. addValue: null,
  541. decValue: null,
  542. challengeValue: null,
  543. upperValue: null,
  544. agupperValue: null,
  545. id: null,
  546. dimId: null,
  547. assessmentId: null
  548. });
  549. console.log("hangdleOpenClick", row);
  550. editVxe.finalValue = row?.finalValue;
  551. editVxe.score = row?.score;
  552. };
  553. const editClosedEvent = row => {
  554. // { row, column, newValue, oldValue }
  555. const $table = tableVxeRef.value;
  556. if ($table) {
  557. console.log(1433223, row.row);
  558. editVxe.relationId = row.row?.relationId;
  559. editVxe.assessmentModelId = row.row?.assessmentModelId;
  560. editVxe.assessmentObjectId = row.row?.assessmentObjectId;
  561. editVxe.id = row.row?.id;
  562. editVxe.dimId = row.row?.dimId;
  563. editVxe.assessmentId = messageData.value.id;
  564. // 判断表头
  565. if (row.column.title == "得分") {
  566. // 判断是否为空
  567. if (row.row?.score) {
  568. // 判断是否id相同
  569. if (editVxe.score != row.row?.score) {
  570. // if (row.row?.id != editVxe.id) {
  571. editVxe.score = convertToNumberIfPercentage(row.row?.score);
  572. editVxe.finalValue = null;
  573. editVxe.challengeValue = null;
  574. editVxe.startValue = null;
  575. editVxe.addValue = null;
  576. editVxe.decValue = null;
  577. editVxe.upperValue = null;
  578. editVxe.targetValue = null;
  579. editVxe.agupperValue = null;
  580. updateAssessmentQuotaDetailsApi(editVxe);
  581. // }
  582. }
  583. }
  584. }
  585. if (row.column.title == "完成值") {
  586. if (row.row?.finalValue) {
  587. // if (row.row?.id != editVxe.id) {
  588. if (editVxe.finalValue != row.row?.finalValue) {
  589. editVxe.finalValue = convertToNumberIfPercentage(row.row?.finalValue);
  590. editVxe.score = null;
  591. editVxe.challengeValue = null;
  592. editVxe.startValue = null;
  593. editVxe.addValue = null;
  594. editVxe.decValue = null;
  595. editVxe.upperValue = null;
  596. editVxe.targetValue = null;
  597. editVxe.agupperValue = null;
  598. updateAssessmentQuotaDetailsApi(editVxe);
  599. }
  600. // }
  601. }
  602. }
  603. if (row.column.title == "挑战值") {
  604. if (row.row?.challengeValue) {
  605. // if (row.row?.id != editVxe.id) {
  606. if (editVxe.challengeValue != row.row?.challengeValue) {
  607. editVxe.challengeValue = convertToNumberIfPercentage(
  608. row.row?.challengeValue
  609. );
  610. editVxe.score = null;
  611. editVxe.finalValue = null;
  612. editVxe.startValue = null;
  613. editVxe.addValue = null;
  614. editVxe.decValue = null;
  615. editVxe.upperValue = null;
  616. editVxe.targetValue = null;
  617. editVxe.agupperValue = null;
  618. updateAssessmentQuotaDetailsApi(editVxe);
  619. }
  620. // }
  621. }
  622. }
  623. if (row.column.title == "门槛值") {
  624. if (row.row?.startValue) {
  625. // if (row.row?.id != editVxe.id) {
  626. if (editVxe.startValue != row.row?.startValue) {
  627. editVxe.startValue = convertToNumberIfPercentage(row.row?.startValue);
  628. editVxe.score = null;
  629. editVxe.finalValue = null;
  630. editVxe.challengeValue = null;
  631. editVxe.addValue = null;
  632. editVxe.decValue = null;
  633. editVxe.upperValue = null;
  634. editVxe.targetValue = null;
  635. editVxe.agupperValue = null;
  636. updateAssessmentQuotaDetailsApi(editVxe);
  637. }
  638. // }
  639. }
  640. }
  641. if (row.column.title == "增幅") {
  642. if (row.row?.addValue) {
  643. if (editVxe.addValue != row.row?.addValue) {
  644. editVxe.addValue = convertToNumberIfPercentage(row.row?.addValue);
  645. editVxe.startValue = null;
  646. editVxe.score = null;
  647. editVxe.finalValue = null;
  648. editVxe.challengeValue = null;
  649. editVxe.decValue = null;
  650. editVxe.upperValue = null;
  651. editVxe.targetValue = null;
  652. editVxe.agupperValue = null;
  653. updateAssessmentQuotaDetailsApi(editVxe);
  654. }
  655. }
  656. }
  657. if (row.column.title == "降幅") {
  658. if (row.row?.decValue) {
  659. if (editVxe.decValue != row.row?.decValue) {
  660. editVxe.decValue = convertToNumberIfPercentage(row.row?.decValue);
  661. editVxe.startValue = null;
  662. editVxe.score = null;
  663. editVxe.finalValue = null;
  664. editVxe.challengeValue = null;
  665. editVxe.addValue = null;
  666. editVxe.upperValue = null;
  667. editVxe.agupperValue = null;
  668. editVxe.targetValue = null;
  669. updateAssessmentQuotaDetailsApi(editVxe);
  670. }
  671. }
  672. }
  673. if (row.column.title == "上期完成值") {
  674. if (row.row?.upperValue) {
  675. if (editVxe.upperValue != row.row?.upperValue) {
  676. editVxe.upperValue = convertToNumberIfPercentage(row.row?.upperValue);
  677. editVxe.startValue = null;
  678. editVxe.score = null;
  679. editVxe.finalValue = null;
  680. editVxe.challengeValue = null;
  681. editVxe.addValue = null;
  682. editVxe.decValue = null;
  683. editVxe.agupperValue = null;
  684. editVxe.targetValue = null;
  685. updateAssessmentQuotaDetailsApi(editVxe);
  686. }
  687. }
  688. }
  689. if (row.column.title == "上上期完成值") {
  690. if (row.row?.agupperValue) {
  691. if (editVxe.agupperValue != row.row?.agupperValue) {
  692. editVxe.agupperValue = convertToNumberIfPercentage(
  693. row.row?.agupperValue
  694. );
  695. editVxe.startValue = null;
  696. editVxe.score = null;
  697. editVxe.finalValue = null;
  698. editVxe.challengeValue = null;
  699. editVxe.addValue = null;
  700. editVxe.decValue = null;
  701. editVxe.upperValue = null;
  702. editVxe.targetValue = null;
  703. updateAssessmentQuotaDetailsApi(editVxe);
  704. }
  705. }
  706. }
  707. if (row.column.title == "目标值") {
  708. if (row.row?.targetValue) {
  709. if (editVxe.targetValue != row.row?.targetValue) {
  710. editVxe.targetValue = convertToNumberIfPercentage(
  711. row.row?.targetValue
  712. );
  713. editVxe.startValue = null;
  714. editVxe.agupperValue = null;
  715. editVxe.score = null;
  716. editVxe.finalValue = null;
  717. editVxe.challengeValue = null;
  718. editVxe.addValue = null;
  719. editVxe.decValue = null;
  720. editVxe.upperValue = null;
  721. updateAssessmentQuotaDetailsApi(editVxe);
  722. }
  723. }
  724. }
  725. }
  726. };
  727. // 关闭弹窗
  728. const closePerson = () => {
  729. Object.assign(addPersonParams, {
  730. assessmentId: "",
  731. objectAddVoList: [],
  732. assessmentModelId: "",
  733. assessmentModelName: ""
  734. });
  735. addPersonParams.value1 = [];
  736. addPersonParams.modulesValue = "";
  737. ruleFormRef.value.resetFields();
  738. dialogVisibleAdd.value = false;
  739. };
  740. // 添加被考核人
  741. const ruleFormRef = ref(null);
  742. const addPerson = () => {
  743. ruleFormRef.value.validate(async valid => {
  744. if (valid) {
  745. addPersonParams.assessmentId = $props.message.id;
  746. let arr = [];
  747. if ($props.message.assessmentType == 0) {
  748. addPersonParams.objectAddVoList.map(it => {
  749. if (it.assessmentObjectId.substring(0, 4) == "user") {
  750. arr.push(it);
  751. }
  752. addPersonParams.objectAddVoList = arr;
  753. });
  754. }
  755. const { data, msg, code } = await postAddAssessmentObject({
  756. assessmentId: addPersonParams.assessmentId,
  757. assessmentModelId: addPersonParams.assessmentModelId,
  758. assessmentModelName: addPersonParams.assessmentModelName,
  759. objectAddVoList: addPersonParams.objectAddVoList
  760. });
  761. if (code === 200) {
  762. ElMessage.success("添加成功");
  763. dialogVisibleAdd.value = false;
  764. getAssessmentObjectDetailsApi();
  765. closePerson();
  766. }
  767. }
  768. });
  769. };
  770. const changTitle = () => {
  771. const obj = {
  772. 0: "添加被考核人",
  773. 1: "添加被考核科室",
  774. 2: "添加被考核医疗组",
  775. 3: "添加被考核部门负责人"
  776. };
  777. return obj[$props.message.assessmentType];
  778. };
  779. const editDisabledEvent = ({}) => {};
  780. // 同步数据
  781. const automaticCollectionApi = async () => {
  782. const { code, msg } = await automaticCollection(initParams.indexParams);
  783. if (code === 200) {
  784. ElMessage.success("同步数据成功");
  785. } else {
  786. ElMessage.error(msg);
  787. }
  788. };
  789. const assessmentHeader = reactive({
  790. id: "",
  791. name: "",
  792. cycle: "",
  793. cycleValue: "",
  794. assessmentType: 0,
  795. assessmentStatus: 0,
  796. isDelete: 0,
  797. showTargetValue: 1,
  798. showChallengeValue: 0,
  799. showStartValue: 0,
  800. showAddValue: 0,
  801. showDecValue: 0,
  802. showUpperValue: 0,
  803. showAgupperValue: 0
  804. });
  805. const showAssessmentHeader = reactive({
  806. showTargetValue: 1,
  807. showChallengeValue: 0,
  808. showStartValue: 0,
  809. showAddValue: 0,
  810. showDecValue: 0,
  811. showUpperValue: 0,
  812. showAgupperValue: 0
  813. });
  814. // 开关状态
  815. // 目标值
  816. const showTargetValueSwitch = computed({
  817. get: () => assessmentHeader.showTargetValue === 1,
  818. set: value => {
  819. assessmentHeader.showTargetValue = value ? 1 : 0;
  820. }
  821. });
  822. // 挑战值
  823. const showChallengeValueSwitch = computed({
  824. get: () => assessmentHeader.showChallengeValue === 1,
  825. set: value => {
  826. assessmentHeader.showChallengeValue = value ? 1 : 0;
  827. }
  828. });
  829. // 门槛值
  830. const showStartValueSwitch = computed({
  831. get: () => assessmentHeader.showStartValue === 1,
  832. set: value => {
  833. assessmentHeader.showStartValue = value ? 1 : 0;
  834. }
  835. });
  836. // 增幅值
  837. const showAddValueSwitch = computed({
  838. get: () => assessmentHeader.showAddValue === 1,
  839. set: value => {
  840. assessmentHeader.showAddValue = value ? 1 : 0;
  841. }
  842. });
  843. // 降幅值
  844. const showDecValueSwitch = computed({
  845. get: () => assessmentHeader.showDecValue === 1,
  846. set: value => {
  847. assessmentHeader.showDecValue = value ? 1 : 0;
  848. }
  849. });
  850. // 上期数值
  851. const showUpperValueSwitch = computed({
  852. get: () => assessmentHeader.showUpperValue === 1,
  853. set: value => {
  854. assessmentHeader.showUpperValue = value ? 1 : 0;
  855. }
  856. });
  857. // 上上期值
  858. const showAgupperValueSwitch = computed({
  859. get: () => assessmentHeader.showAgupperValue === 1,
  860. set: value => {
  861. assessmentHeader.showAgupperValue = value ? 1 : 0;
  862. }
  863. });
  864. const setTableHeaderApi = async () => {
  865. Object.assign(assessmentHeader, {
  866. id: $props.message.id,
  867. name: $props.message.name,
  868. cycle: $props.message.cycle,
  869. cycleValue: $props.message.cycleValue,
  870. assessmentType: $props.message.assessmentType,
  871. assessmentStatus: $props.message.assessmentStatus
  872. });
  873. const { code, msg } = await setTableHeader(assessmentHeader);
  874. if (code === 200) {
  875. getAssessmentQuotaDetailsApi();
  876. let aa = JSON.parse(JSON.stringify(assessmentHeader));
  877. console.log("表头设置", aa);
  878. // 目标值
  879. aa.showTargetValue == 1
  880. ? showColEvent("targetValue")
  881. : hideColEvent("targetValue");
  882. // 挑战值
  883. aa.showChallengeValue == 1
  884. ? showColEvent("challengeValue")
  885. : hideColEvent("challengeValue");
  886. // 门槛值
  887. aa.showStartValue == 1
  888. ? showColEvent("startValue")
  889. : hideColEvent("startValue");
  890. // 增幅
  891. aa.showAddValue == 1 ? showColEvent("addValue") : hideColEvent("addValue");
  892. // 降幅
  893. aa.showDecValue == 1 ? showColEvent("decValue") : hideColEvent("decValue");
  894. // 上期完成值
  895. aa.showUpperValue == 1
  896. ? showColEvent("upperValue")
  897. : hideColEvent("upperValue");
  898. // 上上期完成值
  899. aa.showAgupperValue == 1
  900. ? showColEvent("agupperValue")
  901. : hideColEvent("agupperValue");
  902. Object.assign(showAssessmentHeader, aa);
  903. ElMessage.success("表头设置成功");
  904. } else {
  905. ElMessage.error(msg);
  906. }
  907. };
  908. const getAssessmentDetailsApi = async () => {
  909. const { code, data } = await getAssessmentDetails({
  910. id: messageData.value.id
  911. });
  912. if (code == 200) {
  913. assessmentHeader.showTargetValue = data.showTargetValue;
  914. assessmentHeader.showChallengeValue = data.showChallengeValue;
  915. assessmentHeader.showStartValue = data.showStartValue;
  916. assessmentHeader.showAddValue = data.showAddValue;
  917. assessmentHeader.showDecValue = data.showDecValue;
  918. assessmentHeader.showUpperValue = data.showUpperValue;
  919. assessmentHeader.showAgupperValue = data.showAgupperValue;
  920. let aa = JSON.parse(JSON.stringify(assessmentHeader));
  921. console.log(111111, aa);
  922. // 目标值
  923. aa.showTargetValue == 1
  924. ? showColEvent("targetValue")
  925. : hideColEvent("targetValue");
  926. // 挑战值
  927. aa.showChallengeValue == 1
  928. ? showColEvent("challengeValue")
  929. : hideColEvent("challengeValue");
  930. // 门槛值
  931. aa.showStartValue == 1
  932. ? showColEvent("startValue")
  933. : hideColEvent("startValue");
  934. // 增幅
  935. aa.showAddValue == 1 ? showColEvent("addValue") : hideColEvent("addValue");
  936. // 降幅
  937. aa.showDecValue == 1 ? showColEvent("decValue") : hideColEvent("decValue");
  938. // 上期完成值
  939. aa.showUpperValue == 1
  940. ? showColEvent("upperValue")
  941. : hideColEvent("upperValue");
  942. // 上上期完成值
  943. aa.showAgupperValue == 1
  944. ? showColEvent("agupperValue")
  945. : hideColEvent("agupperValue");
  946. Object.assign(showAssessmentHeader, aa);
  947. }
  948. };
  949. // 判断是否为百分数
  950. function convertToNumberIfPercentage(value) {
  951. // 判断是否为字符串,并且是否包含百分号
  952. if (typeof value === "string" && value.trim().endsWith("%")) {
  953. // 去掉百分号并将剩余的部分转换为数字
  954. const numberValue = parseFloat(value.slice(0, -1));
  955. // 如果转换后的值是有效的数字,返回数字形式
  956. if (!isNaN(numberValue)) {
  957. return numberValue / 100; // 转换为小数
  958. } else {
  959. return value; // 如果无法转换为有效数字,返回原值
  960. }
  961. }
  962. // 如果不是百分数,直接返回原值
  963. return value;
  964. }
  965. // 数据校验
  966. const validRules = ref({
  967. finalValue: [
  968. {
  969. validator: ({ cellValue }) => {
  970. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  971. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  972. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  973. if (
  974. numberPattern.test(cellValue) ||
  975. decimalPattern.test(cellValue) ||
  976. percentagePattern.test(cellValue)
  977. ) {
  978. return; // 校验通过
  979. } else {
  980. cellValue = "";
  981. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  982. }
  983. }
  984. }
  985. ],
  986. targetValue: [
  987. {
  988. validator: ({ cellValue }) => {
  989. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  990. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  991. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  992. if (
  993. numberPattern.test(cellValue) ||
  994. decimalPattern.test(cellValue) ||
  995. percentagePattern.test(cellValue)
  996. ) {
  997. return; // 校验通过
  998. } else {
  999. cellValue = "";
  1000. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  1001. }
  1002. }
  1003. }
  1004. ],
  1005. challengeValue: [
  1006. {
  1007. validator: ({ cellValue }) => {
  1008. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  1009. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  1010. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  1011. if (
  1012. numberPattern.test(cellValue) ||
  1013. decimalPattern.test(cellValue) ||
  1014. percentagePattern.test(cellValue)
  1015. ) {
  1016. return; // 校验通过
  1017. } else {
  1018. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  1019. }
  1020. }
  1021. }
  1022. ],
  1023. startValue: [
  1024. {
  1025. validator: ({ cellValue }) => {
  1026. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  1027. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  1028. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  1029. if (
  1030. numberPattern.test(cellValue) ||
  1031. decimalPattern.test(cellValue) ||
  1032. percentagePattern.test(cellValue)
  1033. ) {
  1034. return; // 校验通过
  1035. } else {
  1036. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  1037. }
  1038. }
  1039. }
  1040. ],
  1041. addValue: [
  1042. {
  1043. validator: ({ cellValue }) => {
  1044. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  1045. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  1046. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  1047. if (
  1048. numberPattern.test(cellValue) ||
  1049. decimalPattern.test(cellValue) ||
  1050. percentagePattern.test(cellValue)
  1051. ) {
  1052. return; // 校验通过
  1053. } else {
  1054. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  1055. }
  1056. }
  1057. }
  1058. ],
  1059. decValue: [
  1060. {
  1061. validator: ({ cellValue }) => {
  1062. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  1063. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  1064. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  1065. if (
  1066. numberPattern.test(cellValue) ||
  1067. decimalPattern.test(cellValue) ||
  1068. percentagePattern.test(cellValue)
  1069. ) {
  1070. return; // 校验通过
  1071. } else {
  1072. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  1073. }
  1074. }
  1075. }
  1076. ],
  1077. upperValue: [
  1078. {
  1079. validator: ({ cellValue }) => {
  1080. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  1081. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  1082. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  1083. if (
  1084. numberPattern.test(cellValue) ||
  1085. decimalPattern.test(cellValue) ||
  1086. percentagePattern.test(cellValue)
  1087. ) {
  1088. return; // 校验通过
  1089. } else {
  1090. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  1091. }
  1092. }
  1093. }
  1094. ],
  1095. agupperValue: [
  1096. {
  1097. validator: ({ cellValue }) => {
  1098. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  1099. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  1100. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  1101. if (
  1102. numberPattern.test(cellValue) ||
  1103. decimalPattern.test(cellValue) ||
  1104. percentagePattern.test(cellValue)
  1105. ) {
  1106. return; // 校验通过
  1107. } else {
  1108. return new Error("请输入一个有效的数字、小数或百分数"); // 校验不通过
  1109. }
  1110. }
  1111. }
  1112. ],
  1113. score: [
  1114. {
  1115. validator: ({ cellValue }) => {
  1116. const numberPattern = /^[0-9]+(\.[0-9]+)?$/; // 匹配数字或小数
  1117. const decimalPattern = /^\d+(\.\d+)?$/; // 匹配小数
  1118. const percentagePattern = /^([0-9]{1,2}|100)(\.[0-9]{1,2})?%$/; // 匹配百分数
  1119. if (numberPattern.test(cellValue) || decimalPattern.test(cellValue)) {
  1120. return;
  1121. } else {
  1122. return new Error("请输入一个有效的数字、小数"); // 校验不通过
  1123. }
  1124. }
  1125. }
  1126. ]
  1127. });
  1128. // 固定表头
  1129. // 计算列配置
  1130. const showColEvent = field => {
  1131. const $table = tableVxeRef.value;
  1132. if ($table) {
  1133. $table.showColumn(field);
  1134. }
  1135. };
  1136. const hideColEvent = field => {
  1137. const $table = tableVxeRef.value;
  1138. if ($table) {
  1139. $table.hideColumn(field);
  1140. }
  1141. };
  1142. const editIndexShow = ref(null);
  1143. const editIndexOpen = (row: Object) => {
  1144. editIndexShow.value.open({
  1145. ...row,
  1146. assessmentId: initParams.indexParams.assessmentId
  1147. });
  1148. };
  1149. const deleteParam = ref([]);
  1150. // 批量删除指标
  1151. const deleteMantList = () => {
  1152. if (deleteParam.value.length === 0) {
  1153. ElMessage.warning("请选择要删除的考核指标");
  1154. } else {
  1155. ElMessageBox.confirm(
  1156. "这些考核项删除后将不可恢复,请谨慎操作",
  1157. "确定删除这些考核项吗?",
  1158. {
  1159. confirmButtonText: "确定",
  1160. cancelButtonText: "取消",
  1161. type: "warning"
  1162. }
  1163. ).then(async () => {
  1164. deleteParam.value.map(item => {
  1165. item.assessmentId = initParams.indexParams.assessmentId;
  1166. });
  1167. const { code } = await delBatchDelScoreInfoVO(deleteParam.value);
  1168. if (code === 200) {
  1169. getAssessmentQuotaDetailsApi();
  1170. activeName.value = "second";
  1171. ElMessage({
  1172. type: "success",
  1173. message: "删除成功"
  1174. });
  1175. }
  1176. });
  1177. }
  1178. };
  1179. // 单选
  1180. const selectChangeEvent = row => {
  1181. const $table = tableVxeRef.value;
  1182. deleteParam.value = [];
  1183. if ($table) {
  1184. // deleteParam.value = row.records;
  1185. row.records.map(item => {
  1186. deleteParam.value.push({
  1187. assessmentObjectId: item.assessmentObjectId,
  1188. assessmentModelId: item.assessmentModelId,
  1189. assessmentId: item.assessmentId,
  1190. dimId: item.dimId,
  1191. indId: item.id
  1192. });
  1193. });
  1194. }
  1195. };
  1196. // 全选
  1197. const selectAllChangeEvent = row => {
  1198. const $table = tableVxeRef.value;
  1199. deleteParam.value = [];
  1200. if ($table) {
  1201. // deleteParam.value = row.records;
  1202. console.log(111111, row.records);
  1203. row.records.map(item => {
  1204. deleteParam.value.push({
  1205. assessmentObjectId: item.assessmentObjectId,
  1206. assessmentModelId: item.assessmentModelId,
  1207. assessmentId: item.assessmentId,
  1208. dimId: item.dimId,
  1209. indId: item.id
  1210. });
  1211. });
  1212. }
  1213. };
  1214. </script>
  1215. <template>
  1216. <div class="w-full">
  1217. <!-- 指标编辑 -->
  1218. <editIndex ref="editIndexShow" />
  1219. <div class="w-full flex items-center justify-between">
  1220. <div class="flex items-center justify-between mt-2">
  1221. <div class="bg-icon">
  1222. <div>
  1223. <el-icon>
  1224. <Tickets />
  1225. </el-icon>
  1226. </div>
  1227. </div>
  1228. <div>
  1229. <div class="flex items-center justify-between">
  1230. <h5>{{ messageData.name }}</h5>
  1231. <el-tag :type="getStateType(messageData.assessmentStatus)">
  1232. {{ assessmentStatus(messageData.assessmentStatus) }}
  1233. </el-tag>
  1234. </div>
  1235. <el-text type="info" class="text-xs">
  1236. {{ messageData.cycleValue }}
  1237. </el-text>
  1238. </div>
  1239. </div>
  1240. <div class="mr-10">
  1241. <Auth :value="['公布考核结果']">
  1242. <el-button v-if="publishShow" type="primary" @click="publish"
  1243. >公布考核结果</el-button
  1244. >
  1245. </Auth>
  1246. </div>
  1247. </div>
  1248. <el-tabs v-model="activeName" class="demo-tabs">
  1249. <el-tab-pane label="考核对象" name="first">
  1250. <div class="w-full flex items-center justify-between">
  1251. <div class="w-1/2 flex items-center justify-between">
  1252. <el-text class="w-1/5">考核模板</el-text>
  1253. <el-select
  1254. v-model="initParams.objParams.modelName"
  1255. placeholder="请选择"
  1256. filterable
  1257. clearable
  1258. style="width: 250px"
  1259. @change="getAssessmentObjectDetailsApi"
  1260. >
  1261. <el-option
  1262. v-for="itemTmp in initParams.tmpList"
  1263. :key="itemTmp.id"
  1264. :label="itemTmp.assessmentModelName"
  1265. :value="itemTmp.assessmentModelName"
  1266. />
  1267. </el-select>
  1268. <el-input
  1269. v-model="initParams.objParams.userName"
  1270. class="ml-2"
  1271. clearable
  1272. placeholder="搜索"
  1273. :prefix-icon="Search"
  1274. @change="getAssessmentObjectDetailsApi"
  1275. />
  1276. </div>
  1277. <div class="mr-10">
  1278. <!-- <el-button type="primary" plain>批量调整执行人</el-button>
  1279. <el-button type="primary" plain>批量重置流程</el-button> -->
  1280. <Auth :value="['批量删除']">
  1281. <el-button type="primary" plain @click="delAssessmentObjectApi">
  1282. 批量删除
  1283. </el-button>
  1284. </Auth>
  1285. <Auth :value="['添加被考核人']">
  1286. <el-button type="primary" plain @click="dialogVisibleAddShow">{{
  1287. changTitle()
  1288. }}</el-button>
  1289. </Auth>
  1290. </div>
  1291. </div>
  1292. <el-table
  1293. :data="objList"
  1294. style="width: 100%"
  1295. @selection-change="changeSelection"
  1296. >
  1297. <el-table-column type="selection" width="55" />
  1298. <el-table-column
  1299. v-if="state.tableType == 0 || state.tableType == 3"
  1300. prop="realName"
  1301. label="人员"
  1302. width="100"
  1303. />
  1304. <el-table-column
  1305. v-if="state.tableType == 2"
  1306. prop="assessmentObjectName"
  1307. label="医疗组"
  1308. width="100"
  1309. />
  1310. <el-table-column
  1311. v-if="state.tableType == 0 || state.tableType == 3"
  1312. prop="userName"
  1313. label="工号"
  1314. width="180"
  1315. />
  1316. <el-table-column
  1317. v-if="state.tableType != 2"
  1318. prop="deptName"
  1319. label="科室"
  1320. width="180"
  1321. />
  1322. <el-table-column
  1323. prop="assessmentModelName"
  1324. label="考核模板"
  1325. width="300"
  1326. />
  1327. <el-table-column prop="name" label="更新时间" width="150" sortable>
  1328. <template #default="{ row }">
  1329. {{ dayjs(row.updateTime).format("YYYY-MM-DD HH:mm:ss") }}
  1330. </template>
  1331. </el-table-column>
  1332. <el-table-column label="操作" width="200" fixed="right">
  1333. <template #default="{ row }">
  1334. <!-- <el-button link :icon="Edit" /> -->
  1335. <el-icon @click="GoView(row)">
  1336. <View />
  1337. </el-icon>
  1338. </template>
  1339. </el-table-column>
  1340. </el-table>
  1341. <div class="flex justify-between item-center">
  1342. <div class="float-left mt-5 ml-2 total">
  1343. <!-- 共{{ initParams.total }}条数据 -->
  1344. </div>
  1345. <div class="float-right mt-5 mr-8">
  1346. <el-pagination
  1347. v-model:current-page="initParams.objParams.pageNumber"
  1348. v-model:page-size="initParams.objParams.pageSize"
  1349. background
  1350. layout="total, sizes, prev, pager, next, jumper"
  1351. :total="initParams.total"
  1352. @size-change="handleSizeChange"
  1353. @current-change="handleCurrentChange"
  1354. />
  1355. </div>
  1356. </div>
  1357. </el-tab-pane>
  1358. <el-tab-pane label="考核指标" name="second">
  1359. <div class="w-full flex items-center justify-between">
  1360. <div class="w-1/2 flex items-center justify-between">
  1361. <!-- <el-text class="w-1/5">考核模板</el-text> -->
  1362. <el-select
  1363. v-model="initParams.indexParams.modelName"
  1364. placeholder="请选择考核模板"
  1365. filterable
  1366. clearable
  1367. style="width: 400px"
  1368. @change="getAssessmentQuotaDetailsApi"
  1369. >
  1370. <el-option
  1371. v-for="itemTmp in initParams.tmpList"
  1372. :key="itemTmp.id"
  1373. :label="itemTmp.assessmentModelName"
  1374. :value="itemTmp.assessmentModelName"
  1375. />
  1376. </el-select>
  1377. <el-input
  1378. v-model="initParams.indexParams.userName"
  1379. class="ml-1"
  1380. placeholder="搜索"
  1381. @change="getAssessmentQuotaDetailsApi"
  1382. />
  1383. <el-input
  1384. v-model="initParams.indexParams.quotaName"
  1385. class="ml-2"
  1386. placeholder="搜索指标名称"
  1387. :prefix-icon="Search"
  1388. @change="getAssessmentQuotaDetailsApi"
  1389. />
  1390. </div>
  1391. <!-- <div class="-mr-">
  1392. <el-button type="primary" plain @click="automaticCollectionApi"
  1393. >同步最新数据</el-button
  1394. >
  1395. </div> -->
  1396. <div class="mr-10 flex items-center justify-between">
  1397. <el-button type="primary" plain @click="deleteMantList"
  1398. >批量删除</el-button
  1399. >
  1400. <el-button type="primary" plain @click="automaticCollectionApi"
  1401. >同步最新数据</el-button
  1402. >
  1403. <Auth :value="['批量导入指标']">
  1404. <el-button type="primary" plain @click="addsImport"
  1405. >批量导入</el-button
  1406. >
  1407. </Auth>
  1408. </div>
  1409. </div>
  1410. <vxe-table
  1411. ref="tableVxeRef"
  1412. class="mt-3"
  1413. show-overflow
  1414. keep-source
  1415. :edit-config="editConfig"
  1416. :edit-rules="validRules"
  1417. :data="initParams.Indexlist"
  1418. @edit-closed="editClosedEvent"
  1419. @checkbox-change="selectChangeEvent"
  1420. @checkbox-all="selectAllChangeEvent"
  1421. @selection-change="changeSelection"
  1422. @edit-disabled="editDisabledEvent"
  1423. >
  1424. <vxe-column type="checkbox" width="60" />
  1425. <vxe-column
  1426. v-if="state.tableType == 0 || state.tableType == 3"
  1427. field="realName"
  1428. fixed
  1429. title="人员"
  1430. width="100"
  1431. />
  1432. <!-- :员工,1:部门,2:医疗组,3:部门负责人 -->
  1433. <vxe-column
  1434. v-if="state.tableType == 0 || state.tableType == 3"
  1435. field="userName"
  1436. fixed
  1437. title="工号"
  1438. width="180"
  1439. />
  1440. <vxe-column
  1441. v-if="state.tableType == 0 || state.tableType == 3"
  1442. field="deptName"
  1443. fixed
  1444. title="部门"
  1445. width="180"
  1446. />
  1447. <vxe-column
  1448. v-if="state.tableType == 2"
  1449. field="userGroupName"
  1450. fixed
  1451. title="医疗组"
  1452. width="180"
  1453. />
  1454. <vxe-column
  1455. v-if="state.tableType == 2"
  1456. field="userGroupHospitalCode"
  1457. fixed
  1458. title="医疗组编号"
  1459. width="180"
  1460. />
  1461. <vxe-column
  1462. v-if="state.tableType == 1"
  1463. field="deptName"
  1464. fixed
  1465. title="部门"
  1466. width="180"
  1467. />
  1468. <vxe-column
  1469. v-if="state.tableType == 1"
  1470. field="deptHospitalCode"
  1471. fixed
  1472. title="部门编号"
  1473. width="200"
  1474. />
  1475. <vxe-column
  1476. field="assessmentModelName"
  1477. fixed
  1478. title="考核模板"
  1479. width="180"
  1480. />
  1481. <vxe-column field="name" fixed title="指标名称" width="180" />
  1482. <vxe-column field="scoreRule" fixed title="评价标准" width="180" />
  1483. <vxe-column field="source" fixed title="数据来源" width="180" />
  1484. <vxe-column
  1485. field="targetValue"
  1486. fixed
  1487. title="目标值"
  1488. :edit-render="{
  1489. name: 'input'
  1490. }"
  1491. width="180"
  1492. />
  1493. <vxe-column
  1494. field="addValue"
  1495. fixed
  1496. title="增幅"
  1497. :edit-render="{
  1498. name: 'input'
  1499. }"
  1500. width="180"
  1501. >
  1502. <template #default="{ row }">
  1503. <div @click="hangdleOpenClick(row)">
  1504. {{ row.addValue }}
  1505. </div>
  1506. </template>
  1507. </vxe-column>
  1508. <vxe-column
  1509. field="decValue"
  1510. fixed
  1511. title="降幅"
  1512. :edit-render="{
  1513. name: 'input'
  1514. }"
  1515. width="180"
  1516. >
  1517. <template #default="{ row }">
  1518. <div @click="hangdleOpenClick(row)">
  1519. {{ row.decValue }}
  1520. </div>
  1521. </template>
  1522. </vxe-column>
  1523. <vxe-column
  1524. field="challengeValue"
  1525. fixed
  1526. title="挑战值"
  1527. :edit-render="{
  1528. name: 'input'
  1529. }"
  1530. width="180"
  1531. >
  1532. <template #default="{ row }">
  1533. <div @click="hangdleOpenClick(row)">
  1534. {{ row.challengeValue }}
  1535. </div>
  1536. </template>
  1537. </vxe-column>
  1538. <vxe-column
  1539. field="startValue"
  1540. fixed
  1541. title="门槛值"
  1542. :edit-render="{
  1543. name: 'input'
  1544. }"
  1545. width="180"
  1546. >
  1547. <template #default="{ row }">
  1548. <div @click="hangdleOpenClick(row)">
  1549. {{ row.startValue }}
  1550. </div>
  1551. </template>
  1552. </vxe-column>
  1553. <vxe-column
  1554. field="upperValue"
  1555. fixed
  1556. title="上期完成值"
  1557. :edit-render="{
  1558. name: 'input'
  1559. }"
  1560. width="180"
  1561. >
  1562. <template #default="{ row }">
  1563. <div @click="hangdleOpenClick(row)">
  1564. {{ row.upperValue }}
  1565. </div>
  1566. </template>
  1567. </vxe-column>
  1568. <vxe-column
  1569. field="agupperValue"
  1570. fixed
  1571. title="上上期完成值"
  1572. :edit-render="{
  1573. name: 'input'
  1574. }"
  1575. width="180"
  1576. >
  1577. <template #default="{ row }">
  1578. <div @click="hangdleOpenClick(row)">
  1579. {{ row.agupperValue }}
  1580. </div>
  1581. </template>
  1582. </vxe-column>
  1583. <vxe-column
  1584. field="finalValue"
  1585. fixed
  1586. title="完成值"
  1587. :edit-render="{
  1588. name: 'input'
  1589. }"
  1590. width="180"
  1591. >
  1592. <template #default="{ row }">
  1593. <div @click="hangdleOpenClick(row)">
  1594. {{ convertToNumberIfPercentage(row.finalValue) }}
  1595. </div>
  1596. </template>
  1597. </vxe-column>
  1598. <vxe-column
  1599. field="score"
  1600. fixed
  1601. title="得分"
  1602. :edit-render="{
  1603. name: 'input'
  1604. }"
  1605. width="180"
  1606. >
  1607. <template #default="{ row }">
  1608. <div @click="hangdleOpenClick(row)">
  1609. {{ row.score }}
  1610. </div>
  1611. </template>
  1612. </vxe-column>
  1613. <vxe-column field="updateTime" title="更新时间" sortable width="180">
  1614. <template #default="{ row }">
  1615. {{ dayjs(row.updateTime).format("YYYY-MM-DD HH:mm:ss") }}
  1616. </template>
  1617. </vxe-column>
  1618. <vxe-column field="" title="操作" fixed="right" width="180">
  1619. <template #header>
  1620. 操作
  1621. <!-- 在表头操作后面添加图标 -->
  1622. <el-dropdown placement="top-start" trigger="click">
  1623. <el-icon class="mt-1 w-20 h-10">
  1624. <Setting />
  1625. </el-icon>
  1626. <template #dropdown>
  1627. <el-dropdown-menu>
  1628. <div class="w-[200px] p-1">
  1629. <div class="mt-2">
  1630. <el-text class="mx-1">表头设置</el-text>
  1631. </div>
  1632. <el-text type="info" size="small">可配置字段</el-text>
  1633. <div class="w-full">
  1634. <div class="w-full flex justify-evenly items-center">
  1635. <div class="w-24">
  1636. <el-text type="info" size="small">目标值</el-text>
  1637. </div>
  1638. <el-switch
  1639. v-model="showTargetValueSwitch"
  1640. size="small"
  1641. class="ml-2"
  1642. />
  1643. </div>
  1644. <div class="w-full flex justify-evenly items-center">
  1645. <div class="w-24">
  1646. <el-text type="info" size="small">增幅</el-text>
  1647. </div>
  1648. <el-switch
  1649. v-model="showAddValueSwitch"
  1650. size="small"
  1651. class="ml-2"
  1652. />
  1653. </div>
  1654. <div class="w-full flex justify-evenly items-center">
  1655. <div class="w-24">
  1656. <el-text type="info" size="small">降幅</el-text>
  1657. </div>
  1658. <el-switch
  1659. v-model="showDecValueSwitch"
  1660. size="small"
  1661. class="ml-2"
  1662. />
  1663. </div>
  1664. <div class="w-full flex justify-evenly items-center">
  1665. <div class="w-24">
  1666. <el-text type="info" size="small">挑战值</el-text>
  1667. </div>
  1668. <el-switch
  1669. v-model="showChallengeValueSwitch"
  1670. size="small"
  1671. class="ml-2"
  1672. />
  1673. </div>
  1674. <div class="w-full flex justify-evenly items-center">
  1675. <div class="w-24">
  1676. <el-text type="info" size="small">门槛值</el-text>
  1677. </div>
  1678. <el-switch
  1679. v-model="showStartValueSwitch"
  1680. size="small"
  1681. class="ml-2"
  1682. />
  1683. </div>
  1684. <div class="w-full flex justify-evenly items-center">
  1685. <div class="w-24">
  1686. <el-text type="info" size="small"
  1687. >上期完成值</el-text
  1688. >
  1689. </div>
  1690. <el-switch
  1691. v-model="showUpperValueSwitch"
  1692. size="small"
  1693. class="ml-2"
  1694. />
  1695. </div>
  1696. <div class="w-full flex justify-evenly items-center">
  1697. <div class="w-24">
  1698. <el-text type="info" size="small"
  1699. >上上期完成值</el-text
  1700. >
  1701. </div>
  1702. <el-switch
  1703. v-model="showAgupperValueSwitch"
  1704. size="small"
  1705. class="ml-2"
  1706. />
  1707. </div>
  1708. </div>
  1709. </div>
  1710. <el-dropdown-item>
  1711. <div class="mt-4 ml-20 mb-2 flex float-right">
  1712. <el-tag effect="light" class="mr-3" size="small"
  1713. >取消</el-tag
  1714. >
  1715. <el-tag
  1716. effect="dark"
  1717. size="small"
  1718. type="primary"
  1719. @click="setTableHeaderApi"
  1720. >确认</el-tag
  1721. >
  1722. </div>
  1723. </el-dropdown-item>
  1724. </el-dropdown-menu>
  1725. </template>
  1726. </el-dropdown>
  1727. </template>
  1728. <template #default="{ row }">
  1729. <div class="w-5 h-5">
  1730. <img :src="iconEdit" alt="" @click="editIndexOpen(row)" />
  1731. </div>
  1732. <!-- <el-icon @click="editIndexOpen(row)">
  1733. <Edit />
  1734. </el-icon> -->
  1735. </template>
  1736. </vxe-column>
  1737. </vxe-table>
  1738. <div class="flex justify-between item-center">
  1739. <div class="float-left mt-5 ml-2 total">
  1740. <!-- 共{{ initParams.total1 }}条数据 -->
  1741. </div>
  1742. <div class="float-right mt-5 mr-8">
  1743. <el-pagination
  1744. v-model:current-page="initParams.indexParams.pageNumber"
  1745. v-model:page-size="initParams.indexParams.pageSize"
  1746. background
  1747. layout="total, sizes, prev, pager, next, jumper"
  1748. :total="initParams.total1"
  1749. @size-change="handleSizeIndexChange"
  1750. @current-change="handleCurrentIndexChange"
  1751. />
  1752. </div>
  1753. </div>
  1754. </el-tab-pane>
  1755. <!-- <el-tab-pane label="统计分析" name="third">
  1756. </el-tab-pane> -->
  1757. <el-tab-pane label="基础信息" name="fourth">
  1758. <!-- 延迟加载获取id -->
  1759. <messagePerson v-if="messageData.id" :id="messageData.id" />
  1760. </el-tab-pane>
  1761. </el-tabs>
  1762. <!-- 添加被考核人 -->
  1763. <el-dialog
  1764. v-model="dialogVisibleAdd"
  1765. :title="changTitle()"
  1766. width="500"
  1767. :before-close="closePerson"
  1768. >
  1769. <div>
  1770. <el-form
  1771. ref="ruleFormRef"
  1772. label-position="top"
  1773. label-width="auto"
  1774. :model="addPersonParams"
  1775. :rules="addPersonParamsRules"
  1776. >
  1777. <el-form-item
  1778. v-if="$props.message.assessmentType == 0"
  1779. label="人员"
  1780. label-position="top"
  1781. prop="value1"
  1782. >
  1783. <el-tree-select
  1784. ref="assessmentTypeRef"
  1785. v-model="addPersonParams.value1"
  1786. :data="convertDepartmentDataRecursive_Person(treeDept)"
  1787. multiple
  1788. :render-after-expand="false"
  1789. show-checkbox
  1790. style="width: 240px"
  1791. @check-change="handleRreeSelect"
  1792. />
  1793. </el-form-item>
  1794. <el-form-item
  1795. v-else-if="$props.message.assessmentType == 1"
  1796. label="科室"
  1797. label-position="top"
  1798. prop="value1"
  1799. >
  1800. <el-tree-select
  1801. ref="assessmentTypeRef"
  1802. v-model="addPersonParams.value1"
  1803. :data="dpetTree"
  1804. multiple
  1805. check-strictly
  1806. :render-after-expand="false"
  1807. show-checkbox
  1808. style="width: 240px"
  1809. @check-change="handleRreeSelect"
  1810. />
  1811. </el-form-item>
  1812. <el-form-item
  1813. v-else-if="$props.message.assessmentType == 2"
  1814. label="医疗组"
  1815. label-position="top"
  1816. prop="value1"
  1817. >
  1818. <el-select
  1819. ref="selectRefs"
  1820. v-model="addPersonParams.value1"
  1821. multiple
  1822. @change="handChange"
  1823. >
  1824. <el-option
  1825. v-for="(it, id) in treeDeptList"
  1826. :key="id"
  1827. :label="it.groupName"
  1828. :value="it.groupCode"
  1829. />
  1830. </el-select>
  1831. </el-form-item>
  1832. <el-form-item
  1833. v-else-if="$props.message.assessmentType == 3"
  1834. label="人员"
  1835. label-position="top"
  1836. prop="value1"
  1837. >
  1838. <el-select
  1839. ref="selectRefs"
  1840. v-model="addPersonParams.value1"
  1841. multiple
  1842. @change="handChange"
  1843. >
  1844. <el-option
  1845. v-for="(it, id) in treeDeptList"
  1846. :key="id"
  1847. :label="it.realName"
  1848. :value="it.userCode"
  1849. />
  1850. </el-select>
  1851. </el-form-item>
  1852. <el-form-item
  1853. label="考核模板"
  1854. label-position="top"
  1855. prop="modulesValue"
  1856. >
  1857. <el-select
  1858. v-model="addPersonParams.modulesValue"
  1859. @change="handleModulesSelect"
  1860. >
  1861. <el-option
  1862. v-for="itemTmp in modulesList"
  1863. :key="itemTmp.id"
  1864. :label="itemTmp.tpName"
  1865. :value="itemTmp.id"
  1866. />
  1867. </el-select>
  1868. </el-form-item>
  1869. </el-form>
  1870. </div>
  1871. <template #footer>
  1872. <div class="dialog-footer w-full flex justify-between mt-4">
  1873. <div>
  1874. <el-button @click="closePerson">取消</el-button>
  1875. <el-button type="primary" @click="addPerson"> 确认 </el-button>
  1876. </div>
  1877. </div>
  1878. </template>
  1879. </el-dialog>
  1880. </div>
  1881. </template>
  1882. <style lang="scss" scoped>
  1883. .bg-icon {
  1884. display: flex;
  1885. align-items: center;
  1886. justify-content: center;
  1887. width: 45px;
  1888. height: 45px;
  1889. margin-right: 5px;
  1890. background: #00a870;
  1891. border-radius: 5px;
  1892. div {
  1893. // border: 1px solid red;
  1894. display: flex;
  1895. align-items: center;
  1896. justify-content: center;
  1897. width: 60%;
  1898. height: 60%;
  1899. color: #00a870;
  1900. background: #fff;
  1901. border-radius: 2px;
  1902. }
  1903. }
  1904. </style>