Эх сурвалжийг харах

feat: 人员数据统计折线图

chenhao 2 жил өмнө
parent
commit
a592799c78

+ 3 - 2
src/modules/analysis/marking-progress/components/TotalProgress.vue

@@ -47,6 +47,7 @@
 /** 评卷进度 */
 import { reactive, watch, computed, ref } from 'vue'
 import VueECharts from 'vue-echarts'
+import { minus } from '@/utils/common'
 import BaseForm from '@/components/element/BaseForm.vue'
 import BaseTable from '@/components/element/BaseTable.vue'
 import SvgIcon from '@/components/common/SvgIcon.vue'
@@ -122,7 +123,7 @@ const totalColumns: EpTableColumn<TotalProgress>[] = [
     align: 'center',
     width: usePX(100),
     formatter(row) {
-      return `${row.totalPaper - row.finishCount}`
+      return `${minus(row.totalPaper, row.finishCount)}`
     },
   },
   {
@@ -130,7 +131,7 @@ const totalColumns: EpTableColumn<TotalProgress>[] = [
     align: 'center',
     width: usePX(72),
     formatter(row) {
-      return `${parseFloat((100 - row.finishRate).toFixed(2))}%`
+      return `${minus(100, row.finishRate)}%`
     },
   },
   {

+ 4 - 4
src/modules/analysis/personnel-statistics/components/StatisticsGroup.vue

@@ -141,7 +141,7 @@ const groupSubjectiveChartsOption = computed<EChartsOption>(() => {
       axisLabel: {
         align: 'right',
       },
-      data: getXAxisData('count', subjectiveByGroup?.value?.segmentsByGroup),
+      data: getXAxisData('scoreStart', subjectiveByGroup?.value?.segmentsByAll),
     },
     yAxis: [
       {
@@ -192,7 +192,7 @@ const groupObjectiveChartsOption = computed<EChartsOption>(() => {
       axisLabel: {
         align: 'right',
       },
-      data: getXAxisData('count', subjectiveByGroup?.value?.segmentsByGroup),
+      data: getXAxisData('scoreStart', objectiveByGroup?.value?.segmentsByGroup),
     },
     yAxis: [
       {
@@ -214,7 +214,7 @@ const groupObjectiveChartsOption = computed<EChartsOption>(() => {
         itemStyle: {
           color: '#3AD500',
         },
-        data: getXAxisData('rate', subjectiveByGroup?.value?.segmentsByGroup),
+        data: getXAxisData('rate', objectiveByGroup?.value?.segmentsByGroup),
       },
       {
         name: '题组客观分布',
@@ -223,7 +223,7 @@ const groupObjectiveChartsOption = computed<EChartsOption>(() => {
         itemStyle: {
           color: '#0064FF',
         },
-        data: getXAxisData('rate', subjectiveByGroup?.value?.segmentsByAll),
+        data: getXAxisData('rate', objectiveByGroup?.value?.segmentsByAll),
       },
     ],
   }

+ 180 - 6
src/modules/analysis/personnel-statistics/components/StatisticsPersonnel.vue

@@ -1,6 +1,14 @@
 <template>
   <div class="p-small radius-base fill-blank">
-    <base-table size="small" :data="data" :columns="columns" :height="useVW(300)">
+    <base-table
+      ref="tableRef"
+      size="small"
+      :data="tableData"
+      :columns="columns"
+      :height="useVW(300)"
+      highlight-current-row
+      @current-change="onCurrentChange"
+    >
       <template #column-marker="{ row }">
         <el-popover
           :ref="(popover: any) => setPopoverRefs(row.markerId,popover)"
@@ -27,10 +35,10 @@
   </div>
   <div class="flex justify-between m-t-base">
     <div class="flex-1 p-base radius-base fill-blank m-r-base chart-box">
-      <vue-e-charts class="full"></vue-e-charts>
+      <vue-e-charts class="full" :option="markerSubjectiveChartsOption"></vue-e-charts>
     </div>
     <div class="flex-1 p-base radius-base fill-blank chart-box">
-      <vue-e-charts class="full"></vue-e-charts>
+      <vue-e-charts class="full" :option="markerObjectiveChartsOption"></vue-e-charts>
     </div>
   </div>
   <set-workload v-model="setWorkloadVisible" :data="setWorkloadData" />
@@ -38,18 +46,24 @@
 
 <script setup lang="tsx" name="StatisticsPersonnel">
 /** 人员数据统计-按人员展开 */
-import { reactive, ref, inject } from 'vue'
+import { reactive, ref, inject, computed, watch } from 'vue'
 import { ElButton, ElPopover, ElMenu, ElMenuItem } from 'element-plus'
 import VueECharts from 'vue-echarts'
 import BaseTable from '@/components/element/BaseTable.vue'
 import SetWorkload from './SetWorkload.vue'
 import useVW, { usePX } from '@/hooks/useVW'
+import useFetch from '@/hooks/useFetch'
+import useTableCheck from '@/hooks/useTableCheck'
 
-import type { ExtractApiResponse } from 'api-type'
+import type { EChartsOption } from 'echarts'
+import type { ExtractApiResponse, ExtractApiParams } from 'api-type'
 import type { EpTableColumn } from 'global-type'
 import type { PopoverInstance } from 'element-plus'
 
-defineProps<{ data: ExtractApiResponse<'getStatisticsByGroup'> }>()
+const props = defineProps<{
+  data: ExtractApiResponse<'getStatisticsByGroup'>
+  params: ExtractApiParams<'getStatisticsByGroup'> & { expand: boolean }
+}>()
 
 const setMessageVisible = inject<(visible: boolean) => void>('setMessageVisible')
 const setReplyUserId = inject<(id: number) => void>('setReplyUserId')
@@ -123,6 +137,166 @@ function onSendMessage(data: ExtractArrayValue<ExtractApiResponse<'getStatistics
   setReplyUserId?.(data.markerId)
   setMessageVisible?.(true)
 }
+
+const data = computed(() => {
+  return props.data || []
+})
+
+const { tableRef, tableData, current, onCurrentChange } = useTableCheck(data)
+
+const { fetch: getStatisticObjectiveByMarker, result: objectiveByMarker } = useFetch('getStatisticObjectiveByMarker')
+const { fetch: getStatisticSubjectiveByMarker, result: subjectiveByMarker } = useFetch('getStatisticSubjectiveByMarker')
+
+watch(
+  [() => props.params, current],
+  () => {
+    const { startTime = '', endTime = '' } = props.params || {}
+    if (current.value?.markerId) {
+      getStatisticObjectiveByMarker({
+        markerId: current.value.markerId,
+        startTime,
+        endTime,
+      })
+      getStatisticSubjectiveByMarker({
+        markerId: current.value.markerId,
+        startTime,
+        endTime,
+      })
+    }
+  },
+  { immediate: true, deep: true }
+)
+
+type StatisticObjectiveByMarker = ExtractApiResponse<'getStatisticObjectiveByMarker'>
+
+type StatisticObjectiveByMarkerValues = StatisticObjectiveByMarker['segmentsByAll']
+
+const getXAxisData = <K extends keyof ExtractArrayValue<StatisticObjectiveByMarkerValues>>(
+  field: K,
+  data?: StatisticObjectiveByMarkerValues
+) => {
+  if (!data) {
+    return []
+  }
+  const getValue = (key: K, item: ExtractArrayValue<StatisticObjectiveByMarkerValues>) => {
+    return item[key]
+  }
+  return data?.map((v) => getValue(field, v))
+}
+
+const markerSubjectiveChartsOption = computed<EChartsOption>(() => {
+  return {
+    legend: {
+      right: 0,
+      itemWidth: 14,
+      data: ['评卷员主观分布', '小组主观分布', '题组主观分布'],
+    },
+    xAxis: {
+      axisLine: { show: false },
+      axisTick: { show: false },
+      splitLine: { show: false },
+      axisLabel: {
+        align: 'right',
+      },
+      data: getXAxisData('scoreStart', subjectiveByMarker?.value?.segmentsByAll),
+    },
+    yAxis: [
+      {
+        type: 'value',
+      },
+      {
+        type: 'value',
+        axisLabel: {
+          formatter: `{value}%`,
+        },
+        splitLine: { show: false },
+      },
+    ],
+    series: [
+      {
+        name: '评卷员主观分布',
+        type: 'line',
+        itemStyle: {
+          color: '#3AD500',
+        },
+        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByUser),
+      },
+      {
+        name: '小组主观分布',
+        type: 'line',
+        itemStyle: {
+          color: '#0064FF',
+        },
+        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByGroup),
+      },
+      {
+        name: '题组主观分布',
+        type: 'line',
+        itemStyle: {
+          color: '#008000',
+        },
+        data: getXAxisData('rate', subjectiveByMarker?.value?.segmentsByAll),
+      },
+    ],
+  }
+})
+
+const markerObjectiveChartsOption = computed<EChartsOption>(() => {
+  return {
+    legend: {
+      right: 0,
+      itemWidth: 14,
+      data: ['评卷员客观分布', '小组客观分布', '题组客观分布'],
+    },
+    xAxis: {
+      axisLine: { show: false },
+      axisTick: { show: false },
+      splitLine: { show: false },
+      axisLabel: {
+        align: 'right',
+      },
+      data: getXAxisData('scoreStart', objectiveByMarker?.value?.segmentsByAll),
+    },
+    yAxis: [
+      {
+        type: 'value',
+      },
+      {
+        type: 'value',
+        axisLabel: {
+          formatter: `{value}%`,
+        },
+        splitLine: { show: false },
+      },
+    ],
+    series: [
+      {
+        name: '评卷员客观分布',
+        type: 'line',
+        itemStyle: {
+          color: '#3AD500',
+        },
+        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByUser),
+      },
+      {
+        name: '小组客观分布',
+        type: 'line',
+        itemStyle: {
+          color: '#0064FF',
+        },
+        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByGroup),
+      },
+      {
+        name: '题组客观分布',
+        type: 'line',
+        itemStyle: {
+          color: '#008000',
+        },
+        data: getXAxisData('rate', objectiveByMarker?.value?.segmentsByAll),
+      },
+    ],
+  }
+})
 </script>
 
 <style scoped lang="scss">