ソースを参照

重新识别接口联调更新

dengshaobo 1 ヶ月 前
コミット
6fcebebc8d

+ 1 - 1
src/api/exam.ts

@@ -425,7 +425,7 @@ export const deleteAnswerCard= (data:any):Promise<ApiResponse> => {
 // 46. 扫描学生 重新识别 识别客观题和全部重新识别
 export const recognizeAgain= (data:any):Promise<ApiResponse> => {
   return request({
-    url: '/api/v1/ai_exam_scan/ai_hand_recognize_again',
+    url: '/api/v1/ai_exam_scan/ai_recognize_again',
     method: 'post',
     data
   })

+ 192 - 0
src/views/exam/components/CircleProcess.vue

@@ -0,0 +1,192 @@
+<template>
+  <div class="circle_progress">
+    <canvas 
+      ref="canvasRef" 
+      :width="canvasWidth" 
+      :height="canvasHeight"
+      :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
+    ></canvas>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
+
+/**
+ * 圆形进度条组件
+ * @description 使用 Canvas 绘制的圆形进度条,支持高分辨率屏幕适配
+ */
+
+// ==================== Props 定义 ====================
+interface Props {
+  /** 进度值 (0-100) */
+  process?: number
+  /** 线条宽度 */
+  lineWidth?: number
+  /** 背景圆颜色 */
+  backgroundColor?: string
+  /** 进度条颜色 */
+  lineColor?: string
+  /** Canvas 显示宽度(CSS像素) */
+  canvasWidth?: number
+  /** Canvas 显示高度(CSS像素) */
+  canvasHeight?: number
+  /** 圆形半径 */
+  circleRadius?: number
+}
+
+const props = withDefaults(defineProps<Props>(), {
+  process: 0,
+  lineWidth: 3,
+  backgroundColor: '#ffffff',
+  lineColor: '#2E64FA',
+  canvasWidth: 20,
+  canvasHeight: 20,
+  circleRadius: 5
+})
+
+// ==================== 响应式数据 ====================
+/** Canvas DOM 引用 */
+const canvasRef = ref<HTMLCanvasElement | null>(null)
+
+/** 防抖定时器 */
+let resizeTimer: ReturnType<typeof setTimeout> | null = null
+
+// ==================== 核心方法 ====================
+
+/**
+ * 绘制圆形进度条
+ * @description 包含背景圆和进度圆弧的绘制,支持高清屏适配
+ */
+const drawCircle = (): void => {
+  const canvas = canvasRef.value
+  if (!canvas) return
+
+  // 获取设备像素比
+  const dpr = window.devicePixelRatio || 1
+
+  // 设置canvas的实际物理尺寸(像素)- 这会重置 Canvas 状态
+  canvas.width = props.canvasWidth * dpr
+  canvas.height = props.canvasHeight * dpr
+
+  // 设置canvas的显示尺寸(CSS像素)
+  canvas.style.width = props.canvasWidth + 'px'
+  canvas.style.height = props.canvasHeight + 'px'
+
+  const ctx = canvas.getContext('2d')
+  if (!ctx) return
+
+  // 缩放绘制上下文以匹配设备像素比
+  ctx.scale(dpr, dpr)
+
+  // 启用高质量渲染
+  ctx.imageSmoothingEnabled = true
+  ctx.imageSmoothingQuality = 'high'
+
+  // 设置线条样式
+  ctx.lineCap = 'round'
+  ctx.lineJoin = 'round'
+  ctx.lineWidth = props.lineWidth
+
+  // 清除画布
+  ctx.clearRect(0, 0, props.canvasWidth, props.canvasHeight)
+
+  // 计算圆心坐标
+  const centerX = props.canvasWidth / 2
+  const centerY = props.canvasHeight / 2
+
+  // 绘制背景圆(灰色)
+  ctx.beginPath()
+  ctx.arc(centerX, centerY, props.circleRadius, 0, 2 * Math.PI)
+  ctx.strokeStyle = '#cccccc'
+  ctx.stroke()
+
+  // 绘制进度圆弧(仅当进度大于 0 时绘制)
+  if (props.process > 0) {
+    ctx.beginPath()
+    
+    // 起始角度:从顶部开始(-90度)
+    const startAngle = -90 * Math.PI / 180
+    
+    // 结束角度:根据进度计算
+    const endAngle = ((props.process / 100) * 360 - 90) * Math.PI / 180
+    
+    console.log('进度值:', props.process, '起始角度:', startAngle, '结束角度:', endAngle)
+    
+    // 绘制圆弧
+    ctx.arc(centerX, centerY, props.circleRadius, startAngle, endAngle, false)
+    ctx.strokeStyle = props.lineColor
+    ctx.stroke()
+  }
+}
+
+/**
+ * 窗口大小变化处理函数
+ * @description 使用防抖优化,避免频繁重绘
+ */
+const handleResize = (): void => {
+  if (resizeTimer) {
+    clearTimeout(resizeTimer)
+  }
+  
+  resizeTimer = setTimeout(() => {
+    drawCircle()
+  }, 100)
+}
+
+// ==================== 生命周期钩子 ====================
+
+/**
+ * 组件挂载时执行
+ */
+onMounted(() => {
+  drawCircle()
+  window.addEventListener('resize', handleResize)
+})
+
+/**
+ * 组件卸载前执行
+ */
+onBeforeUnmount(() => {
+  window.removeEventListener('resize', handleResize)
+  
+  if (resizeTimer) {
+    clearTimeout(resizeTimer)
+    resizeTimer = null
+  }
+})
+
+// ==================== 监听器 ====================
+
+/**
+ * 监听进度变化,自动重绘
+ */
+watch(
+  () => props.process,
+  () => {
+    drawCircle()
+  }
+)
+
+/**
+ * 监听 Canvas 尺寸变化,自动重绘
+ */
+watch(
+  () => [props.canvasWidth, props.canvasHeight, props.circleRadius],
+  () => {
+    drawCircle()
+  }
+)
+</script>
+
+<style lang="scss" scoped>
+.circle_progress {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  
+  canvas {
+    display: block;
+  }
+}
+</style>

+ 3 - 2
src/views/exam/components/ReIdentify.vue

@@ -332,9 +332,10 @@ const StartReIdentify = () => {
     // 调用重新识别接口
     recognizeAgain(param).then(res => {
         console.log("重新识别结果", res);
-        reIdentifyLoading.value = false;
+        // reIdentifyLoading.value = false;
         if (res.code == 200) {
-            ElMessage.success("重新识别完成!");
+            // ElMessage.success("重新识别完成!");
+            console.log("开始重新识别");
         }
         else
         {   

+ 51 - 4
src/views/exam/examList.vue

@@ -42,10 +42,23 @@
                         </div>
                     </template>
                 </el-table-column>
-                <el-table-column prop="name" label="已上传/学生数" align="center">
+                <el-table-column prop="name" label="已上传/学生数(%)" align="center">
                     <template v-slot="scope">
-                        <div class="full_mark_input">
+                        <!-- <div class="full_mark_input">
                             {{scope.row.uploadedNum}}/{{scope.row.totalStudentNum}}
+                            <CircleProcess></CircleProcess>
+                        </div> -->
+                        <div class="table_row_scan_number">
+                            <div class="scan_number">
+                                {{ scope.row.uploadedNum<0?'0':scope.row.uploadedNum }}/{{scope.row.totalStudentNum}}
+                            </div>
+                            <div class="scan_progress">
+                                <div class="scan_progress_circle" >
+                                    <CircleProcess :process="scope.row.uploadedRate"></CircleProcess>
+                                    <span class="span_number">{{ scope.row.uploadedRate+'%' }}</span> 
+                                </div>
+                                
+                            </div>
                         </div>
                    </template>
                 </el-table-column>
@@ -125,7 +138,7 @@
         </div>
     </div>
     <AddStudent ref="addStudentRef"  v-model="showAddStudent" :selectSchoolId="selectSchoolId" @success="HandleSuccess" />
-    <PaperPreview v-model="showPaperPreview"  :imageList="previewImageList"></PaperPreview>
+    <PaperPreview v-model="showPaperPreview"  :imageList="previewImageList" :showDraw="true" :answerData="[]"></PaperPreview>
   </div>
 </template>
 <script lang="ts" setup>
@@ -136,7 +149,7 @@ import { onMounted, onUnmounted, ref, nextTick,computed, watch } from 'vue';
 import { ElMessageBox, ElMessage } from 'element-plus'
 import AddStudent from './components/addStudent.vue' // 新增学生弹窗
 import PaperPreview from '@/views/exam/components/PaperPreview.vue';//试卷预览
-
+import CircleProcess from '@/views/exam/components/CircleProcess.vue'
 // 实例化 Store
 const examStore = useExamStore()
 const router = useRouter()
@@ -508,5 +521,39 @@ onUnmounted(() => {
         border-radius: 50%;
     }
 
+}
+
+//扫描进度
+.table_row_scan_number
+{
+    display: flex;
+    justify-content: space-between;
+    font-weight: 400;
+    font-size: 14px;
+    color: #666666;
+    width:calc(100% - 36px);
+    height: 52px;
+    line-height: 52px;
+    margin: auto;
+
+    .scan_number
+    {
+        width: 50%;
+    }
+    .scan_progress
+    {
+        width: 50%;
+        .scan_progress_circle
+        {
+            display: flex;
+            justify-content: flex-start;
+        }
+        .span_number
+        {
+            margin-left: 10px;
+            
+        }
+    }
+
 }
 </style>