Explorar o código

feat:完成批改界面右侧版本选择显示

白白 hai 1 ano
pai
achega
c987dcaf20

+ 1 - 1
src/apis/evaluation.ts

@@ -37,7 +37,7 @@ const evaluationApis = {
             }
         })
     },
-    getVersionList(assignmentId: number, studentId: number){
+    getEvaluationVersionList(assignmentId: number, studentId: number){
         return axiosInstance.get(`${EVALUATION_PREFIX}/record/list`, {
             params: {
                 assignmentId,

+ 1 - 0
src/apis/index.ts

@@ -9,6 +9,7 @@ import courseApis from "@/apis/course";
 import fileApis from "@/apis/file";
 import evaluationApis from "@/apis/evaluation";
 import emailApis from "@/apis/email";
+import authApis from "@/apis/auth";
 
 
 const apis = {

+ 178 - 17
src/views/AIEvaluationPage/AIEvaluationPage.vue

@@ -1,5 +1,5 @@
 <template>
-  <div style="display: flex;">
+  <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>
@@ -106,6 +106,72 @@
 <!--        </div>-->
 <!--      </el-tab-pane>-->
 <!--    </el-tabs>-->
+    <el-card
+        style="
+          width: 240px;  /* 固定宽度代替百分比 */
+          height: 90vh;
+          margin: 10px 0 10px auto;  /* 关键:左侧自动边距 */
+          border-left: 1px solid #e4e7ed;
+          border-radius: 0 8px 8px 0;
+          box-shadow: -2px 0 4px rgba(0,0,0,0.05);
+          /*position: sticky;  !* 新增固定定位 *!*/
+          right: 0;
+      "
+        shadow="never"
+    >
+      <div style="
+        position: relative;
+        height: 100%;
+        padding: 20px 10px;
+      ">
+        <!-- 版本选择标题 -->
+        <div style="
+          position: absolute;
+          top: 20px;
+          left: -1px;
+          width: 80px;
+          height: 30px;
+          background: var(--system-color);
+          clip-path: polygon(0 0, 100% 0, 90% 50%, 100% 100%, 0 100%);
+          color: white;
+          display: flex;
+          align-items: center;
+          padding-left: 12px;
+          font-size: 13px;
+        ">
+          版本历史
+        </div>
+
+        <!-- 版本列表 -->
+        <el-scrollbar height="800px" style="margin-top: 50px;">
+          <div
+              v-for="version in data.versionList"
+              :key="version.id"
+              class="version-item"
+              :class="{ active: selectedVersion === version.version }"
+              @click="selectedVersion = 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>
+          </div>
+        </el-scrollbar>
+
+        <!-- 当前版本提示 -->
+        <div style="
+          position: absolute;
+          bottom: 10px;
+          left: 10px;
+          right: 10px;
+          font-size: 12px;
+          color: #666;
+        ">
+          当前选择:v{{ selectedVersion }}
+        </div>
+      </div>
+    </el-card>
   </div>
 </template>
 
@@ -113,37 +179,78 @@
   import {onMounted, reactive, ref, watch} from "vue";
   import useApis from "@/apis";
   import MyComponent from "@/views/AIEvaluationPage/MyComponent.vue";
+  import {ElMessage} from "element-plus";
 
   const apis = useApis()
   const highlightSentenceId = ref(-1)
   const selected = ref('trapezoid');
+  const data = reactive<{
+    overallEvaluation: OverallEvaluation | null;
+    sentenceEvaluationList: SentenceEvaluation[];
+    versionList: []
+  }>({
+    overallEvaluation: null,
+    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)
         .then(res => {
-          console.log(res)
+          if(res.data.code === 200){
+            getEvaluation()
+          }else if(res.data.code === 400){
+            ElMessage.error(res.data.msg)
+          }
         })
         .catch(err => {
           console.log(err)
         })
     apis.sentenceEvaluation(16,15)
         .then(res => {
-          console.log(res)
+          if(res.data.code === 200){
+            getEvaluation()
+          }else if(res.data.code === 400){
+            ElMessage.error(res.data.msg)
+          }
         })
         .catch(err => {
           console.log(err)
         })
   }
 
-  const data = reactive<{
-    overallEvaluation: OverallEvaluation | null;
-    sentenceEvaluationList: SentenceEvaluation[];
-  }>({
-    overallEvaluation: null,
-    sentenceEvaluationList: []
-  })
-
   const getEvaluation = () => {
     apis.getOverall(16,15,2)
         .then(res => {
@@ -163,9 +270,25 @@
         })
   }
 
+  const getEvaluationVersionList = () => {
+    apis.getEvaluationVersionList(16, 15)
+        .then(res => {
+          // 从未批改过
+          if(res.data.data.length === 0){
+            data.versionList = []
+          } else {
+            data.versionList = res.data.data
+          }
+        })
+        .catch(err => {
+          console.log(err)
+        })
+  }
+
   onMounted(() => {
     toEvaluation()
     getEvaluation()
+    getEvaluationVersionList()
   })
 </script>
 
@@ -176,12 +299,7 @@ export default {
 </script>
 
 <style scoped>
-.tip1 {
-  background-color: rgba(255, 192, 203, 0.5)
-}
-.tip2 {
-  background-color: rgba(255, 165, 0, 0.5)
-}
+
 .combined-box {
   width: 100%; /* 整体宽度 */
   height: 100%;
@@ -231,4 +349,47 @@ export default {
   background-color: #fff; /* 长方形的背景颜色 */
   border-radius: 0 5px 5px 5px;
 }
+
+.version-item {
+  display: flex;
+  align-items: center;
+  padding: 8px;
+  margin-bottom: 8px;
+  border-radius: 4px;
+  cursor: pointer;
+  transition: all 0.2s;
+  box-sizing: border-box;
+}
+
+.version-item:hover {
+  background: #f5f7fa;
+}
+
+.version-item.active {
+  background: rgba(89, 125, 59, 0.1);
+  border: 1px solid rgba(89, 125, 59, 0.3);
+  box-sizing: border-box;
+}
+
+.version-marker {
+  width: 8px;
+  height: 8px;
+  border-radius: 50%;
+  background: #cfcfcf;
+  margin-right: 10px;
+}
+
+.version-item.active .version-marker {
+  background: var(--system-color);
+}
+
+.version-time {
+  font-size: 12px;
+  color: #333;
+}
+
+.version-author {
+  font-size: 10px;
+  color: #999;
+}
 </style>

+ 1 - 1
src/views/EditPage/EditPage.vue

@@ -15,7 +15,7 @@
     <div class="my-work-input">
       <Edit :engagement="dataForm.engagement"/>
     </div>
-    <Slider :dialogueId="dataForm.dialogueId"/>
+    <Slider :dialogueId="dataForm.dialogueId" :engagement="dataForm.engagement"/>
   </div>
 </template>
 

+ 29 - 8
src/views/Home/component/Silder/component/ExpandableParagraph.vue

@@ -6,11 +6,13 @@
 <template>
   <div>
     <div
+        ref="contentEl"
         :class="{'collapsed': !expanded, 'expanded': expanded}"
     >
       <span>{{ $props.text }}</span>
     </div>
     <el-button
+        v-if="showToggle || expanded"
         @click="toggle"
         type="text"
         class="toggle-button"
@@ -21,7 +23,7 @@
 </template>
 
 <script>
-import { ref, onMounted } from 'vue';
+import {ref, onMounted, onUpdated, nextTick} from 'vue';
 
 export default {
   name: 'ExpandableParagraph',
@@ -31,15 +33,33 @@ export default {
     },
   },
   setup(props) {
+    const contentEl = ref(null);
     const expanded = ref(false);
+    const showToggle = ref(false);
+
+    const checkOverflow = () => {
+      nextTick(() => {
+        if (contentEl.value) {
+          // 折叠状态下判断是否溢出
+          const lineHeight = parseInt(getComputedStyle(contentEl.value).lineHeight);
+          const maxHeight = lineHeight * 2;
+          showToggle.value = contentEl.value.scrollHeight > maxHeight;
+        }
+      });
+    };
 
     const toggle = () => {
       expanded.value = !expanded.value;
     };
 
+    onMounted(checkOverflow);
+    onUpdated(checkOverflow);
+
     return {
+      contentEl,
       expanded,
-      toggle,
+      showToggle,
+      toggle
     };
   },
 };
@@ -50,17 +70,18 @@ export default {
   overflow: hidden;
   display: -webkit-box;
   -webkit-box-orient: vertical;
-  -webkit-line-clamp: 2; /* Limit to 2 lines */
-  max-height: 3em; /* Height for 2 lines of text */
+  -webkit-line-clamp: 2;
+  line-height: 1.5em; /* 明确设置行高 */
 }
 
 .expanded {
   overflow: visible;
-  max-height: none;
+  -webkit-line-clamp: unset;
+  line-height: 1.5em; /* 明确设置行高 */
 }
 
 .toggle-button {
-  margin-top: -5px;
-  cursor: pointer;
+  padding: 0;
+  font-size: 12px;
 }
-</style>
+</style>

+ 67 - 32
src/views/Home/component/Silder/index.vue

@@ -24,12 +24,12 @@
         <!--作业描述-->
         <ExpandableParagraph :text="data.assignment.description" />
         <!--下载按钮-->
-        <div class="down">
-          <el-link type="primary">下载</el-link>
-        </div>
+<!--        <div class="down">-->
+<!--          <el-link type="primary">下载</el-link>-->
+<!--        </div>-->
         <!--要求文件和附件-->
         <template v-if="data.assignment.descriptionFile || data.assignment.attachments">
-          <div>范文、介绍</div>
+          <div>作业附件</div>
           <div class="slider-tag">
             <template v-if="data.assignment.descriptionFile">
               <div class="slider-tag-item" @click="openEditor(data.assignment.descriptionFile, data.assignment.assignmentName)">作业要求</div>
@@ -40,8 +40,9 @@
           </div>
         </template>
         <div class="edit-box-header">
-          智能批改修改意见
-          <el-button @click="handleCorrect">智能批改</el-button>
+          智能批改
+          <el-button @click="handleCorrect" v-if="showCorrectBtn">开始批改</el-button>
+          <el-button @click="handleCorrectToPage" v-if="showCorrectToPageBtn">查看完整批改报告</el-button>
         </div>
         <div class="capacity-item">
           <div v-loading="loading" element-loading-text="智能批改中" class="remark">{{ aiRemark }}</div>
@@ -55,7 +56,7 @@
 <script lang="ts" setup>
 import {defineProps, onMounted, reactive, ref, watch, watchEffect} from 'vue'
   import "./index.scss"
-  import type {IAssignment} from "@/types/vo";
+import type {engagementVO, IAssignment} from "@/types/vo";
   import useApis from "@/apis";
   import {useStore} from "@/store";
   import {Expand, Fold} from "@element-plus/icons-vue"
@@ -65,9 +66,6 @@ import {useRoute} from "vue-router";
 import {ElMessage} from "element-plus";
 import router from "@/router";
 
-  interface ISliderProps {
-    dialogueId: string;
-  }
 
   interface IPreviewProps {
     url: string;
@@ -76,13 +74,17 @@ import router from "@/router";
 
   const apis = useApis()
   const store = useStore()
-  const props = defineProps<ISliderProps>()
+  const props = defineProps<{
+    dialogueId: string,
+    engagement: engagementVO
+  }>()
 
   let isShrink = ref(false)
   let aiRemark = ref("")
   let loading = ref(false)
   let open= ref(false)
-  let expanded = ref(false)
+  let showCorrectBtn = ref(false)
+  let showCorrectToPageBtn = ref(false)
 
   // 获得路由中的assignmentId
   const route = useRoute()
@@ -123,27 +125,30 @@ import router from "@/router";
 
   // 请求批改
   const handleCorrect = () => {
-    // loading.value = true;
-    
-    router.push(`/home/assignment/AIEvaluation`)
-    // 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.overallEvaluation;
-    //       }
-    //     })
-    //     .catch((err: any) => {
-    //       console.error(err);
-    //     })
-    //     .finally(() => {
-    //       loading.value = false;
-    //     });
+    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;
+        });
   };
 
+  const handleCorrectToPage = () => {
+    router.push(`/home/assignment/AIEvaluation`)
+  }
+
   const openEditor = (url: string, title: string) => {
     open.value = true;
     data.currentPreview.url = url;
@@ -170,8 +175,38 @@ 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
+            }
+            // 批改过且版本未有更新
+            showCorrectBtn.value = max !== props.engagement.version;
+            console.log(props.engagement)
+            console.log(max)
+          }
+        })
+        .catch(err => {
+          console.log(err)
+        })
+  }
+
   onMounted(() => {
-    fetchData();
+    fetchData()
+    getEvaluationVersionList()
+    console.log(props.engagement)
   });
 </script>