瀏覽代碼

feat:整合批改

白白 2 年之前
父節點
當前提交
4c5a097294

+ 114 - 0
src/views/CorrectPage/CorrectPage.vue

@@ -0,0 +1,114 @@
+<!--
+  Description: 教师批改界面。改写于EditPage
+  Author: XiaoYu
+  Created Date: 2024-7-24
+-->
+<template>
+
+    <div class="my-correct">
+      <!-- 写作题目 及 作文内容 -->
+      <div class="my-correct-header">
+        <StudentWritingRequirements /> 
+        <!-- TODO:怎么这么难写!!! -->
+        <StudentEssay :studentId = "studentId" :assignmentId="assignmentId"/> 
+      </div>
+      
+      <div class="right-side">
+        <!-- TODO:AI评分及写作过程记录:框架已完成,内容调取待完成 -->
+        <div class="my-correct-item">
+            <h2>历史记录</h2><br>
+            <ContentSelector/>
+        </div>
+        
+        <!-- 教师评分、修改意见及评价 -->
+        <!--新修改:评分小组件放入Remark组件中了  -->
+        <div class="my-correct-item">
+            
+            <Remark :studentId = "studentId" :assignmentId="assignmentId"/>              
+        </div>    
+        
+      </div>
+      
+      
+      
+    </div>
+  </template>
+
+<script setup lang="ts">
+import AIChatter from "@/components/AIChatter/AIChatter.vue";
+import Dictionaries from "@/views/Home/component/Dictionaries/index.vue";
+import useApis from "@/apis";
+import {useStore} from "@/store";
+import router from "@/router"
+import {onMounted, reactive, ref, watchEffect} from "vue";
+import type {engagementVO} from "@/types/vo";
+import type {IDialogue} from "@/types/dialogue.ts";
+import Edit from "@/views/Home/component/Edit/index.vue";
+import Slider from '@/views/Home/component/Silder/index.vue'
+import "./index.scss"
+import {useRoute} from 'vue-router'
+import StudentEssay from "../Home/component/StudentEssay/StudentEssay.vue";
+import ContentSelector from "../Home/component/ContentSelector/ContentSelector.vue";
+import StudentWritingRequirements from "../Home/component/StudentEssay/StudentWritingRequirements.vue";
+import Remark from "../Home/component/Remark/Remark.vue";
+
+
+// 获得路由中的assignmentId
+const route = useRoute()
+const assignmentId = Number(route.params.assignmentId)
+const studentId = Number(route.query.studentId)
+
+const apis = useApis()
+const store = useStore()
+
+//直接搬的EditPage,不知是否需要修改
+const dataForm = reactive<{
+  messages: IDialogue[],
+  dialogueId: string;
+  engagement: engagementVO
+}>({
+  messages: [],
+  dialogueId: '',
+  engagement: {} as engagementVO
+})
+
+// 获取数据
+async function fetchData(){
+  await apis.getAIDialogues(assignmentId,studentId )
+      .then((_res:any) => {
+        const data = _res.data.data
+        console.log(data)
+        Object.assign(dataForm, {
+          dialogueId: data?.dialogueId,
+          messages: data?.messages.content,
+          engagement: dataForm.engagement
+        })
+      })
+
+  await apis.getEngagement(studentId, assignmentId)
+      .then((_res:any) => {
+        console.log(_res)
+        Object.assign(dataForm, {
+          dialogueId: dataForm.dialogueId,
+          messages: dataForm.messages,
+          engagement: _res.data.data
+        })
+      }).catch((_err:any) => {
+        console.log(_err)
+        router.push("/login")
+      })
+}
+
+onMounted( () => {
+  console.log("获取数据")
+  console.log(assignmentId,"assassignmentId的值")
+  fetchData()
+})
+
+</script>
+
+<script lang="ts">
+export default {
+name: "CorrectPage"
+}
+</script>

