刘洋 2 жил өмнө
parent
commit
4d6990c13a

+ 2 - 0
package.json

@@ -26,6 +26,7 @@
     "dayjs": "1.11.5",
     "echarts": "5.4.0",
     "element-plus": "2.2.17",
+    "element-resize-detector": "^1.2.4",
     "lodash-es": "4.17.21",
     "mitt": "^3.0.0",
     "pinia": "2.0.23",
@@ -38,6 +39,7 @@
   "devDependencies": {
     "@types/big.js": "^6.1.6",
     "@types/crypto-js": "^4.1.1",
+    "@types/element-resize-detector": "^1.1.3",
     "@types/lodash-es": "^4.17.6",
     "@types/offscreencanvas": "^2019.7.0",
     "@types/splitpanes": "^2.2.1",

+ 28 - 1
src/assets/styles/app.scss

@@ -113,8 +113,35 @@ a {
 
 
 img {
-  pointer-events: none
+  // pointer-events: none
 }
 .splitpanes.default-theme .splitpanes__pane {
   background-color: #fff !important;
+}
+.mark-container{
+  .next-button{
+    z-index:5;
+  }
+}
+.table-view{
+  transition:all .3s;
+  &.collapse{
+    width:0 !important;
+    padding:0 !important;
+    overflow:hidden;
+  }
+  .detail-info-table-header{
+    .detail-info-label{
+      padding-left:5px;
+      padding-right:5px;
+    }
+  }
+  // .detail-info-table-header{
+  //   // flex-direction: column !important;
+  //   text-align:right;
+  //   display:block !important;
+  //   &>.el-pagination{
+  //     margin-top:3px;
+  //   }
+  // }
 }

+ 2 - 2
src/components/shared/MarkHeader.vue

@@ -34,8 +34,8 @@
       </div>
     </div>
 
-    <base-dialog v-model="standardVisible" title="评分标准" width="90vw" center :footer="false">
-      <iframe style="width: 100%; height: calc(100vh - 100px)" :src="standardRes?.url" alt="" />
+    <base-dialog v-model="standardVisible" title="评分标准" width="40vw" center :footer="false">
+      <iframe style="width: 100%; height: 50vh" :src="standardRes?.url" alt="" />
     </base-dialog>
   </div>
 </template>

+ 20 - 2
src/components/shared/RightButton.vue

@@ -1,11 +1,29 @@
 <template>
   <div class="pointer right-button">
-    <svg-icon name="right"></svg-icon>
+    <!-- <svg-icon name="right"></svg-icon> -->
+    <el-icon>
+      <right v-if="showRight" />
+      <back v-else />
+    </el-icon>
   </div>
 </template>
 
 <script setup lang="ts" name="RightButton">
-import SvgIcon from '../common/SvgIcon.vue'
+// import SvgIcon from '../common/SvgIcon.vue'
+import { onMounted, ref } from 'vue'
+import { ElIcon } from 'element-plus'
+import { Right, Back } from '@element-plus/icons-vue'
+import elementResizeDetectorMaker from 'element-resize-detector'
+const showRight = ref(true)
+onMounted(() => {
+  var erd = elementResizeDetectorMaker()
+  erd.listenTo(document.querySelector('.table-view') as HTMLElement, function (element: any) {
+    var width = element.offsetWidth
+    var height = element.offsetHeight
+    console.log('Size: ' + width + 'x' + height)
+    showRight.value = width > 0
+  })
+})
 </script>
 
 <style scoped lang="scss">

+ 6 - 2
src/hooks/useTableCheck.ts

@@ -1,5 +1,5 @@
 import { ref, computed, watch, nextTick, unref } from 'vue'
-import { isDefine } from '@/utils/common'
+import { isDefine, toggleClass } from '@/utils/common'
 
 import type { Ref, ShallowRef, UnwrapRef } from 'vue'
 import type { InstanceTable } from 'global-type'
@@ -76,7 +76,11 @@ const useTableCheck = <T extends TableDataType<InputDataType>>(data: T, auto = t
 
   /** 下一份 */
   const next = () => {
-    elTableRef?.value?.setCurrentRow(tableData.value[((current.value?.index || 0) + 1) % tableData.value.length])
+    // elTableRef?.value?.setCurrentRow(tableData.value[((current.value?.index || 0) + 1) % tableData.value.length])
+    const rightTableViewDom = document.querySelector('.table-view')
+    if (rightTableViewDom) {
+      toggleClass(rightTableViewDom, 'collapse')
+    }
   }
 
   return {

+ 2 - 1
src/modules/analysis/group-monitoring-detail/index.vue

@@ -33,7 +33,8 @@
             background
             right
             hide-on-single-page
-            :pager-count="5"
+            :pager-count="3"
+            small
           ></el-pagination>
         </div>
         <div class="flex-1 scroll-auto">

+ 43 - 18
src/modules/analysis/marking-progress/components/TotalProgress.vue

@@ -3,15 +3,10 @@
     <base-form size="small" :model="model" :items="items"></base-form>
     <div class="total-progress-info">
       <div class="p-t-base p-b-extra-small table-title">整体进度</div>
-      <div
-        v-if="canLoadTopChart"
-        class="p-t-small p-b-extra-small overflow-hidden chart-info"
-        :style="{ height: topChartHeight + 'px' }"
-      >
-        <vue-e-charts class="full" :option="totalChartsOption" autoresize></vue-e-charts>
-      </div>
-      <div class="m-t-base">
+
+      <div class="flex m-t-base">
         <base-table
+          class="left-table"
           border
           stripe
           size="small"
@@ -22,6 +17,13 @@
         >
           <template #empty>暂无数据</template>
         </base-table>
+        <div
+          v-if="canLoadTopChart"
+          class="p-b-extra-small overflow-hidden chart-info flex-1"
+          :style="{ height: topChartHeight + 'px' }"
+        >
+          <vue-e-charts class="full" :option="totalChartsOption" autoresize></vue-e-charts>
+        </div>
       </div>
     </div>
   </div>
@@ -103,12 +105,14 @@ const totalColumns: EpTableColumn<TotalProgress>[] = [
   {
     label: '大题',
     formatter: getMainName,
+    fixed: 'left',
   },
-  { label: '试卷总量', prop: 'totalPaper', align: 'center', sortable: true },
-  { label: '已完成', prop: 'finishCount', align: 'center', sortable: true },
+  { label: '试卷总量', prop: 'totalPaper', align: 'center', sortable: true, minWidth: 95 },
+  { label: '已完成', prop: 'finishCount', align: 'center', sortable: true, minWidth: 80 },
   {
     label: '完成比',
     align: 'center',
+    minWidth: 80,
     formatter(row) {
       return `${row.finishRate}%`
     },
@@ -117,6 +121,7 @@ const totalColumns: EpTableColumn<TotalProgress>[] = [
   {
     label: '待完成',
     align: 'center',
+    minWidth: 80,
     formatter(row) {
       return `${minus(row.totalPaper, row.finishCount)}`
     },
@@ -125,6 +130,7 @@ const totalColumns: EpTableColumn<TotalProgress>[] = [
   {
     label: '待完成比',
     align: 'center',
+    minWidth: 95,
     formatter(row) {
       return `${minus(100, row.finishRate)}%`
     },
@@ -133,6 +139,7 @@ const totalColumns: EpTableColumn<TotalProgress>[] = [
   {
     label: '预计耗时(分)',
     align: 'center',
+    minWidth: 120,
     formatter(row) {
       return `${parseFloat((row.takeTime / 60).toFixed(2))}`
     },
@@ -153,7 +160,7 @@ const totalProgressData = computed(() => {
 })
 
 const topChartHeight = computed(() => {
-  return ((markProgressResult.value as any) || []).length * 80 + 1
+  return ((markProgressResult.value as any) || []).length * 44 + 60
 })
 watch(
   () => topChartHeight.value,
@@ -200,8 +207,20 @@ const getYAxisData = (field: keyof TotalProgress | 'name', data?: TotalProgress[
 
 const totalChartsOption = computed<EChartsOption>(() => {
   return {
+    tooltip: {
+      show: true,
+      trigger: 'item',
+      formatter(params: any) {
+        let prev = params.seriesName + '<br />' + params.name + ': ' + params.value
+        if (params.seriesName === '完成比') {
+          return prev + '%'
+        } else {
+          return prev
+        }
+      },
+    },
     grid: {
-      top: 20,
+      top: 26,
       bottom: -20,
       left: 20,
       right: 30,
@@ -209,6 +228,7 @@ const totalChartsOption = computed<EChartsOption>(() => {
     },
     legend: {
       right: 0,
+      top: 0,
       itemWidth: 14,
       data: ['试卷总量', '已完成', '完成比'],
     },
@@ -246,7 +266,7 @@ const totalChartsOption = computed<EChartsOption>(() => {
         barWidth: 11,
         barGap: '-200%',
         itemStyle: {
-          color: '#3AD500',
+          color: '#0064FF',
         },
         data: getYAxisData('totalPaper', markProgressResult?.value),
       },
@@ -256,14 +276,15 @@ const totalChartsOption = computed<EChartsOption>(() => {
         barWidth: 11,
         barGap: '-200%',
         itemStyle: {
-          color: '#0064FF',
+          color: '#3AD500',
         },
         data: getYAxisData('finishCount', markProgressResult?.value),
       },
       {
         name: '完成比',
         type: 'bar',
-        barWidth: 44,
+        // barWidth: 44,
+        barWidth: 11,
         barGap: '-200%',
         showBackground: true,
         xAxisIndex: 1,
@@ -380,7 +401,7 @@ const groupChartsOption = computed<EChartsOption>(() => {
         type: 'bar',
         barWidth: 20,
         itemStyle: {
-          color: '#3AD500',
+          color: '#0064FF',
         },
         data: getXAxisData('finishCount', groupProgressResult?.value),
       },
@@ -389,7 +410,7 @@ const groupChartsOption = computed<EChartsOption>(() => {
         type: 'bar',
         barWidth: 20,
         itemStyle: {
-          color: '#0064FF',
+          color: '#3AD500',
         },
         data: getXAxisData('dayFinishCount', groupProgressResult?.value),
       },
@@ -412,7 +433,11 @@ const groupChartsOption = computed<EChartsOption>(() => {
 
 <style scoped lang="scss">
 .total-progress-box {
-  // height: 323px;
+  height: 323px;
+  .left-table {
+    width: 50%;
+    // flex: 1;
+  }
   .total-progress-info {
     border-top: $OnePixelLine;
     // height: 253px;

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

@@ -7,13 +7,14 @@
       size="small"
       :columns="columns"
       :data="tableData"
-      :height="'300px'"
+      :height="tableHeight"
       highlight-current-row
       @current-change="onCurrentChange"
     >
     </base-table>
   </div>
-  <div class="flex justify-between m-t-base">
+  <div v-if="!!current" v-loading="loading1 || loading2" class="flex justify-between m-t-base charts-box">
+    <el-button type="primary" plain size="small" class="close-panel" @click="clearCheck">关闭</el-button>
     <div class="flex-1 p-mini radius-base fill-blank m-r-base chart-box">
       <vue-e-charts class="full" :option="groupSubjectiveChartsOption"></vue-e-charts>
     </div>
@@ -31,7 +32,7 @@ import VueECharts from 'vue-echarts'
 import useVW, { usePX } from '@/hooks/useVW'
 import useFetch from '@/hooks/useFetch'
 import useTableCheck from '@/hooks/useTableCheck'
-
+import { ElButton } from 'element-plus'
 import type { EChartsOption } from 'echarts'
 import type { ExtractApiResponse, ExtractApiParams } from '@/api/api'
 import type { EpTableColumn } from 'global-type'
@@ -103,10 +104,18 @@ const data = computed(() => {
   return arr
 })
 
-const { tableRef, tableData, current, onCurrentChange } = useTableCheck(data)
+const { tableRef, tableData, current, onCurrentChange, elTableRef } = useTableCheck(data, false)
 
-const { fetch: getStatisticObjectiveByGroup, result: objectiveByGroup } = useFetch('getStatisticObjectiveByGroup')
-const { fetch: getStatisticSubjectiveByGroup, result: subjectiveByGroup } = useFetch('getStatisticSubjectiveByGroup')
+const {
+  fetch: getStatisticObjectiveByGroup,
+  result: objectiveByGroup,
+  loading: loading1,
+} = useFetch('getStatisticObjectiveByGroup')
+const {
+  fetch: getStatisticSubjectiveByGroup,
+  result: subjectiveByGroup,
+  loading: loading2,
+} = useFetch('getStatisticSubjectiveByGroup')
 
 watch(
   [() => props.params, current],
@@ -148,7 +157,12 @@ const getXAxisData = <K extends keyof ExtractArrayValue<StatisticObjectiveByGrou
   }
   return data?.map((v) => getValue(field, v))
 }
-
+const tableHeight = computed(() => {
+  return !!current.value ? 'calc(100vh - 520px)' : 'calc(100vh - 219px)'
+})
+const clearCheck = () => {
+  ;(elTableRef as any).value!.setCurrentRow(undefined)
+}
 const groupSubjectiveChartsOption = computed<EChartsOption>(() => {
   return {
     legend: {
@@ -256,4 +270,14 @@ const groupObjectiveChartsOption = computed<EChartsOption>(() => {
 .chart-box {
   height: 293px;
 }
+.charts-box {
+  position: relative;
+  .close-panel {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translateX(-50%) translateY(-50%);
+    z-index: 1;
+  }
+}
 </style>

+ 4 - 2
src/modules/analysis/view-marked-detail/index.vue

@@ -49,7 +49,8 @@
             background
             right
             hide-on-single-page
-            :pager-count="5"
+            :pager-count="3"
+            small
           ></el-pagination>
         </div>
         <div class="flex-1 scroll-auto">
@@ -233,7 +234,8 @@ onRefresh()
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
 
     .marker-name {
       border-bottom: $OnePixelLine;

+ 2 - 1
src/modules/expert/assess/index.vue

@@ -265,7 +265,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/expert/expert/index.vue

@@ -329,7 +329,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/expert/sample/index.vue

@@ -248,7 +248,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/expert/standard/index.vue

@@ -229,7 +229,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/expert/training/index.vue

@@ -216,7 +216,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 3 - 1
src/modules/marking/arbitration/index.vue

@@ -167,6 +167,7 @@ const formItems = computed<EpFormItem[]>(() => [
     label: '状态',
     prop: 'status',
     slotType: 'select',
+    labelWidth: '58px',
     slot: {
       options: [
         { label: '已给分', value: 'GRADED' },
@@ -268,7 +269,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 4 - 2
src/modules/marking/inquiry-result/index.vue

@@ -44,7 +44,8 @@
             background
             right
             hide-on-single-page
-            :pager-count="5"
+            :pager-count="3"
+            small
           ></el-pagination>
         </div>
         <div class="flex-1 scroll-auto m-t-mini">
@@ -369,7 +370,8 @@ onRefresh()
   //   }
   // }
   .table-view {
-    width: 620px;
+    // width: 620px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 3 - 1
src/modules/marking/problem/index.vue

@@ -199,6 +199,7 @@ const formItems = computed<EpFormItem[]>(() => [
     label: '状态',
     prop: 'status',
     slotType: 'select',
+    labelWidth: '58px',
     slot: {
       options: [
         { label: '未处理', value: 'INITIAL' },
@@ -308,7 +309,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 480px;
+    // width: 480px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 3 - 2
src/modules/marking/repeat/index.vue

@@ -177,7 +177,7 @@ const formItems = computed<EpFormItem[]>(() => [
   span10({
     rowKey: 'row-1',
     label: '状态',
-    labelWidth: '40px',
+    labelWidth: '46px',
     prop: 'confirm',
     slotType: 'select',
     slot: {
@@ -283,7 +283,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 480px;
+    // width: 480px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 3 - 2
src/modules/marking/similar/index.vue

@@ -113,7 +113,7 @@ const formItems = computed<EpFormItem[]>(() => [
   span10({
     rowKey: 'row-1',
     label: '雷同判定',
-    labelWidth: '88px',
+    labelWidth: '86px',
     prop: 'status',
     slotType: 'select',
     slot: {
@@ -214,7 +214,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/marking/training-record/index.vue

@@ -161,7 +161,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
   }
 }
 </style>

+ 2 - 1
src/modules/marking/view-sample/index.vue

@@ -139,7 +139,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
   }
 }
 </style>

+ 2 - 1
src/modules/monitor/system-check/index.vue

@@ -318,7 +318,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 480px;
+    // width: 480px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/monitor/training-monitoring-detail/index.vue

@@ -192,7 +192,8 @@ fetchData()
     }
   }
   .table-view {
-    width: 480px;
+    // width: 480px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/quality/self-check-detail/index.vue

@@ -232,7 +232,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 480px;
+    // width: 480px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 2 - 1
src/modules/quality/subjective-check/index.vue

@@ -339,7 +339,8 @@ const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
     }
   }
   .table-view {
-    width: 580px;
+    // width: 580px;
+    width: 35%;
     .detail-info-label {
       .detail-info-label-num {
         min-width: 32px;

+ 10 - 1
src/plugins/echarts.ts

@@ -1,7 +1,14 @@
 import { use } from 'echarts/core'
 import { SVGRenderer, CanvasRenderer } from 'echarts/renderers'
 import { BarChart, LineChart } from 'echarts/charts'
-import { TitleComponent, GridComponent, LegendComponent, MarkLineComponent } from 'echarts/components'
+import {
+  TitleComponent,
+  GridComponent,
+  LegendComponent,
+  MarkLineComponent,
+  ToolboxComponent,
+  TooltipComponent,
+} from 'echarts/components'
 
 const useECharts = () => {
   return use([
@@ -13,6 +20,8 @@ const useECharts = () => {
     GridComponent,
     LegendComponent,
     MarkLineComponent,
+    ToolboxComponent,
+    TooltipComponent,
   ])
 }
 

+ 16 - 0
src/utils/common.ts

@@ -234,3 +234,19 @@ export const transHtmlContent = (content: string) => {
     .replace('&gt;', '>')
     .replace('&nbsp;', ' ')
 }
+
+// 首先判断当前dom是否已经包含了要添加的类
+export function hasClass(el: any, className: string) {
+  const reg = new RegExp('(^|\\s)' + className + '(\\s|$)')
+  return reg.test(el.className)
+}
+// 动态添加class
+export function toggleClass(el: any, className: string) {
+  const newClass = el.className.split(' ')
+  if (hasClass(el, className)) {
+    newClass.splice(newClass.indexOf(className), 1)
+  } else {
+    newClass.push(className)
+  }
+  el.className = newClass.join(' ')
+}