Jelajahi Sumber

feat:完成智能批改相关内容

白白 1 tahun lalu
induk
melakukan
16adac4bc9

+ 1 - 1
src/router/index.ts

@@ -85,7 +85,7 @@ const router = createRouter({
           component: () => import('../views/EditPage/EditPage.vue')
         },
         {
-          path: 'assignment/AIEvaluation',
+          path: 'assignment/:assignmentId/AIEvaluation',
           name: 'AIEvaluation',
           component: () => import('../views/AIEvaluationPage/AIEvaluationPage.vue')
         },

+ 112 - 130
src/views/AIEvaluationPage/AIEvaluationPage.vue

@@ -1,22 +1,44 @@
 <template>
   <div style="display: flex">
-    <el-card style="width: 40%; height: 90vh; margin: 10px; position: relative;" shadow="never">
-      <div style="display: flex;justify-content: center;align-items: center;width: 100px; height: 50px; background-color:var(--system-color); position: absolute; top: 20px; left: 0; clip-path: polygon(0 0, 100% 0, 80% 50%, 100% 100%, 0 100%);">
-        <span style="margin-left: -20px;color: white">原文</span>
-      </div>
-      <div style="white-space: pre-wrap; margin-top: 80px; line-height: 30px">
-        <el-scrollbar height="800px">
+    <!-- 1.作文展示区域 -->
+    <div style="width: 40%; height: 90vh; margin: 10px; position: relative;">
+      <el-breadcrumb :separator-icon="ArrowRight" style="height: 30px; align-content: center; margin-left: 6px">
+        <el-breadcrumb-item :to="{ path: `/home/Assignment/${assignmentId}/edit` }">写作</el-breadcrumb-item>
+        <el-breadcrumb-item><span style="color: rgba(22,119,255,0.62); font-weight: bold; cursor:pointer;">智能批改</span></el-breadcrumb-item>
+      </el-breadcrumb>
+
+      <el-card  shadow="never">
+        <!-- 原文标识 -->
+        <div style="display: flex;justify-content: center;align-items: center;width: 100px; height: 50px; background-color:var(--system-color); position: absolute; top: 40px; left: 0; clip-path: polygon(0 0, 100% 0, 80% 50%, 100% 100%, 0 100%);">
+          <span style="margin-left: -20px;color: white">原文</span>
+        </div>
+        <!-- 作文内容展示区域 -->
+        <div style="white-space: pre-wrap; margin-top: 80px; line-height: 30px">
+          <el-scrollbar height="760px">
           <span style="position: relative;">
-            <span v-for="sentenceEvaluation in data.sentenceEvaluationList"
-                  :key="sentenceEvaluation.id"
-                  :style="{ 'text-decoration': 'underline', 'text-decoration-color': 'pink', 'text-decoration-thickness': '3px', 'text-decoration-style': 'dashed', 'background-color': sentenceEvaluation.id === highlightSentenceId? 'rgba(255, 192, 203, 0.3)' : 'transparent' }">
-              {{ sentenceEvaluation.sentence }}
-            </span>
+            <template v-if="data.sentenceEvaluationList?.length != 0">
+              <span v-for="sentenceEvaluation in data.sentenceEvaluationList"
+                    :key="sentenceEvaluation.id"
+                    :style="{ 'text-decoration': 'underline', 'text-decoration-color': 'pink', 'text-decoration-thickness': '3px', 'text-decoration-style': 'dashed', 'background-color': sentenceEvaluation.id === highlightSentenceId? 'rgba(255, 192, 203, 0.3)' : 'transparent' }">
+                {{ sentenceEvaluation.sentence }}
+              </span>
+            </template>
+            <template v-else>
+              <span
+                  :style="{ 'text-decoration': 'underline', 'text-decoration-color': 'pink', 'text-decoration-thickness': '3px', 'text-decoration-style': 'dashed'}">
+                {{ data.overallEvaluation?.content }}
+              </span>
+            </template>
+
           </span>
-        </el-scrollbar>
-      </div>
-    </el-card>
-    <div style="width: 40%; margin: 10px; height: 88vh;">
+          </el-scrollbar>
+        </div>
+      </el-card>
+    </div>
+
+
+    <!-- 2.AI评价区域 -->
+    <div style="width: 40%; margin: 10px; height: 89vh;">
       <div class="combined-box">
         <div style="display: flex">
           <div
@@ -34,81 +56,58 @@
             逐句评价
           </div>
         </div>
-        <template v-if="selected === 'trapezoid'">
-          <div class="rectangle">
-            <div style="display: flex;align-items: flex-start;margin-bottom: 15px;">
-              <div>
-                <!--展示头像-->
-                <el-avatar src="@/image/404.jpg" :size="32" :shape="'circle'">
-                </el-avatar>
-              </div>
-              <div style="margin-left: 15px">
-                <!--名字-->
-                <div style="margin-bottom: 2px">SEEAI系统</div>
-                <!--内容-->
-                <div style="background-color: #f0f0f0;padding: 8px 12px;border-radius: 16px;white-space: pre-line;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);">
-                  {{ data.overallEvaluation }}
-                </div>
-              </div>
-            </div>
-          </div>
-        </template>
-        <template v-else>
-          <div class="rectangle">
-            <el-scrollbar height="800px">
-              <div style="display: flex; flex-direction: column;">
-                <el-card v-for="sentenceEvaluation in data.sentenceEvaluationList"
-                         :key="sentenceEvaluation.id"
-                         style="cursor: pointer; margin-bottom: 10px; position: relative;" shadow="hover"
-                         @mouseenter="highlightSentenceId = sentenceEvaluation.id"
-                         @mouseleave="highlightSentenceId = sentenceEvaluation.id"
-                >
-                  <div style="display: flex;justify-content: center;align-items: center;width: 20px; height: 100%; background-color: pink; position: absolute; top: 0; left: calc(100% - 20px)">
+        <div class="rectangle">
+          <template v-if="selected === 'trapezoid'">
+            <el-scrollbar height="820px">
+              <div style="display: flex;align-items: flex-start;margin-bottom: 15px;">
+                <div>
+                  <!--展示头像-->
+                  <!--<el-avatar src="@/image/seecoderLogo.png" :size="32" :shape="'circle'">-->
+                  <!--</el-avatar>-->
+                  <div style="border-radius: 50%; background-color:#fff; width: 40px; height: 40px;display: flex;justify-content: center;align-items: center;">
+                    <img src="@/image/seecoderLogo.png" width="32" >
                   </div>
-                  <div style="padding-right: 30px">
-                    {{ sentenceEvaluation.evaluation }}
+                </div>
+                <div style="margin-left: 15px">
+                  <!--名字-->
+                  <div style="margin-bottom: 2px">SEEAI英语助手</div>
+                  <!--内容-->
+                  <div style="background-color: #f0f0f0;padding: 8px 12px;border-radius: 16px;white-space: pre-line;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);">
+                    {{ data.overallEvaluation?.evaluation }}
                   </div>
-                </el-card>
+                </div>
               </div>
             </el-scrollbar>
-          </div>
-        </template>
+          </template>
+          <template v-else>
+              <el-scrollbar height="820px">
+                <div style="display: flex; flex-direction: column;">
+                  <template v-if="data.sentenceEvaluationList?.length == 0">
+                    暂无逐句评价
+                  </template>
+                  <el-card v-for="sentenceEvaluation in data.sentenceEvaluationList"
+                           :key="sentenceEvaluation.id"
+                           style="cursor: pointer; margin-bottom: 10px; position: relative;" shadow="hover"
+                           @mouseenter="highlightSentenceId = sentenceEvaluation.id"
+                           @mouseleave="highlightSentenceId = sentenceEvaluation.id"
+                  >
+                    <div style="display: flex;justify-content: center;align-items: center;width: 20px; height: 100%; background-color: pink; position: absolute; top: 0; left: calc(100% - 20px)">
+                    </div>
+                    <div style="padding-right: 30px">
+                      {{ sentenceEvaluation.evaluation }}
+                    </div>
+                  </el-card>
+                </div>
+              </el-scrollbar>
+          </template>
+        </div>
       </div>
     </div>
-<!--    <el-tabs style="width: 30%; margin: 10px; padding: 10px; background-color:#fff;" type="border-card">-->
-<!--      <el-tab-pane>-->
-<!--        <template #label>-->
-<!--        <span class="custom-tabs-label">-->
-<!--          <span>整体评价</span>-->
-<!--        </span>-->
-<!--        </template>-->
-<!--        整体评价-->
-<!--      </el-tab-pane>-->
-<!--      <el-tab-pane>-->
-<!--        <template #label>-->
-<!--        <span class="custom-tabs-label">-->
-<!--          <span>逐句评价</span>-->
-<!--        </span>-->
-<!--        </template>-->
-<!--        <div style="display: flex; flex-direction: column;">-->
-<!--          <el-card v-for="sentenceEvaluation in data.sentenceEvaluationList"-->
-<!--                   :key="sentenceEvaluation.id"-->
-<!--                   style="cursor: pointer; margin-bottom: 10px; position: relative;" shadow="hover"-->
-<!--                   @mouseenter="highlightSentenceId = sentenceEvaluation.id"-->
-<!--                   @mouseleave="highlightSentenceId = sentenceEvaluation.id"-->
-<!--          >-->
-<!--            <div style="display: flex;justify-content: center;align-items: center;width: 20px; height: 100%; background-color: pink; position: absolute; top: 0; left: calc(100% - 20px)">-->
-<!--            </div>-->
-<!--            <div style="padding-right: 30px">-->
-<!--              {{ sentenceEvaluation.evaluation }}-->
-<!--            </div>-->
-<!--          </el-card>-->
-<!--        </div>-->
-<!--      </el-tab-pane>-->
-<!--    </el-tabs>-->
+
+    <!-- 3.历史版本选择区域 -->
     <el-card
         style="
-          width: 240px;  /* 固定宽度代替百分比 */
+          width: 15%;  /* 固定宽度代替百分比 */
           height: 90vh;
           margin: 10px 0 10px auto;  /* 关键:左侧自动边距 */
           border-left: 1px solid #e4e7ed;
@@ -127,10 +126,10 @@
         <!-- 版本选择标题 -->
         <div style="
           position: absolute;
-          top: 20px;
-          left: -1px;
+          top: 0;
+          left: -20px;
           width: 80px;
-          height: 30px;
+          height: 40px;
           background: var(--system-color);
           clip-path: polygon(0 0, 100% 0, 90% 50%, 100% 100%, 0 100%);
           color: white;
@@ -149,12 +148,12 @@
               :key="version.id"
               class="version-item"
               :class="{ active: selectedVersion === version.version }"
-              @click="selectedVersion = version.version"
+              @click="getEvaluation(version.version)"
           >
             <div class="version-marker"></div>
             <div class="version-info">
-              <div class="version-time">{{ version.version }}</div>
-<!--              <div class="version-author">by {{ version.author }}</div>-->
+              <div class="version-time">{{ version.time }}</div>
+              <div class="version-author">v{{ version.version }}</div>
             </div>
           </div>
         </el-scrollbar>
@@ -180,10 +179,16 @@
   import useApis from "@/apis";
   import MyComponent from "@/views/AIEvaluationPage/MyComponent.vue";
   import {ElMessage} from "element-plus";
+  import {useRoute} from "vue-router";
+  import {useStore} from "@/store";
+  import { ArrowRight } from "@element-plus/icons-vue";
 
   const apis = useApis()
+  const store = useStore()
   const highlightSentenceId = ref(-1)
   const selected = ref('trapezoid');
+  const route = useRoute()
+  const assignmentId = Number(route.params.assignmentId)
   const data = reactive<{
     overallEvaluation: OverallEvaluation | null;
     sentenceEvaluationList: SentenceEvaluation[];
@@ -193,44 +198,13 @@
     sentenceEvaluationList: [],
     versionList: []
   })
