workerRank.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <script setup lang="ts">
  2. defineOptions({
  3. name: "AssessmentRank"
  4. });
  5. import { ref, onMounted } from "vue";
  6. import { Search } from "@element-plus/icons-vue";
  7. import {
  8. getAssessmentPageList,
  9. getPageScoreInfoByAssessment
  10. } from "@/api/manage";
  11. import { ElMessage } from "element-plus";
  12. import { useRouter } from "vue-router";
  13. import { useAppStoreHook } from "@/store/modules/app";
  14. // 考核活动点击交互
  15. const activityList: any = ref([]);
  16. const activeActivity = ref(0);
  17. const handleActiveActivity = (item: any, index: number) => {
  18. activeActivity.value = index;
  19. getPageScoreInfoByAssessmentApi(item);
  20. };
  21. // 考核活动数据
  22. const getAssessmentPageListApi = async (name = "") => {
  23. const params: {
  24. pageNumber: number;
  25. pageSize: number;
  26. assessmentType: number;
  27. name?: string;
  28. } = {
  29. pageNumber: 1,
  30. pageSize: 999999,
  31. assessmentType: 0 // 0:员工,1:部门,2:医疗组,3:部门负责人
  32. };
  33. if (name) {
  34. params.name = name;
  35. }
  36. const { code, msg, data } = await getAssessmentPageList(params);
  37. if (code === 200) {
  38. activityList.value = data.records || [];
  39. if (activityList.value && activityList.value.length) {
  40. handleActiveActivity(activityList.value[0], 0);
  41. }
  42. } else {
  43. ElMessage.error(msg);
  44. }
  45. };
  46. onMounted(() => {
  47. getAssessmentPageListApi();
  48. });
  49. const handleSearch = () => {
  50. getAssessmentPageListApi(searchKeyword.value);
  51. };
  52. // 右侧列表
  53. const searchKeyword = ref("");
  54. const averageScore = ref<number | string>(0);
  55. const tableData = ref<any>([]);
  56. const getPageScoreInfoByAssessmentApi = async (obj: any = {}) => {
  57. const params = {
  58. assessmentId: obj.id,
  59. assessmentType: `${obj.assessmentType}`
  60. };
  61. const { code, msg, data = [] } = await getPageScoreInfoByAssessment(params);
  62. if (code === 200) {
  63. tableData.value = data;
  64. if (tableData.value.length) {
  65. let allCount = 0;
  66. tableData.value.forEach(item => {
  67. allCount += item.score ? Number(item.score) : 0;
  68. });
  69. let resultNum: number | string = allCount / tableData.value.length;
  70. if (
  71. resultNum.toString().split(".")[1] &&
  72. resultNum.toString().split(".")[1].length > 3
  73. ) {
  74. resultNum = resultNum.toFixed(3);
  75. }
  76. averageScore.value = resultNum;
  77. }
  78. } else {
  79. tableData.value = [];
  80. }
  81. };
  82. // 跳转到数据明细
  83. const router = useRouter();
  84. const toDetail = (row: any = {}) => {
  85. router.push({
  86. path: "/draw/children/worker/dataDetail",
  87. query: {
  88. mid: row.templateId,
  89. id: activityList.value[activeActivity.value].id,
  90. mname: row.templateName,
  91. name: activityList.value[activeActivity.value].name
  92. }
  93. });
  94. useAppStoreHook().toggleSideBar(false, "关闭");
  95. };
  96. </script>
  97. <template>
  98. <div class="assessment-rank flex">
  99. <div class="search-section mr-4">
  100. <el-input
  101. v-model="searchKeyword"
  102. placeholder="考核活动名称"
  103. class="w-64"
  104. :suffix-icon="Search"
  105. clearable
  106. @keyup.enter="handleSearch"
  107. />
  108. <div class="search-section-list">
  109. <p
  110. v-for="(item, index) in activityList"
  111. :key="item.id"
  112. class="mt-4 cursor-pointer overflow-hidden text-ellipsis whitespace-nowrap"
  113. :style="{ color: activeActivity === index ? '#0052d9' : '#333' }"
  114. @click="handleActiveActivity(item, index)"
  115. >
  116. {{ item.name }}
  117. </p>
  118. </div>
  119. </div>
  120. <el-card class="w-full">
  121. <template #header>
  122. <div class="flex justify-between items-center">
  123. <span class="text-base font-medium">平均得分: </span>
  124. <span>{{ averageScore }}</span>
  125. </div>
  126. </template>
  127. <el-table :data="tableData" style="width: 100%" border>
  128. <el-table-column type="index" label="排名" width="80" align="center" />
  129. <el-table-column prop="templateName" label="考核模板" min-width="200">
  130. <template #default="{ row }">
  131. <el-button type="primary" link @click="toDetail(row)">
  132. {{ row.templateName }}
  133. </el-button>
  134. </template>
  135. </el-table-column>
  136. <el-table-column prop="deptName" label="科室" min-width="150" />
  137. <el-table-column prop="userName" label="员工" min-width="150">
  138. <template #default="{ row }">
  139. <el-button type="primary" link @click="toDetail(row)">
  140. {{ row.userName }}
  141. </el-button>
  142. </template>
  143. </el-table-column>
  144. <el-table-column
  145. prop="score"
  146. label="实际得分"
  147. width="120"
  148. align="right"
  149. />
  150. </el-table>
  151. </el-card>
  152. </div>
  153. </template>
  154. <style scoped lang="scss">
  155. .assessment-rank {
  156. padding: 20px 0;
  157. }
  158. .search-section {
  159. flex-shrink: 0;
  160. width: 200px;
  161. .search-section-list {
  162. height: calc(100vh - 250px);
  163. margin-top: 20px;
  164. overflow: auto;
  165. }
  166. }
  167. :deep(.el-card__header) {
  168. padding: 15px 20px;
  169. }
  170. </style>