Kaynağa Gözat

feat: 管理端新需求

zhangjie 1 hafta önce
ebeveyn
işleme
59bcd93be6

+ 10 - 0
src/api/analysis.ts

@@ -38,6 +38,16 @@ export function exportTotalAnalysisList(
     { params, responseType: 'blob' }
   );
 }
+// TODO:总量分析总结表导出
+export function exportTotalAnalysisSummaryList(
+  params: AnalysisListFilter
+): Promise<AxiosResponse<Blob>> {
+  return axios.post(
+    '/api/admin/report/subject/export/summary',
+    {},
+    { params, responseType: 'blob' }
+  );
+}
 
 // 分段统计列表
 export function getSegmentAnalysisList(

+ 17 - 0
src/api/mark.ts

@@ -367,3 +367,20 @@ export function getMarkStatList(
 export function markSubjectClose(subjectIds: number[]): Promise<boolean> {
   return axios.post('/api/mark/subject/close', {}, { params: { subjectIds } });
 }
+
+// 导出评卷进度
+export function exportMarkProgress(): Promise<AxiosResponse<Blob>> {
+  return axios.post(
+    '/api/admin/mark/info/export/progress',
+    {},
+    { responseType: 'blob' }
+  );
+}
+// 导出工作量统计
+export function exportMarkWorkload(): Promise<AxiosResponse<Blob>> {
+  return axios.post(
+    '/api/admin/mark/info/export/marker',
+    {},
+    { responseType: 'blob' }
+  );
+}

+ 21 - 17
src/api/types/review.ts

@@ -36,11 +36,13 @@ export type ReviewStatListPageRes = PageResult<ReviewStatItem>;
 
 export interface ReviewStatListFilter {
   // 科目
-  subjectCode: string | null;
+  subjectCode?: string;
   // 选做科目
-  selective: boolean | null;
+  selective?: boolean;
   // 完成进度
-  finished: boolean | null;
+  finished?: boolean;
+  // 复核次数
+  inspectRound?: number;
 }
 export type ReviewStatListPageParams = PageParams<ReviewStatListFilter>;
 
@@ -64,6 +66,20 @@ export interface FullReviewItem {
   totalScore: number;
   // 得分明细
   subjectiveScoreList: string;
+  // 复核轮数
+  inspectHistoryMap?: Record<
+    string,
+    {
+      examId: number;
+      id: number;
+      inspectRound: number;
+      inspectTime: string;
+      inspectorId: number;
+      inspectorName: string;
+      studentId: number;
+      subjectCode: string;
+    }
+  >;
 }
 export type FullReviewListPageRes = PageResult<FullReviewItem>;
 
@@ -74,6 +90,8 @@ export interface FullReviewListFilter {
   selective?: boolean;
   // 状态:已复核、未复核
   inspected?: boolean;
+  // 标记卷
+  marked?: boolean;
   // 学院
   college?: number;
   // 试卷总分
@@ -94,20 +112,6 @@ export interface FullReviewListFilter {
   questionScore?: number;
   // 密号
   secretNumber?: string;
-  // 复核轮数
-  inspectHistoryMap?: Record<
-    string,
-    {
-      examId: number;
-      id: number;
-      inspectRound: number;
-      inspectTime: string;
-      inspectorId: number;
-      inspectorName: string;
-      studentId: number;
-      subjectCode: string;
-    }
-  >;
 }
 export type FullReviewListPageParams = PageParams<FullReviewListFilter>;
 

+ 9 - 0
src/utils/download-export.ts

@@ -25,6 +25,7 @@ import { exportScanStatByPoint, exportScanStatByCourse } from '@/api/scan';
 import { exportRejectStat, exportRejectRecord } from '@/api/reject';
 import { exportIssuePaper } from '@/api/issue-paper';
 import {
+  exportTotalAnalysisSummaryList,
   exportTotalAnalysisList,
   exportSegmentAnalysisList,
   exportCollegeAnalysisList,
@@ -39,6 +40,8 @@ import {
   exportArbitrationList,
   exportMarkTaskList,
   markerImportTemplate,
+  exportMarkProgress,
+  exportMarkWorkload,
 } from '@/api/mark';
 import {
   exportReviewStatList,
@@ -106,6 +109,8 @@ const downloadConfig = {
   // 导出问题卷
   exportIssuePaper,
   // analysis
+  // 总量分析总结表导出
+  exportTotalAnalysisSummaryList,
   // 总量分析导出
   exportTotalAnalysisList,
   // 分段分析导出
@@ -131,6 +136,10 @@ const downloadConfig = {
   exportMarkTaskList,
   // 评卷员导入模板下载
   markerImportTemplate,
+  // 导出评卷进度
+  exportMarkProgress,
+  // 导出工作量统计
+  exportMarkWorkload,
   // review
   // 导出复核进度
   exportReviewStatList,

+ 25 - 11
src/views/analysis/TotalAnalysis.vue

@@ -1,16 +1,22 @@
 <template>
   <div class="part-box is-border">
-    <el-form inline>
-      <el-form-item label="科目">
-        <select-subject v-model="searchModel.subjectCode"></select-subject>
-      </el-form-item>
-      <el-form-item>
-        <el-space wrap>
-          <el-button type="primary" @click="toPage(1)">查询</el-button>
-          <el-button @click="onExport">导出</el-button>
-        </el-space>
-      </el-form-item>
-    </el-form>
+    <div class="box-justify">
+      <el-form inline>
+        <el-form-item label="科目">
+          <select-subject v-model="searchModel.subjectCode"></select-subject>
+        </el-form-item>
+        <el-form-item>
+          <el-space wrap>
+            <el-button type="primary" @click="toPage(1)">查询</el-button>
+            <el-button @click="onExport">导出</el-button>
+            <el-button @click="onExportSummary">导出总结表</el-button>
+          </el-space>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button @click="onRefresh">刷新</el-button>
+      </div>
+    </div>
     <el-divider class="form-divider" />
 
     <el-table
@@ -82,4 +88,12 @@
   async function onExport() {
     await downloadExport('exportTotalAnalysisList', searchModel);
   }
+
+  async function onExportSummary() {
+    await downloadExport('exportTotalAnalysisSummaryList', searchModel);
+  }
+
+  async function onRefresh() {
+    // TODO: 刷新数据
+  }
 </script>

+ 21 - 2
src/views/mark/GroupManage.vue

@@ -6,10 +6,10 @@
       </el-form-item>
     </el-form>
     <el-divider class="form-divider" />
-    <div class="part-action">
+    <div class="part-action box-justify">
       <el-space wrap>
         <el-button type="primary" @click="toPage(1)">查询</el-button>
-        <el-button @click="onAdd">新增</el-button>
+        <el-button type="success" @click="onAdd">新增</el-button>
         <el-button :disabled="checkLoading" @click="onDataCheck"
           >数量校对</el-button
         >
@@ -18,6 +18,11 @@
         >
         <el-button @click="onSetTrialCount">设置试评数量</el-button>
       </el-space>
+      <div>
+        <el-tooltip effect="dark" content="预览所有试卷" placement="top">
+          <el-button class="is-shade">全卷预览</el-button>
+        </el-tooltip>
+      </div>
     </div>
 
     <el-table
@@ -68,6 +73,14 @@
       <el-table-column prop="status" label="状态" width="80" />
       <el-table-column label="操作" width="120" fixed="right">
         <template #default="scope">
+          <el-button
+            type="primary"
+            size="small"
+            link
+            @click="onView(scope.row)"
+          >
+            预览
+          </el-button>
           <el-button
             type="primary"
             size="small"
@@ -187,6 +200,12 @@
     // TODO: 实现修改分组的逻辑,功能空着留着后面做
   }
 
+  // 预览分组
+  function onView(row: MarkGroupItem) {
+    ElMessage.info(`预览分组:${row.groupNumber}`);
+    // TODO: 实现预览分组的逻辑,功能空着留着后面做
+  }
+
   // 设置试评数量
   function onSetTrialCount() {
     setTrialCountDialogRef.value?.open();

+ 11 - 16
src/views/mark/MarkProgress.vue

@@ -37,19 +37,12 @@
         <el-button :loading="closeLoading" @click="onCloseSubject"
           >关闭</el-button
         >
-
-        <el-dropdown @command="onExportCommand">
-          <el-button class="is-shade">
-            导出
-            <el-icon class="el-icon--right"><CaretBottom /> </el-icon>
-          </el-button>
-          <template #dropdown>
-            <el-dropdown-menu>
-              <el-dropdown-item command="fhy">整体评卷进度</el-dropdown-item>
-              <el-dropdown-item command="fhy">评卷员工作量</el-dropdown-item>
-            </el-dropdown-menu>
-          </template>
-        </el-dropdown>
+        <el-button @click="onExportCommand('exportMarkProgress')"
+          >导出评卷进度</el-button
+        >
+        <el-button @click="onExportCommand('exportMarkWorkload')"
+          >导出工作量</el-button
+        >
       </el-space>
     </div>
 
@@ -118,7 +111,6 @@
 <script setup lang="ts">
   import { reactive, ref, computed, onMounted } from 'vue';
   import { ElMessage } from 'element-plus';
-  import { CaretBottom } from '@element-plus/icons-vue';
   import { useAppStore } from '@/store';
 
   import {
@@ -134,6 +126,7 @@
   import useTable from '@/hooks/table';
   import useLoading from '@/hooks/loading';
   import { modalConfirm } from '@/utils/ui';
+  import { downloadExport } from '@/utils/download-export';
 
   defineOptions({
     name: 'MarkProgress',
@@ -270,8 +263,10 @@
   }
 
   // 导出
-  const onExportCommand = (command: string) => {
-    console.log('导出命令:', command);
+  const onExportCommand = async (
+    command: 'exportMarkProgress' | 'exportMarkWorkload'
+  ) => {
+    downloadExport(command);
   };
 
   // 获取统计信息

+ 19 - 0
src/views/review/AllReview.vue

@@ -26,6 +26,17 @@
           <el-option label="未复核" :value="false" />
         </el-select>
       </el-form-item>
+      <el-form-item label="标记卷">
+        <el-select
+          v-model="searchModel.marked"
+          placeholder="请选择"
+          clearable
+          style="width: 120px"
+        >
+          <el-option label="是" :value="true" />
+          <el-option label="否" :value="false" />
+        </el-select>
+      </el-form-item>
       <el-form-item label="学院">
         <select-option v-model="searchModel.college" type="college">
         </select-option>
@@ -202,6 +213,13 @@
         min-width="200"
         sortable
       />
+      <el-table-column prop="marked" label="标记卷" width="100">
+        <template #default="scope">
+          <el-tag :type="scope.row.marked ? 'success' : 'info'">
+            {{ scope.row.marked ? '是' : '否' }}
+          </el-tag>
+        </template>
+      </el-table-column>
       <el-table-column prop="secretNumber" label="密号" width="120" />
       <el-table-column label="选做异常" width="100">
         <template #default="scope">
@@ -334,6 +352,7 @@
     subjectCode: null,
     selective: undefined,
     inspected: undefined,
+    marked: undefined,
     college: undefined,
     startScore: undefined,
     endScore: undefined,

+ 17 - 3
src/views/review/ScoreReviewStatistics.vue

@@ -40,6 +40,19 @@
           <el-option label="未完成" :value="false" />
         </el-select>
       </el-form-item>
+      <el-form-item label="复核次数">
+        <el-input-number
+          v-model="searchModel.inspectRound"
+          :min="0"
+          :max="99"
+          :step="1"
+          :precision="0"
+          :controls="false"
+          step-strictly
+          placeholder="请输入"
+          style="width: 120px"
+        />
+      </el-form-item>
       <el-form-item>
         <el-button type="primary" @click="toPage(1)">查询</el-button>
         <el-button @click="onExport">导出</el-button>
@@ -131,9 +144,10 @@
   });
 
   const searchModel = reactive<ReviewStatListFilter>({
-    subjectCode: null,
-    selective: null,
-    finished: null,
+    subjectCode: undefined,
+    selective: undefined,
+    finished: undefined,
+    inspectRound: undefined,
   });
 
   const {