-
-  const versions = ref([
-    { id: 1.2, time: '2024-06-20 14:30', author: '李老师' },
-    { id: 77771.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 44441.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 33331.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 22221.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 7871.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 691.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 591.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 581.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 481.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 461.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 451.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 321.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 1251.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 141.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 131.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 121.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 111.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 91.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 81.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 71.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 61.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 51.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 41.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 31.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 21.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 11.1, time: '2024-06-19 09:15', author: '张同学' },
-    { id: 1.0, time: '2024-06-18 16:45', author: '系统' }
-  ])
   const selectedVersion = ref(1.2)
 
   const toEvaluation = () => {
-    apis.overAllEvaluation(16, 15)
+    apis.overAllEvaluation(assignmentId, store.user.id)
         .then(res => {
           if(res.data.code === 200){
-            getEvaluation()
+            // getEvaluation()
           }else if(res.data.code === 400){
             ElMessage.error(res.data.msg)
           }
@@ -238,10 +212,10 @@
         .catch(err => {
           console.log(err)
         })
-    apis.sentenceEvaluation(16,15)
+    apis.sentenceEvaluation(assignmentId,store.user.id)
         .then(res => {
           if(res.data.code === 200){
-            getEvaluation()
+            // getEvaluation()
           }else if(res.data.code === 400){
             ElMessage.error(res.data.msg)
           }
@@ -251,33 +225,41 @@
         })
   }
 
-  const getEvaluation = () => {
-    apis.getOverall(16,15,2)
+  const getEvaluation = (version: number) => {
+    selectedVersion.value = version
+    apis.getOverall(assignmentId,store.user.id,version)
         .then(res => {
           console.log(res)
           data.overallEvaluation = res.data.data
         })
         .catch(err => {
           console.log(err)
+          data.overallEvaluation = {} as OverallEvaluation
         })
-    apis.getSentence(16,15,2)
+    apis.getSentence(assignmentId,store.user.id,version)
         .then(res => {
           console.log(res)
-          data.sentenceEvaluationList = res.data.data
+          if(res.data.code === 200){
+            data.sentenceEvaluationList = res.data.data
+          } else {
+            data.sentenceEvaluationList = []
+          }
         })
         .catch(err => {
           console.log(err)
+          data.sentenceEvaluationList = []
         })
   }
 
   const getEvaluationVersionList = () => {
-    apis.getEvaluationVersionList(16, 15)
+    apis.getEvaluationVersionList(assignmentId, store.user.id)
         .then(res => {
           // 从未批改过
           if(res.data.data.length === 0){
             data.versionList = []
           } else {
             data.versionList = res.data.data
+            getEvaluation(res.data.data[0].version)
           }
         })
         .catch(err => {
@@ -286,8 +268,8 @@
   }
 
   onMounted(() => {
-    toEvaluation()
-    getEvaluation()
+    // toEvaluation()
+    // getEvaluation()
     getEvaluationVersionList()
   })
 </script>

+ 107 - 47
src/views/Home/component/Silder/index.vue

@@ -41,11 +41,11 @@
         </template>
         <div class="edit-box-header">
           智能批改
-          <el-button @click="handleCorrect" v-if="showCorrectBtn">开始批改</el-button>
-          <el-button @click="handleCorrectToPage" v-if="showCorrectToPageBtn">查看完整批改报告</el-button>
+          <el-button @click="handleCorrect" :disabled="!showCorrectBtn" @mouseover="handleCorrectTip">开始批改</el-button>
+          <el-button @click="handleCorrectToPage" :disabled="!showCorrectToPageBtn" @mouseover="handleCorrectToPageTip">查看完整批改报告</el-button>
         </div>
         <div class="capacity-item">
-          <div v-loading="loading" element-loading-text="智能批改中" class="remark">{{ aiRemark }}</div>
+          <div v-loading="loading" element-loading-text="智能批改中" class="remark">{{ data.overallEvaluation?.evaluation }}</div>
         </div>
       </template>
     </div>
@@ -54,7 +54,7 @@
 </template>
 
 <script lang="ts" setup>
-import {defineProps, onMounted, reactive, ref, watch, watchEffect} from 'vue'
+import {defineProps, nextTick, onMounted, reactive, ref, watch, watchEffect} from 'vue'
   import "./index.scss"
 import type {engagementVO, IAssignment} from "@/types/vo";
   import useApis from "@/apis";
@@ -65,6 +65,7 @@ import ViewsWordEditor from "@/components/ViewsWordEditor/ViewsWordEditor.vue";
 import {useRoute} from "vue-router";
 import {ElMessage} from "element-plus";
 import router from "@/router";
+import * as path from "node:path";
 
 
   interface IPreviewProps {
@@ -92,10 +93,14 @@ import router from "@/router";
 
   let data = reactive<{
     assignment: IAssignment,
-    currentPreview: IPreviewProps
+    currentPreview: IPreviewProps,
+    overallEvaluation: OverallEvaluation | null;
+    sentenceEvaluationList: SentenceEvaluation[];
   }>({
     assignment: {} as IAssignment,
-    currentPreview: {} as IPreviewProps
+    currentPreview: {} as IPreviewProps,
+    overallEvaluation: null,
+    sentenceEvaluationList: [],
   })
 
   const alertProps = reactive({
@@ -123,30 +128,73 @@ import router from "@/router";
     });
   };
 
-  // 请求批改
-  const handleCorrect = () => {
-    loading.value = true;
-    apis.rewrite(assignmentId, store.user.id)
-        .then((res: any) => {
-          if (res.data.code == 500) {
-            aiRemark.value = new Array(2).join("智能批改请求超时")
-            ElMessage.error("智能批改请求超时")
-          } else {
-            console.log(res.data.data)
-            aiRemark.value = res.data.data.content;
-            showCorrectToPageBtn.value = true
-          }
+  const getEvaluation = () => {
+    apis.getOverall(props.engagement.assignmentId, store.user.id,props.engagement.version)
+        .then(res => {
+          console.log(res)
+          data.overallEvaluation = res.data.data
+          loading.value = false;
         })
-        .catch((err: any) => {
-          console.error(err);
+        .catch(err => {
+          console.log(err)
+          loading.value = false;
         })
-        .finally(() => {
+  }
+
+  const toEvaluation = () => {
+    apis.overAllEvaluation(props.engagement.assignmentId, store.user.id)
+        .then(res => {
+          if(res.data.code === 200){
+            getEvaluation()
+          }else if(res.data.code === 400){
+            ElMessage.error(res.data.msg)
+            loading.value = false;
+            // 允许查看详细报告
+            showCorrectToPageBtn.value = true;
+          }
+        })
+        .catch(err => {
+          console.log(err)
           loading.value = false;
-        });
+        })
+    apis.sentenceEvaluation(props.engagement.assignmentId, store.user.id)
+        .then(res => {
+          if(res.data.code === 400){
+            ElMessage.error(res.data.msg)
+          }
+        })
+        .catch(err => {
+          console.log(err)
+        })
+  }
+
+  // 请求批改
+  const handleCorrect = () => {
+    loading.value = true;
+    // apis.rewrite(assignmentId, store.user.id)
+    //     .then((res: any) => {
+    //       if (res.data.code == 500) {
+    //         aiRemark.value = new Array(2).join("智能批改请求超时")
+    //         ElMessage.error("智能批改请求超时")
+    //       } else {
+    //         console.log(res.data.data)
+    //         aiRemark.value = res.data.data.content;
+    //         showCorrectToPageBtn.value = true
+    //       }
+    //     })
+    //     .catch((err: any) => {
+    //       console.error(err);
+    //     })
+    //     .finally(() => {
+    //       loading.value = false;
+    //     });
+    toEvaluation()
   };
 
   const handleCorrectToPage = () => {
-    router.push(`/home/assignment/AIEvaluation`)
+    router.push({
+      path: `/home/assignment/${props.engagement.assignmentId}/AIEvaluation`,
+    })
   }
 
   const openEditor = (url: string, title: string) => {
@@ -179,34 +227,46 @@ import router from "@/router";
    * 用于判断是否已存在历史批改记录
    */
   const getEvaluationVersionList = () => {
-    apis.getEvaluationVersionList(16, 15)
-        .then(res => {
-          // 从未批改过
-          if(res.data.data.length === 0){
-            showCorrectBtn.value = true
-            showCorrectToPageBtn.value = false
-          } else {
-            showCorrectToPageBtn.value = true
-            let max = 0;
-            let records = res.data.data
-            for(let i = 0; i < records.length; i++){
-              if(records.version > max) max = records.version
+    if(JSON.stringify(props.engagement) !== '{}'){
+      apis.getEvaluationVersionList(props.engagement.assignmentId, store.user.id)
+          .then(res => {
+            // 从未批改过
+            console.log(res.data.data.length === 0)
+            if(res.data.data.length === 0){
+              showCorrectBtn.value = true
+              showCorrectToPageBtn.value = false
+            } else {
+              showCorrectToPageBtn.value = true
+              showCorrectBtn.value = (res.data.data[0].version !== props.engagement.version)
+              console.log(res.data.data)
             }
-            // 批改过且版本未有更新
-            showCorrectBtn.value = max !== props.engagement.version;
-            console.log(props.engagement)
-            console.log(max)
-          }
-        })
-        .catch(err => {
-          console.log(err)
-        })
+          })
+          .catch(err => {
+            console.log(err)
+          })
+    }
+
   }
 
+  const handleCorrectTip = () => {
+    if(!showCorrectBtn.value)
+      ElMessage.error("请更新作文内容并暂存后批改~")
+  }
+
+  const handleCorrectToPageTip = () => {
+    if(!showCorrectToPageBtn.value)
+      ElMessage.error("批改后才能查看报告~")
+  }
+
+  // 监听props变化
+  watch(() => props.engagement, (newEngagement, oldEngagement) => {
+    if (newEngagement) {
+      getEvaluationVersionList();
+    }
+  }, { immediate: true });
+
   onMounted(() => {
     fetchData()
-    getEvaluationVersionList()
-    console.log(props.engagement)
   });
 </script>