+ 45 - 0
src/views/CorrectPage/index.scss

@@ -0,0 +1,45 @@
+
+
+.my-correct {
+    padding: 20px 0 20px 12px;
+    box-sizing: border-box;
+    height: calc(100vh - 40px);
+    display: flex;
+    gap: 20px;
+    //border: 1px solid black;
+  
+    .my-correct-header {
+      width: 50%;
+      height: 100%;
+      flex-shrink: 0;
+      //border: 1px solid black;
+      background-color:#fff;
+
+      
+    }
+    .right-side{
+      display: flex;
+      gap: 10px;
+      flex-direction: column;
+      height: 100%;
+      width: 50%;
+
+      .my-correct-item {
+        background-color: #f9f9f9;  
+        border-radius: 5px;  
+        padding: 15px;  
+        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+        flex-grow: 1;
+        //border: 1px solid black;
+        background-color: #fff;
+        
+      }
+
+
+    }
+
+    
+    
+    
+    
+}

+ 107 - 0
src/views/Home/component/Remark/Remark.vue

@@ -0,0 +1,107 @@
+<!--
+  Description: 教师评分和批改组件
+  Author: XiaoYu
+  Created Date: 2024-7-18
+-->
+<!-- 
+Attention: 创建作业和批改作业的老师须是同一位
+英语作文第一次作业的老师信息:
+"officialNumber": "2401016",
+"password": "309aabad-a151-42c3-b726-530fc426c5e2"
+-->
+<template>  
+  <div>  
+    <!-- 评分小组件 -->
+     <div class="rating-component">
+      <span>评分:&nbsp;&nbsp;</span>
+      <input
+        type="number"
+        class="score-input"  
+        :min="1"  
+        :max="100"  
+        placeholder="请输入1~100的分数"  
+        v-model="correction.score"/>
+     </div>  
+     
+    
+    <div class="textarea">
+      <!-- 评论输入框 -->  
+      <textarea v-model="correction.remark" placeholder="请输入评语"></textarea>  
+    </div>
+    
+    <!-- 提交按钮 -->
+    <el-button color="#597D3B" @click="handleCorrect">提交批改</el-button>
+  </div>  
+</template>  
+  
+<script lang="ts">  
+import "./index.scss"
+import useApis from "@/apis";
+import {  ElMessage } from "element-plus";
+import router from '@/router';
+
+export default { 
+  //defineprops只能在setup中使用 否则就直接写进这里 
+  props: {
+    studentId: {
+      type: Number,
+      required: true
+    },
+    assignmentId: {
+      type: Number,
+      required: true
+    }
+  },
+  
+  data() {  
+    return {  
+      // 初始化correction对象,它将被用作correctDTO的模板  
+      correction: {  
+        score: 0, 
+        remark: ''
+      }
+    };  
+  }, 
+  
+  methods: {  
+    async handleCorrect() {
+      const apis = useApis();
+      console.log(this.correction)
+      await apis.engagementCorrect(this.studentId, this.assignmentId, this.correction)
+            .then(res =>{
+              if(res.data.code === 200 ){
+                ElMessage.success("批改成功");
+                router.push(`/home/myCorrect/assignment/${this.assignmentId}`);
+              }else{
+                ElMessage.error("批改异常"+res.data.msg)
+                console.log(res)
+              }
+
+            }).catch(err=>{
+              console.log(err)
+            })
+    }
+  },  
+  
+}  
+</script>  
+  
+<style scoped>
+.score-input {  
+    /* 设置边框样式 */  
+    border: 2px solid #597D3B; /* 蓝色边框 */  
+    border-radius: 5px; /* 边框圆角 */  
+  
+    /* 设置背景色和字体样式 */  
+    background-color: #f8f9fa; /* 浅灰色背景 */  
+    color: #212529; /* 深色字体 */  
+    font-size: 16px; /* 字体大小 */  
+    padding: 8px 12px; /* 内边距 */  
+  
+    /* 设置焦点时的样式 */  
+    &:focus {  
+        border-color: #597D3B; /* 聚焦时边框颜色变深 */  
+        box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); /* 聚焦时添加阴影效果 */  
+    }
+}  
+</style>

