|
@@ -1,138 +1,3 @@
|
|
|
-<!-- <template>
|
|
|
- <vxe-table
|
|
|
- border
|
|
|
- style="width: 100%"
|
|
|
- :data="tableData"
|
|
|
- show-overflow
|
|
|
- show-header-overflow
|
|
|
- show-footer-overflow
|
|
|
- :column-config="{ resizable: true }"
|
|
|
- :scroll-x="{ enabled: true, gt: 0 }"
|
|
|
- :merge-cells="mergeCells"
|
|
|
- >
|
|
|
- <vxe-column field="index" title="排名" width="80" fixed="left">
|
|
|
- <template #default="scope">
|
|
|
- <div
|
|
|
- v-if="scope._rowIndex == 0"
|
|
|
- class="text-center text-sm font-extrabold text-[#000000] pt-4"
|
|
|
- >
|
|
|
- 平均得分
|
|
|
- </div>
|
|
|
- <div v-if="scope._rowIndex > 3" class="diamond">
|
|
|
- {{ scope.row.ranking }}
|
|
|
- </div>
|
|
|
- <div v-else class="text-center">
|
|
|
- <img :src="RANK_IMG[scope.row.ranking - 1]" alt="" />
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </vxe-column>
|
|
|
- <vxe-column
|
|
|
- v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'"
|
|
|
- field="deptName"
|
|
|
- :title="tabTitle"
|
|
|
- fixed="left"
|
|
|
- width="150"
|
|
|
- />
|
|
|
- <vxe-column
|
|
|
- v-else
|
|
|
- field="assessmentObjectName"
|
|
|
- :title="deptName"
|
|
|
- fixed="left"
|
|
|
- width="150"
|
|
|
- />
|
|
|
- <vxe-column
|
|
|
- v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'"
|
|
|
- field="assessmentObjectName"
|
|
|
- fixed="left"
|
|
|
- title="姓名"
|
|
|
- width="100"
|
|
|
- />
|
|
|
- <template v-for="(ita, itk) in tableData" :key="itk">
|
|
|
- <template v-for="item in ita.dimensionList" :key="item.dimId">
|
|
|
- <vxe-colgroup
|
|
|
- :title="`${item.dimName}(${soreRate(item.soreRate)}%)`"
|
|
|
- width="150"
|
|
|
- >
|
|
|
- <template v-for="it in item.quotaList" :key="it.quotaId">
|
|
|
- <vxe-column
|
|
|
- :field="it.quotaScore"
|
|
|
- :title="`${it.quotaName}(${soreRate(it.quotaWeight)}%)`"
|
|
|
- width="150"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </vxe-colgroup>
|
|
|
- <vxe-column field="totalSore" title="总分" width="150" />
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- <vxe-column field="allScore" title="总得分" fixed="right" width="150" />
|
|
|
- </vxe-table>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script lang="ts" setup>
|
|
|
-import { computed, reactive, ref, onMounted } from "vue";
|
|
|
-import rank1 from "@/assets/rank/rank1.png";
|
|
|
-import rank2 from "@/assets/rank/rank2.png";
|
|
|
-import rank3 from "@/assets/rank/rank3.png";
|
|
|
-import { useRoute } from "vue-router";
|
|
|
-const $route = useRoute();
|
|
|
-const RANK_IMG = [rank1, rank2, rank3];
|
|
|
-const deptName = ref("");
|
|
|
-const name = ref("");
|
|
|
-const tableData = ref();
|
|
|
-const tabTitle = ref("");
|
|
|
-const mergeCells = ref([
|
|
|
- // 合并第一行前两列
|
|
|
- { row: 0, col: 0, rowspan: 1, colspan: 2 },
|
|
|
- { row: 2, col: 1, rowspan: 0, colspan: 0 }
|
|
|
-]);
|
|
|
-onMounted(() => {
|
|
|
- cellTable();
|
|
|
-});
|
|
|
-const cellTable = () => {
|
|
|
- // if ($route.name == "workerRank") {
|
|
|
- // mergeCells.value = [
|
|
|
- // { row: 0, col: 0, rowspan: 1, colspan: 3 },
|
|
|
- // { row: 2, col: 1, rowspan: 1, colspan: 3 }
|
|
|
- // ];
|
|
|
- // }
|
|
|
- if ($route.name == "healthDrank" || $route.name == "healthRank") {
|
|
|
- tabTitle.value = "医疗组";
|
|
|
- } else {
|
|
|
- tabTitle.value = "科室";
|
|
|
- }
|
|
|
-};
|
|
|
-const averageData = averageSore => {
|
|
|
- if ($route.name != "workerDrak" || $route.name != "workerRank") {
|
|
|
- if (tableData.value.length > 0) {
|
|
|
- tableData.value.unshift({
|
|
|
- dimensionList: [],
|
|
|
- allScore: averageSore
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-const init = (item, deptNames, names) => {
|
|
|
- tableData.value = item;
|
|
|
- deptName.value = deptNames;
|
|
|
- name.value = names;
|
|
|
- if ($route.name != "workerDrak") {
|
|
|
- averageData(item.averageSore);
|
|
|
- }
|
|
|
- console.log("tableData.value", tableData.value);
|
|
|
- console.log("deptName.value", item);
|
|
|
-};
|
|
|
-const soreRate = row => {
|
|
|
- if (row) {
|
|
|
- return row;
|
|
|
- } else {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-};
|
|
|
-defineExpose({
|
|
|
- init
|
|
|
-});
|
|
|
-</script> -->
|
|
|
-
|
|
|
<template>
|
|
|
<div class="w-full aa">
|
|
|
<vxe-button class="float-right -top-10 mr-20 mb-4" @click="exportEvent"
|
|
@@ -144,7 +9,6 @@ defineExpose({
|
|
|
ref="gridRef"
|
|
|
class="mt-10"
|
|
|
:merge-cells="mergeCells"
|
|
|
- @sortChange="changeSort"
|
|
|
>
|
|
|
<template #imgUrl_default="{ row }">
|
|
|
<div>
|
|
@@ -164,13 +28,7 @@ defineExpose({
|
|
|
{{ row.allScore }}
|
|
|
</template>
|
|
|
</vxe-grid>
|
|
|
- <vxe-grid
|
|
|
- v-else
|
|
|
- v-bind="gridOptions"
|
|
|
- ref="gridRef1"
|
|
|
- class="mt-10"
|
|
|
- @sortChange="changeSort"
|
|
|
- >
|
|
|
+ <vxe-grid v-else v-bind="gridOptions" ref="gridRef1" class="mt-10">
|
|
|
<template #imgUrl_default="{ row }">
|
|
|
<div v-if="row.ranking <= 3" class="text-center">
|
|
|
<img class="mt-auto" :src="RANK_IMG[Number(row.ranking) - 1]" />
|
|
@@ -261,81 +119,12 @@ const init = (item, deptNames, names) => {
|
|
|
defineExpose({
|
|
|
init
|
|
|
});
|
|
|
-
|
|
|
-// 排序状态
|
|
|
-const gridEvents = {
|
|
|
- sortChange({ column, order }) {
|
|
|
- if (!column || !order) {
|
|
|
- gridOptions.data = [...originalData.value]; // 恢复到原始数据
|
|
|
- } else {
|
|
|
- const sortedData = [...originalData.value];
|
|
|
- // 先将所有 isAverageRow 为 true 的行提取出来
|
|
|
- const averageRows = sortedData.filter(item => item.isAverageRow);
|
|
|
- const otherRows = sortedData.filter(item => !item.isAverageRow);
|
|
|
-
|
|
|
- // 对其他数据进行排序
|
|
|
- otherRows.sort((a, b) => {
|
|
|
- const field = column.field;
|
|
|
- const aValue = a[field];
|
|
|
- const bValue = b[field];
|
|
|
-
|
|
|
- // 根据正序倒序来决定排序规则
|
|
|
- if (order === "ascending") {
|
|
|
- return aValue > bValue ? 1 : aValue < bValue ? -1 : 0;
|
|
|
- } else if (order === "descending") {
|
|
|
- return aValue < bValue ? 1 : aValue > bValue ? -1 : 0;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- });
|
|
|
-
|
|
|
- // 将排序后的数据与平均分行数据合并,平均分行始终放在最前面
|
|
|
- gridOptions.data = [...averageRows, ...otherRows];
|
|
|
-
|
|
|
- // 使用深拷贝确保数据变化被检测到
|
|
|
- nextTick(() => {
|
|
|
- if (gridRef.value) {
|
|
|
- // 使用 loadData 传递深拷贝的数据
|
|
|
- gridRef.value.loadData([...averageRows, ...otherRows]);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-function changeSort({ column, order }) {
|
|
|
- if (!column || !order) {
|
|
|
- gridOptions.data = [...originalData.value]; // 恢复到原始数据
|
|
|
- } else {
|
|
|
- const sortedData = [...originalData.value];
|
|
|
- // 先将所有 isAverageRow 为 true 的行提取出来
|
|
|
- const averageRows = sortedData.filter(item => item.isAverageRow);
|
|
|
- const otherRows = sortedData.filter(item => !item.isAverageRow);
|
|
|
-
|
|
|
- // 对其他数据进行排序
|
|
|
- otherRows.sort((a, b) => {
|
|
|
- const field = column.field;
|
|
|
- const aValue = a[field];
|
|
|
- const bValue = b[field];
|
|
|
-
|
|
|
- // 根据正序倒序来决定排序规则
|
|
|
- if (order === "ascending") {
|
|
|
- return aValue > bValue ? 1 : aValue < bValue ? -1 : 0;
|
|
|
- } else if (order === "descending") {
|
|
|
- return aValue < bValue ? 1 : aValue > bValue ? -1 : 0;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- });
|
|
|
-
|
|
|
- // 将排序后的数据与平均分行数据合并,平均分行始终放在最前面
|
|
|
- gridOptions.data = [...averageRows, ...otherRows];
|
|
|
- console.log("132131排序", [...averageRows, ...otherRows]);
|
|
|
- // 使用深拷贝确保数据变化被检测到
|
|
|
- nextTick(() => {
|
|
|
- if (gridRef.value) {
|
|
|
- // 使用 loadData 传递深拷贝的数据
|
|
|
- gridRef.value.loadData([...averageRows, ...otherRows]);
|
|
|
- }
|
|
|
- });
|
|
|
+// 判断key值是否相同返回具体值
|
|
|
+function getValueByKey(obj, key) {
|
|
|
+ if (key in obj) {
|
|
|
+ return obj[key];
|
|
|
}
|
|
|
+ return null; // 如果 key 不存在则返回 null
|
|
|
}
|
|
|
|
|
|
// 生成动态表头
|
|
@@ -368,7 +157,24 @@ const createColumns = () => {
|
|
|
sortable: true,
|
|
|
width: 150,
|
|
|
fixed: "right", // 将此列固定在右侧
|
|
|
- slots: { default: "dim-allScore" }
|
|
|
+ slots: { default: "dim-allScore" },
|
|
|
+ sortBy({ column, row }) {
|
|
|
+ // 如果是平均行(isAverageRow为true),则返回一个很大的值,避免被排序
|
|
|
+ if (column.field in row && typeof row[column.field] === "number") {
|
|
|
+ if (column.order == "asc") {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return -9999999999;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return 99999999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return -9999999999;
|
|
|
+ }
|
|
|
+ return row.allScore; // 返回正常的得分,进行排序
|
|
|
+ }
|
|
|
}
|
|
|
];
|
|
|
} else {
|
|
@@ -392,7 +198,24 @@ const createColumns = () => {
|
|
|
width: 150,
|
|
|
sortable: true,
|
|
|
fixed: "right", // 将此列固定在右侧
|
|
|
- slots: { default: "dim-allScore" }
|
|
|
+ slots: { default: "dim-allScore" },
|
|
|
+ sortBy({ column, row }) {
|
|
|
+ // 如果是平均行(isAverageRow为true),则返回一个很大的值,避免被排序
|
|
|
+ if (column.field in row && typeof row[column.field] === "number") {
|
|
|
+ if (column.order == "asc") {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return -9999999999;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return 99999999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return -9999999999;
|
|
|
+ }
|
|
|
+ return row.allScore; // 返回正常的得分,进行排序
|
|
|
+ }
|
|
|
}
|
|
|
];
|
|
|
}
|
|
@@ -428,7 +251,38 @@ const createColumns = () => {
|
|
|
title: `${quota.quotaName} (${quota.quotaWeight}%)`, // 在 title 后拼接 quotaWeight
|
|
|
width: 120,
|
|
|
sortable: true,
|
|
|
- field: `${dimName}_${quota.quotaName}` // 确保字段唯一
|
|
|
+ field: `${dimName}_${quota.quotaName}`, // 确保字段唯一
|
|
|
+ sortBy({ column, row }) {
|
|
|
+ // 如果是平均行(isAverageRow为true),则返回一个很大的值,避免被排序
|
|
|
+ let aa = Number(row[column.field]);
|
|
|
+ if (typeof aa === "number" && !isNaN(aa)) {
|
|
|
+ if (column.order == "asc") {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return -9999999999;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return 99999999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 倒序在最后
|
|
|
+ if (column.order == "asc") {
|
|
|
+ if (!row.isAverageRow) {
|
|
|
+ return 9999999999999;
|
|
|
+ } else {
|
|
|
+ return -999999999999;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!row.isAverageRow) {
|
|
|
+ return -999999999999;
|
|
|
+ } else {
|
|
|
+ return 999999999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return getValueByKey(row, column.field); // 返回正常的得分,进行排序
|
|
|
+ }
|
|
|
}));
|
|
|
|
|
|
// 添加维度名称及其对应的子列
|
|
@@ -442,7 +296,38 @@ const createColumns = () => {
|
|
|
title: `总分`, // 可根据需要调整标题
|
|
|
field: `${dimName}_totalSore`,
|
|
|
width: 120,
|
|
|
- sortable: true
|
|
|
+ sortable: true,
|
|
|
+ sortBy({ column, row }) {
|
|
|
+ // 如果是平均行(isAverageRow为true),则返回一个很大的值,避免被排序
|
|
|
+ let aa = Number(row[column.field]);
|
|
|
+ if (typeof aa === "number" && !isNaN(aa)) {
|
|
|
+ if (column.order == "asc") {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return -9999999999;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (row.isAverageRow) {
|
|
|
+ return 99999999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 倒序在最后
|
|
|
+ if (column.order == "asc") {
|
|
|
+ if (!row.isAverageRow) {
|
|
|
+ return 9999999999999;
|
|
|
+ } else {
|
|
|
+ return -999999999999;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!row.isAverageRow) {
|
|
|
+ return -999999999999;
|
|
|
+ } else {
|
|
|
+ return 999999999999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return getValueByKey(row, column.field); // 返回正常的得分,进行排序
|
|
|
+ }
|
|
|
});
|
|
|
});
|
|
|
gridOptions.columns = columns;
|