+ 25 - 0
src/views/Home/component/Remark/index.scss

@@ -0,0 +1,25 @@
+
+.remark {  
+  display: flex;  
+  flex-direction: column; // 垂直布局  
+  gap: 10px; // 元素之间的间隙  
+  padding: 10px; // 内边距  
+  border: 1px solid #ccc; // 边框  
+  border-radius: 4px; // 边框圆角  
+  background-color: #fff; // 背景色   
+
+} 
+.rating-component {  
+  margin-bottom: 10px; // 下边距  
+}  
+
+// 文本区域样式  
+textarea { 
+  margin-bottom: 10px; /* 为textarea底部留出空间给提交按钮 */ 
+  height:250px;
+  width: 98%; // 宽度占满父容器  
+  padding: 10px; // 内边距   
+  border: 1px solid #ccc; // 边框  
+  border-radius: 4px; // 边框圆角  
+  // 其他样式...  
+}   

+ 116 - 0
src/views/Home/component/StudentEssay/StudentEssay.vue

@@ -0,0 +1,116 @@
+<!--
+  Description: 学生提交的作文内容组件
+  Author: XiaoYu
+  Created Date: 2024-7-24
+-->
+
+
+<template>
+    <div>
+      <div style="margin-left: 5%;">
+          <span style="font-weight: 600 " >学生姓名: </span>
+          {{ data.studentName }}
+          <span style="font-weight: 600 " >&nbsp;&nbsp;学生ID: </span>
+          {{ studentId }}
+          
+      </div>
+
+        <!-- 最后使用的在线预览是Office Web Viewer(微软) -->
+    <div class="iframe-wrapper">  
+        <iframe
+            :src="officeUrl"
+            frameborder="0"
+            width="100%"
+            height="560px"
+            
+
+        >
+        </iframe>
+    </div>
+            
+       
+    </div>
+</template>
+<!-- TODO:文件无法渲染 -->
+<script setup lang="ts">
+import { onMounted, defineProps ,computed, reactive} from 'vue';
+
+import useApis from '@/apis'; //  API 钩子函数
+
+ 
+const apis = useApis()
+
+let data = reactive({
+    loading: false,
+    docxUrl:"",
+    studentName:""
+})
+
+// 调用 API 获取文档 URL  
+const fetchDocxUrl = async (studentId: number, assignmentId: number) => {
+    data.loading = true;
+    await apis.getEngagement(studentId, assignmentId)
+        .then(_res => {
+            if (_res.data.code === 200 && _res.data.data.fileUrl)
+                data.docxUrl = _res.data.data.fileUrl
+            console.log(data)
+        }).catch(_err => {
+            console.log(_err)
+        }).finally(() => {
+            data.loading = false
+        })   
+};
+
+
+
+async function fetchUserAndPrint(studentId) {  
+    apis.findUserById(props.studentId)
+        .then((res:any)=>{
+            data.studentName = res.data.data.records[0].name
+        })    
+}  
+// Office Web Viewer(微软)实现在线预览
+const officeUrl = computed(() => {
+      return `https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(data.docxUrl)}`;
+    });
+
+// 组件挂载时调用,请求数据的方法
+onMounted(() => {
+    fetchDocxUrl(props.studentId, props.assignmentId)
+    fetchUserAndPrint(props.studentId)
+});
+
+const props = defineProps<{
+        studentId: number;
+        assignmentId: number;
+    }>();
+
+
+</script>
+
+<script lang="ts">
+
+
+
+</script>
+
+<style scoped>
+.loading {
+    /* 加载状态的样式 */
+    text-align: center;
+    padding: 20px;
+}
+
+.error {
+    /* 错误消息的样式 */
+    color: red;
+    text-align: center;
+    padding: 20px;
+}
+.iframe-wrapper {  
+  margin-top: 20px; /* 上边距 */  
+  margin-bottom: 20px; /* 下边距 */  
+} 
+</style>
+
+<!-- 注意:确保在父组件或全局范围内注册了 VueOfficeDocx 组件 -->

+ 77 - 0
src/views/Home/component/StudentEssay/StudentWritingRequirements.vue

@@ -0,0 +1,77 @@
+<!--
+  Description: 批改页面中的写作要求
+  Author: XiaoYu
+  Created Date: 2024-7-24
+-->
+
+
+<template>
+    <div class="homework-details">
+      <div class="homework-details-info">
+        <div class="homework-details-text">
+          <div class="title">
+            {{data.assignmentName}}
+          </div>
+          <div class="item">
+            <span style="font-weight: 600">作业描述: </span>
+            {{data.description}}
+          </div>
+          <div class="item">
+            <el-link type="primary" @click="console.log('文件下载')">相关文件下载</el-link>
+          </div>
+        </div>
+      </div>
+    </div>
+  
+  
+  </template>
+  
+  <script lang="ts" setup>
+  import useApis from "@/apis";
+  import {useRoute} from "vue-router";
+  import {onMounted, reactive} from "vue";
+  import type {AssignmentVO} from "@/types/vo";
+  import './studentWritingRequirements.scss'
+  
+  
+  const apis = useApis()
+  const route = useRoute()
+  const assignmentId = +route.params.assignmentId //string转number
+  
+  let data = reactive<AssignmentVO>({
+    assignmentId: null,
+    assignmentName: "",
+    description: "",
+    descriptionFile: null,
+    attachments: null,
+    teacherId: null,
+    courseId: null,
+    startTime: "",
+    endTime: "",
+    createTime: "",
+    status: ""
+  })
+  
+  
+  
+  const fetchData = () => {
+    apis.getAssignmentById(assignmentId)
+        .then((res: any) => {
+          Object.assign(data, res.data.data)
+        })
+  }
+  
+  onMounted(() => {
+    fetchData()
+  })
+  </script>
+  
+  <script lang="ts">
+  export default {
+    name: "StudentEssay"
+  }
+  </script>
+  
+  
+  
+  

+ 33 - 0
src/views/Home/component/StudentEssay/studentEssay.scss

@@ -0,0 +1,33 @@
+
+.student-essay {
+    width: 800px;
+    margin: 0 auto;
+    padding: 20px;
+    //background-color: #fff;
+  
+    .student-essay-info {
+      padding: 16px;
+      box-sizing: border-box;
+      border-radius: 7px;
+      border: solid 1px #d0d0d0;
+      display: flex;
+      gap: 20px;
+      background-color: #fff;
+      line-height: 30px;
+  
+      .student-essay-text {
+        display: flex;
+        flex-direction: column;
+        gap: 15px;
+      }
+  
+      .title {
+        font-size: 18px;
+        font-weight: 600;
+      }
+  
+      .item {
+      }
+    }
+
+  }

+ 32 - 0
src/views/Home/component/StudentEssay/studentWritingRequirements.scss

@@ -0,0 +1,32 @@
+.homework-details {
+    width: 800px;
+    margin: 0 auto;
+    padding: 20px;
+    //background-color: #fff;
+  
+    .homework-details-info {
+      padding: 16px;
+      box-sizing: border-box;
+      border-radius: 7px;
+      border: solid 1px #d0d0d0;
+      display: flex;
+      gap: 20px;
+      background-color: #fff;
+      line-height: 30px;
+  
+      .homework-details-text {
+        display: flex;
+        flex-direction: column;
+        gap: 15px;
+      }
+  
+      .title {
+        font-size: 18px;
+        font-weight: 600;
+      }
+  
+      .item {
+      }
+    }
+
+  }