Przeglądaj źródła

Merge remote-tracking branch 'origin/refactor' into refactor-admin

白白 1 rok temu
rodzic
commit
2e9848f49b

+ 10 - 0
src/apis/assignment.ts

@@ -39,7 +39,17 @@ const assignmentApis = {
                 assignmentId
             }
         })
+    },
+    deleteAssignmentById(teacherId:number, assignmentId:number){
+        return axiosInstance.delete(`${ASSIGNMENT_PREFIX}`, {
+            params: {
+                teacherId,
+                assignmentId
+            }
+        })
+
     }
+
 }
 
 export default assignmentApis

+ 1 - 1
src/apis/axios.config.ts

@@ -3,7 +3,7 @@ import axios from "axios";
 // const BASEURL = 'http://47.111.23.171:8081'
 // const BASEURL = 'http://localhost:8080'
 // const BASEURL = 'http://8.130.126.86:8080'
-const BASEURL = ''
+const BASEURL = 'https://air.seec.seecoder.cn/'
 
 const axiosInstance = axios.create({
     baseURL: BASEURL,

+ 33 - 1
src/components/AIChatter/AIChatter.module.scss

@@ -1,7 +1,7 @@
 .container {
   position: relative;
   width: 100%;
-  height: 58%; // 原值:60%
+  height: 60%; // 原值:60%
   padding: 10px;
   box-sizing: border-box;
   background-color: #ffffff;
@@ -69,6 +69,38 @@
     }
   }
 
+}
+//教师视图 应当适配correctPage
+.teacher-view{
+  position: relative;
+  width: 100%;
+  height: 90%; 
+  padding: 5px;
+  box-sizing: border-box;
+  background-color: #ffffff;
+  border-radius: 10px;
+
+
+  .message-box {
+    width: 100%;
+    height: 34vh;
+    overflow: auto;
+
+    .item {
+      display: flex;
+      align-items: flex-start;
+      margin-bottom: 15px;
+
+      .content {
+        background-color: #f0f0f0;
+        padding: 8px 12px;
+        border-radius: 16px;
+        word-break: break-word;
+        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+      }
+    }
+  }
+
 }
 
 //  .question-box {

+ 92 - 52
src/components/AIChatter/AIChatter.vue

@@ -3,27 +3,32 @@
   Author: BaiQi
   Created Date: 2024-6-21
 -->
+<!--TODO: 设置单次ai对话次数:10次-->
 <template>
-  <div :class="$style.container">
+  <div :class="[{'teacher-view': props.isTeacher},$style.container]">
     <!--大语言模型选择器-->
-    <div :class="$style.header">
-      <div :class="$style['model-selector']">
-        <el-dropdown trigger="click" @command="handleCommand">
-        <span style="font-size: 16px">
-          {{ data.model }}<el-icon ><arrow-down/></el-icon>
-        </span>
-          <template #dropdown>
-            <el-dropdown-menu>
-              <el-dropdown-item v-for="model in modelOptions" :command="model">{{ model }}</el-dropdown-item>
-            </el-dropdown-menu>
-          </template>
-        </el-dropdown>
+    <!-- Update: 目前只有glm4可用 删掉其他选项 -->
+     <div v-if="!props.isTeacher">
+      <div :class="$style.header">
+        <div :class="$style['model-selector']">
+          <el-dropdown trigger="click" @command="handleCommand">
+          <span style="font-size: 16px">
+            {{ data.model }}<el-icon ><arrow-down/></el-icon>
+          </span>
+            <template #dropdown>
+              <el-dropdown-menu>
+                <el-dropdown-item v-for="model in modelOptions" :command="model">{{ model }}</el-dropdown-item>
+              </el-dropdown-menu>
+            </template>
+          </el-dropdown>
+        </div>
       </div>
-    </div>
+     </div>
+
     <!-- 消息区域,采用ChatGPT的交互模式 -->
     <div :class="$style['message-box']" ref="containerTopRef">
       <div
-          v-for="(item, index) in data.messages"
+          v-for="(item, index) in messageList"
           :key="index"
           :class="$style.item"
       >
@@ -48,38 +53,40 @@
     </div>
 
     <!-- 对话框区域,用于AI提问和提示词模版展现 -->
-    <div :class="$style['question-box']">
-      <div :class="$style['input-group']">
-        <el-input
-            v-model="data.questionContent"
-            ref="inputRef"
-            :placeholder="`Message ${data.model} ...`"
-        >
-        </el-input>
-        <el-button
-            :disabled="data.questionContent === ''"
-            @click="handleSendQuestion"
-            style="width: 40px; border: none"
-            v-loading="data.loading"
-        >
-          <el-icon><Top/></el-icon>
-        </el-button>
-        <el-dropdown @command="handleMenuClick">
-          <el-button type="text" style="width: 40px;">
-            <el-icon><ArrowDown/></el-icon>
+    <div v-if="!props.isTeacher">
+      <div :class="$style['question-box']">
+        <div :class="$style['input-group']">
+          <el-input
+              v-model="data.questionContent"
+              ref="inputRef"
+              :placeholder="`Message ${data.model} ...`"
+          >
+          </el-input>
+          <el-button
+              :disabled="data.questionContent === ''"
+              @click="handleSendQuestion"
+              style="width: 40px; border: none"
+              v-loading="data.loading"
+          >
+            <el-icon><Top/></el-icon>
           </el-button>
-          <template #dropdown>
-            <el-dropdown-menu>
-              <el-dropdown-item
-                  v-for="(template, index) in questionTemplates"
-                  :key="index"
-                  :command="index"
-              >
-                {{ template }}
-              </el-dropdown-item>
-            </el-dropdown-menu>
-            </template>
-        </el-dropdown>
+          <el-dropdown @command="handleMenuClick">
+            <el-button type="text" style="width: 40px;">
+              <el-icon><ArrowDown/></el-icon>
+            </el-button>
+            <template #dropdown>
+              <el-dropdown-menu>
+                <el-dropdown-item
+                    v-for="(template, index) in questionTemplates"
+                    :key="index"
+                    :command="index"
+                >
+                  {{ template }}
+                </el-dropdown-item>
+              </el-dropdown-menu>
+              </template>
+          </el-dropdown>
+        </div>
       </div>
     </div>
   </div>
@@ -103,21 +110,23 @@
           L 15 15
         " style="fill: rgba(0, 0, 0, 0)"/>
       `
-
+//update: 加入isTeacher属性,用于判断是否是教师批改界面
   interface IProps {
     dialogueId: string;
     messages: IDialogue[]
+    isTeacher: boolean
   }
 
   const props = defineProps<{
     dialogueId: string,
     messages: IDialogue[]
+    isTeacher: boolean
   }>()
 
   const apis = useApis()
   const store = useStore()
-  // ChatGLM改为4
-  const modelOptions = ["ChatGPT", "ChatGLM4", "QWen14B"]
+  //UPDATE: 目前只有ChatGLM4
+  const modelOptions = ["ChatGLM4"]
   const questionTemplates = [
     "xxx是什么意思?",
     "英文如何描述xxx",
@@ -129,6 +138,9 @@
   const messagesEndRef = ref(null);
   const containerTopRef = ref(null);
 
+  // 用于处理ai对话展示异常问题
+  let messageList:IDialogue[] = []
+
   let data = reactive<{
     model: string;
     questionContent: string;
@@ -148,6 +160,7 @@
   // 加载聊天记录,并滚动至最后
   onMounted(() => {
     if (props.messages) data.messages = props.messages;
+    // console.log(props.messages)
     scrollToEnd();
   });
 
@@ -158,6 +171,8 @@
   watch(() => props.messages, (newMessages:any) => {
     if (newMessages)
       data.messages = newMessages;
+    console.log(newMessages)
+    handleMessageList()
     scrollToEnd();
   });
 
@@ -185,6 +200,7 @@
     });
   });
 
+  //  BUG: 按这套逻辑显示的名字可能与内容对不上
   const handleSendQuestion = () => {
     data.loading = true;
 
@@ -197,8 +213,8 @@
     apis.requestAI(props.dialogueId, data.model, requestBody)
         .then((_res:any) => {
           const resDialogue = _res.data.data;
-          console.log(resDialogue);
           data.messages.push(resDialogue);
+          handleMessageList()
         })
         .catch((_err:any) => {
           console.log(_err);
@@ -216,10 +232,34 @@
 
   // 选择模板问题
   const handleMenuClick = (key:any) => {
-    data.questionContent = questionTemplates[key];
-    inputRef.value.focus();// 设置焦点自动回到Input
+    // data.questionContent = questionTemplates[key];
+    // inputRef.value.focus();// 设置焦点自动回到Input
+    console.log(data.messages)
   };
 
+  // 处理ai对话显示异常问题
+  const handleMessageList = () => {
+    let count1 = 0
+    let count2 = 1
+    for(let message of data.messages){
+      if(message.role == "user"){
+        messageList[count1] = {
+          role: "user",
+          content: message.content
+        }
+        count1+=2
+      }
+      if(message.role == "assistant"){
+        messageList[count2] = {
+          role: "assistant",
+          content: message.content
+        }
+        count2+=2
+      }
+    }
+  }
+
+
 </script>
 
 <script lang="ts">

+ 1 - 1
src/components/WordEditor/WordEditor.vue

@@ -6,7 +6,7 @@
 <template>
     <DocumentEditor
         id="docxEditor"
-        documentServerUrl="http://139.196.252.184:8082/"
+        documentServerUrl="https://docx.seec.seecoder.cn/"
         :config="config"
         :events_onDocumentReady="onDocumentReady"
         :onLoadComponentError="onLoadComponentError"

+ 1 - 1
src/views/CorrectPage/AssignmentPage.vue

@@ -40,7 +40,7 @@
       </template>
       <el-table-column type="index"/>
       <el-table-column prop="assignmentName" label="作业名称" width="400"/>
-      <el-table-column prop="description" label="描述" width="500"/>
+      <!-- <el-table-column prop="description" label="描述" width="500"/> -->
       <el-table-column prop="endTime" label="截止时间" sortable/>
       <el-table-column prop="status" label="状态" sortable/>
       <el-table-column label="操作">

+ 4 - 4
src/views/CorrectPage/CorrectAssignmentPage.vue

@@ -34,10 +34,10 @@
         暂无作业
       </template>
       <el-table-column type="index"/>
-      <el-table-column prop="statusName" label="状态" sortable width="150"/>
-      <el-table-column prop="studentName" label="学生姓名" width="150"/>
-      <el-table-column prop="score" label="得分" sortable width="150"/>
-      <el-table-column prop="remark" label="评价" width="750"/>
+      <el-table-column prop="statusName" label="状态" sortable />
+      <el-table-column prop="studentName" label="学生姓名" />
+      <el-table-column prop="score" label="得分" sortable />
+      <!-- <el-table-column prop="remark" label="评价" width="750"/> -->
       <el-table-column label="操作">
         <template #default="scope">
           <el-button @click="handleCorrect(scope.row.assignmentId, scope.row.studentId)" style="margin-right: 0; margin-left: 0;padding-left: 10px; padding-right: 10px" color="#597D3B">

+ 4 - 4
src/views/CorrectPage/CorrectPage.vue

@@ -14,10 +14,10 @@
       </div>
       
       <div class="right-side">
-        <!-- TODO:AI评分及写作过程记录:框架已完成,内容调取待完成 -->
+        <!-- update: 仅保留AI历史对话 -->
         <div class="my-correct-record">
-            <h2>历史记录</h2><br>
-            <ContentSelector :dialogueId="dataForm.dialogueId" :messages="dataForm.messages"/>
+            <h2>学生与AI对话历史记录</h2><br>
+            <AIChatter :dialogueId="dataForm.dialogueId" :messages="dataForm.messages" :is-teacher="true"/>
         </div>
         
         <!-- 教师评分、修改意见及评价 -->
@@ -64,7 +64,7 @@ const studentId = Number(route.query.studentId)
 const apis = useApis()
 const store = useStore()
 
-//直接搬的EditPage,不知是否需要修改
+
 const dataForm = reactive<{
   messages: IDialogue[],
   dialogueId: string;

+ 2 - 2
src/views/CorrectPage/CoursePage.vue

@@ -21,8 +21,8 @@
         暂无课程
       </template>
       <el-table-column type="index"/>
-      <el-table-column prop="courseName" label="课程名称" width="300"/>
-      <el-table-column prop="description" label="描述" width="600"/>
+      <el-table-column prop="courseName" label="课程名称" width="280"/>
+      <el-table-column prop="description" label="描述" width="420"/>
       <el-table-column prop="endTime" label="截止时间" sortable/>
 <!--      <el-table-column prop="endTime" label="状态" sortable/>-->
       <el-table-column label="操作">

+ 2 - 2
src/views/CorrectPage/index.scss

@@ -35,7 +35,7 @@
         border-radius: 5px;  
         padding: 15px;  
         box-shadow: 0 2px 4px rgba(0,0,0,0.1);
-        height: 35vh;
+        height: 36vh;
         //border: 1px solid black;
         background-color: #fff;
         
@@ -45,7 +45,7 @@
         border-radius: 5px;  
         padding: 15px;  
         box-shadow: 0 2px 4px rgba(0,0,0,0.1);
-        height: 64vh;
+        height: 63vh;
         //border: 1px solid black;
         background-color: #fff;
         

+ 40 - 6
src/views/CoursePage/CoursePage.vue

@@ -20,8 +20,8 @@
         暂无课程
       </template>
       <el-table-column type="index"/>
-      <el-table-column prop="courseName" label="课程名称" width="300"/>
-      <el-table-column prop="description" label="描述" width="600"/>
+      <el-table-column prop="courseName" label="课程名称" width="280"/>
+      <el-table-column prop="description" label="描述" width="420"/>
       <el-table-column prop="endTime" label="截止时间" sortable/>
       <el-table-column label="操作">
         <template #default="scope">
@@ -49,14 +49,14 @@
 
   <el-dialog v-model="visible" title="新增课程">
     <el-form :model="newCourse">
-      <el-form-item label="课程名称">
-        <el-input v-model="newCourse.courseName" placeholder="请输入名称"></el-input>
+      <el-form-item label="课程名称" >
+        <el-input v-model="newCourse.courseName" placeholder="请输入课程名称"></el-input>
       </el-form-item>
       <el-form-item label="面向年级">
-        <el-input v-model="newCourse.targetGrade" placeholder="请输入年级"></el-input>
+        <el-input v-model="newCourse.targetGrade" placeholder="请输入目标年级,例:2024级软件1-4班"></el-input>
       </el-form-item>
       <el-form-item label="描述">
-        <el-input v-model="newCourse.description" placeholder="请输入描述"></el-input>
+        <el-input v-model="newCourse.description" placeholder="请输入课程描述"></el-input>
       </el-form-item>
       <el-form-item label="选课码">
         <el-input v-model="newCourse.enrollCode" placeholder="请输入选课码"></el-input>
@@ -238,8 +238,41 @@
   }
 
   const handleSubmit = () => {
+    if(newCourse.courseName === '') {
+      ElNotification({title: '课程名称不得为空',type: 'error',})
+      return
+    }
+    if(newCourse.targetGrade === '') {
+      ElNotification({title: '面向年级不得为空',type: 'error',})
+      return
+    }
+    if(newCourse.description === '') {
+      ElNotification({title: '描述不得为空',type: 'error',})
+      return
+    }
+    // if(newCourse.enrollCode === '') {
+    //   ElNotification({title: '选课码不得为空',type: 'error',})
+    //   return
+    // }
+    if(newCourse.startTime === '') {
+      ElNotification({title: '开始时间不得为空',type: 'error',})
+      return
+    }
+    if(newCourse.endTime === '') {
+      ElNotification({title: '结束时间不得为空',type: 'error',})
+      return
+    }
+    if(newCourse.startTime >= newCourse.endTime) {
+      ElNotification({title: '结束时间不得在起始时间之前',type: 'error',})
+      return
+    }
     newCourse.endTime = formatDate(newCourse.endTime)
     newCourse.startTime = formatDate(newCourse.startTime)
+    if(new Date(newCourse.endTime) < new Date(newCourse.startTime)){
+      ElMessage.error('截止时间不能早于开始时间!');
+      return;
+    }
+
     apis.createCourse(newCourse)
         .then((res:any) => {
           if(res.data.code===200) {
@@ -247,6 +280,7 @@
               title: '添加成功',
               type: 'success',
             })
+            fetchData()
           }else {
             console.log(res.data)
           }

+ 68 - 1
src/views/CourseSquare/component/CourseDetails/component/CourseHomeworkTable.vue

@@ -137,6 +137,8 @@
       <div class="dialog-footer">
         <el-button @click="dialogConfig.visible = false; cleanNewAssignmentInfo()">取消</el-button>
         <el-button type="primary" @click="handleSubmit">确定</el-button>
+        <!-- TODO:有点问题 总是删除失败 -->
+        <el-button type="danger" @click="confirmDelete()">删除作业</el-button>
       </div>
     </template>
   </el-dialog>
@@ -153,6 +155,7 @@ import {defineProps, inject, onMounted, reactive, ref} from 'vue';
   import {
   ElMessage,
   ElNotification,
+  ElMessageBox,
   type UploadFile,
   type UploadFiles,
   type UploadProps,
@@ -162,6 +165,7 @@ import {defineProps, inject, onMounted, reactive, ref} from 'vue';
   import ViewsWordEditor from "@/components/ViewsWordEditor/ViewsWordEditor.vue";
   import {useStore} from "@/store";
   import {Search, Edit, UploadFilled, Plus} from "@element-plus/icons-vue"
+import { userInfo } from 'os';
 
   const props = defineProps<{
     tableData: IAssignmentTableItem[],
@@ -411,6 +415,28 @@ const openEditor = (url: string, title: string) => {
 
 
   const handleSubmit = async () => {
+
+    if(newAssignmentInfo.assignmentName === '') {
+      ElNotification({title: '作业名称不得为空',type: 'error',})
+      return
+    }
+    if(newAssignmentInfo.description === '') {
+      ElNotification({title: '作业描述不得为空',type: 'error',})
+      return
+    }
+
+    if(newAssignmentInfo.startTime === '') {
+      ElNotification({title: '开始时间不得为空',type: 'error',})
+      return
+    }
+    if(newAssignmentInfo.endTime === '') {
+      ElNotification({title: '结束时间不得为空',type: 'error',})
+      return
+    }
+    if(newAssignmentInfo.startTime >= newAssignmentInfo.endTime) {
+      ElNotification({title: '结束时间不得在起始时间之前',type: 'error',})
+      return
+    }
     // console.log("提交方法最开始",newAssignmentInfo)
     newAssignmentInfo.endTime = formatDate(newAssignmentInfo.endTime);
     newAssignmentInfo.startTime = formatDate(newAssignmentInfo.startTime);
@@ -423,7 +449,9 @@ const openEditor = (url: string, title: string) => {
               ElNotification({
                 title: '新增成功',
                 type: 'success',
-              })
+              });
+              //TODO: 新建作业后自动刷新页面 但是怎么跳转回作业列表页面?
+              location.reload();
             }else {
               ElNotification({
                 title: '新增失败',
@@ -464,6 +492,45 @@ const openEditor = (url: string, title: string) => {
     }
     doRefresh();
   }
+//传teacherId:number, assignmentId:number
+  const confirmDelete = () => {
+    ElMessageBox.confirm('确定要删除这个作业吗?', '警告', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }).then(() => {
+      deleteAssignment();
+    }).catch(() => {
+      // 用户选择取消,什么都不做
+    });
+  };
+
+  const deleteAssignment = () => {
+    apis.deleteAssignmentById(store.user.id,IAssignmentId.value)
+    
+      .then((res: any) => {
+        if (res.data.code === 200) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!'
+          });
+          // 这里可以调用刷新数据的方法
+          doRefresh();
+        } else {
+          ElMessage({
+            type: 'error',
+            message: '删除失败!'+res.data.message
+          });
+        }
+      })
+      .catch((err) => {
+        console.log(err);
+        ElMessage({
+          type: 'error',
+          message: '请求出错!'
+        });
+      });
+  };
 
   const isDisabled = (teacherId: string, endDate: string) => {
     if(props.role == 'teachers'){// 是教师且不是作业发布人则禁用

+ 28 - 4
src/views/CourseSquare/component/CourseDetails/index.vue

@@ -495,6 +495,11 @@ const submitForm = async (formEl: FormInstance | undefined) => {
 const handleSubmit = () => {
   newCourseInfo.endTime = formatDate(newCourseInfo.endTime)
   newCourseInfo.startTime = formatDate(newCourseInfo.startTime)
+  if(new Date(newCourseInfo.endTime) < new Date(newCourseInfo.startTime)){
+      ElMessage.error('截止时间不能早于开始时间!');
+      checkTimeAndAdjust();
+      return;
+  }
   // uploadRef.value!.submit()
   console.log(newCourseInfo)
   // TODO: 更新图片需要更新两次,不知道为什么
@@ -506,10 +511,11 @@ const handleSubmit = () => {
           type: 'success',
         })
         visible.value = false
-        apis.getCourseByCourseId(dataForm.courseId)
-            .then((res:any) => {
-              console.log(res.data.data.records[0])
-            })
+        getCourse();
+        // apis.getCourseByCourseId(dataForm.courseId)
+        //     .then((res:any) => {
+        //       console.log(res.data.data.records[0])
+        //     })
         // setTimeout(() => apis.updateCourse(dataForm.courseId, newCourseInfo), 500)
       }else {
         ElNotification({
@@ -524,6 +530,19 @@ const handleSubmit = () => {
     })
 }
 
+const checkTimeAndAdjust = () => {
+  const startTime = new Date(dataForm.startTime);
+  let endTime = new Date(dataForm.endTime);
+
+  // 检查截止时间是否早于开始时间
+  if (endTime < startTime) {
+      // 将截止时间设置为开始时间的下一天
+      endTime.setDate(startTime.getDate() + 1);
+      newCourseInfo.endTime = formatDate(endTime.toISOString()); // 更新格式
+      ElMessage.warning('先前时间逻辑有误,截止时间已自动调整为开始时间的下一天!');
+  }  
+}
+
 function isDisabled(){
   if(role == "student") return showCode.value;
   if(role == "teachers") return !showEdit.value;
@@ -534,9 +553,14 @@ onMounted(() => {
   getHomeworkList()
   if(role == 'student') isShowCode()
   if(role == 'teachers') isShowEdit()
+
+  //检查并自动调整时间逻辑
+  checkTimeAndAdjust();
 })
 
 
+
+
 </script>
 
 <style scoped>

+ 5 - 2
src/views/EditPage/EditPage.vue

@@ -9,8 +9,7 @@
 
     <div class="my-work-slider">
       <el-button class="back" color="#597D3B" @click="handleBack">&lt;返回</el-button>
-      <AIChatter :dialogueId="dataForm.dialogueId" :messages="dataForm.messages" />
-
+      <AIChatter :dialogueId="dataForm.dialogueId" :messages="dataForm.messages" :is-teacher="false" />
       <Dictionaries />
     </div>
     <div class="my-work-input">
@@ -65,6 +64,7 @@
             messages: data == null ? []: data?.messages.content,
             engagement: dataForm.engagement
           })
+
         })
 
     await apis.getEngagement(store.user.id, assignmentId)
@@ -74,6 +74,9 @@
             messages: dataForm.messages,
             engagement: _res.data.data
           })
+          if(!dataForm.engagement){
+            fetchData()
+          }
         }).catch((_err:any) => {
           console.log("错误", _err)
         })

+ 1 - 0
src/views/EditPage/index.scss

@@ -16,6 +16,7 @@
       text-align: left; /* 文字左对齐 */
       width: 70px;
     }
+    overflow: auto;
   }
 
   .my-work-input {

+ 28 - 12
src/views/Home/component/ContentSelector/ContentSelector.vue

@@ -3,33 +3,49 @@
   Author: XiaoYu
   Created Date: 2024-7-27
 -->
-<!-- TODO:还是demo,三个内容还不能用 -->
+<!-- update: 已弃用 -->
 <template>  
   <div class="content-selector">  
     <!-- 按钮组 -->  
     <div class="button-group">
       <el-button color="#597D3B" class="submit-button" @click="selectContent(0)">AI对话</el-button>
-      <el-button color="#597D3B" class="submit-button" @click="selectContent(1)">字典查询</el-button>
-      <el-button color="#597D3B" class="submit-button" @click="selectContent(2)">浏览器搜索</el-button>  
     </div>  
   
-    <!-- 内容输入框,带有实线边框 -->  
+    <!-- update: 删掉了字典和浏览器记录的按钮,只保留AI对话 -->  
     <div class="content-input-box">  
       <!-- 根据selectedContent的值动态显示内容 -->  
       <div v-if="selectedContent === 0" class="content-item">  
-        <!-- 这里可以是一个真正的输入框或其他内容显示区域 -->  
-        <textarea disabled placeholder="AI对话的内容将显示在这里..." class="input-area"></textarea>  
-      </div>  
-      <div v-if="selectedContent === 1" class="content-item">  
-        <textarea disabled placeholder="字典查询的结果将显示在这里..." class="input-area"></textarea>  
-      </div>  
-      <div v-if="selectedContent === 2" class="content-item">  
-        <textarea disabled placeholder="浏览器搜索的结果将显示在这里..." class="input-area"></textarea>  
+        <!-- TODO:调取AI对话内容,并显示在这里 -->  
+        <AIChatter :dialogueId="dataForm.dialogueId" :messages="dataForm.messages" />  
       </div>  
     </div>  
   </div>  
 </template>
 
+<script setup lang="ts">  
+import AIChatter from '@/components/AIChatter/AIChatter.vue';
+import { IDialogue } from '@/types/dialogue';
+import { reactive, ref } from 'vue';
+import { useRoute } from 'vue-router';
+import { useStore } from '@/store';
+import useApis from '@/apis';
+
+const route = useRoute()
+const assignmentId  = Number(route.params.assignmentId) 
+const apis = useApis()
+const store = useStore()
+
+
+const dataForm =reactive<{
+  messages: IDialogue[],
+  dialogueId: string,
+
+}>({
+  messages: [],
+  dialogueId: ''
+})
+</script>
+
 <script>  
 export default {  
   name: 'ContentSelector', // 组件名称  

+ 67 - 11
src/views/Home/component/Dictionaries/index.vue

@@ -2,6 +2,7 @@
   Description: 写作界面左下角,字典组件
   Author: BaiQi
   Created Date: 2024-6-21
+  6718dffaee5b2137080707f5
 -->
 <template>
   <div :class="$style.dictionaries">
@@ -23,7 +24,7 @@
         </template>
       </el-input>
       <!--TODO 字典展示-->
-      <div>{{ res }}</div>
+      <div style="white-space: pre-wrap;">{{ res }}</div>
     </div>
   </div>
 </template>
@@ -34,6 +35,7 @@
   import {ref} from "vue";
   import LanguageIcon from "@/components/languageIcon/languageIcon.vue";
   import {Search} from '@element-plus/icons-vue';
+  import type {IDialogue} from "@/types/dialogue";
 
   const apis = useApis()
   const store = useStore()
@@ -41,23 +43,77 @@
   const content = ref('')
   const res = ref('')
   const loading = ref(false)
+  const promptTemplate = "任务说明:\n" +
+      "\n" +
+      "如果用户提供中文句子,请将该句子翻译为英文。\n" +
+      "如果用户提供英文句子,请将该句子翻译为中文。\n" +
+      "如果用户提供中文或英文单词,请提供该单词的所有可能翻译,并给出相关的例句。\n" +
+      "示例:\n" +
+      "\n" +
+      "中文句子翻译:\n" +
+      "用户:我今天去学校了。\n" +
+      "模型:I went to school today.\n" +
+      "\n" +
+      "英文句子翻译:\n" +
+      "用户:She is studying at the library.\n" +
+      "模型:她正在图书馆学习。\n" +
+      "\n" +
+      "中文单词翻译与例句:\n" +
+      "用户:书\n" +
+      "模型:\n" +
+      "\n" +
+      "翻译: book, paper (某些上下文中可指书面材料)\n" +
+      "例句:\n" +
+      "I bought a new book yesterday. (我昨天买了一本新书。)\n" +
+      "He wrote a letter on a piece of paper. (他在一张纸上写了封信。)\n" +
+      "英文单词翻译与例句:\n" +
+      "用户:apple\n" +
+      "模型:\n" +
+      "\n" +
+      "翻译: 苹果 (名词), 苹果公司 (名词)\n" +
+      "例句:\n" +
+      "I ate an apple this morning. (我今天早上吃了一个苹果。)\n" +
+      "Apple is a well-known technology company. (苹果公司是一个知名的科技公司。)\n" +
+      "请确保根据用户输入的语言(中文或英文)进行适当的翻译或解释。\n" +
+      "必须直接给出翻译结果,不要交互,不要任何其他信息。\n" +
+      "以下是用户输入:\n\n";
 
 
   const chinesePattern = new RegExp("[\u4E00-\u9FA5]+");
   const englishPattern = new RegExp("[A-Za-z]+");
 
   const search = () => {
-    loading.value = true
-    apis.requestDictionary({
-      q: content.value,
-      from: 'auto',
-      to: chinesePattern.test(content.value) ? 'zh-cn' : 'en'
-    }, 1, store.user.id)
-        .then((response:any) => {
-          // console.log('requestDictionary', response)
-          res.value = response.data.data
-          loading.value = false
+    // loading.value = true
+    // apis.requestDictionary({
+    //   q: content.value,
+    //   from: 'auto',
+    //   to: chinesePattern.test(content.value) ? 'zh-cn' : 'en'
+    // }, 1, store.user.id)
+    //     .then((response:any) => {
+    //       // console.log('requestDictionary', response)
+    //       res.value = response.data.data
+    //       loading.value = false
+    //     })
+    loading.value = true;
+
+    let requestBody:IDialogue[] = []
+    requestBody.push({
+      role: 'user',
+      content: promptTemplate + content.value
+    })
+
+    apis.requestAI("6718dffaee5b2137080707f5", "ChatGLM4", requestBody)
+        .then((_res:any) => {
+          let translation = _res.data.data.content;
+          console.log(translation)
+          res.value = translation
+        })
+        .catch((_err:any) => {
+          console.log(_err);
         })
+        .finally(() => {
+          loading.value = false;
+        });
   }
 
 

+ 4 - 4
src/views/HomeworkPage/index.vue

@@ -30,10 +30,10 @@
         暂无作业
       </template>
       <el-table-column type="index"/>
-      <el-table-column prop="assignmentName" label="课程名称" width="300"/>
-      <el-table-column prop="description" label="描述" width="400"/>
-      <el-table-column prop="endTime" label="截止时间" sortable  width="200"/>
-      <el-table-column prop="status" label="状态" sortable width="150"/>
+      <el-table-column prop="assignmentName" label="课程名称" width="400"/>
+      <!-- <el-table-column prop="description" label="描述" width="400"/> -->
+      <el-table-column prop="endTime" label="截止时间" sortable/>
+      <el-table-column prop="status" label="状态" sortable/>
       <el-table-column label="操作" width="100">
         <template #default="scope">
           <el-button @click="handleShowDetail(scope.row.assignmentId)" style="margin-right: 0; margin-left: 0;padding-left: 10px; padding-right: 10px" color="#597D3B">

+ 5 - 9
src/views/LoginPage/component/Register.vue

@@ -13,7 +13,7 @@
       <!--角色-->
       <el-form :rules="userRules" :model="userRegisterDTO" ref="formRef" :size="formSize">
         <el-form-item label="账号角色" prop="role">
-          <el-select v-model="userRegisterDTO.role" placeholder="请选择注册账号的角色">
+          <el-select v-model="userRegisterDTO.role" placeholder="请选择注册账号的角色,注意角色选定无法修改">
             <el-option v-for="item in roleOptions" :key="item.value" :label="item.label" :value="item.value"
               :disabled="item.disabled" />
           </el-select>
@@ -31,7 +31,7 @@
 
         <!--邮箱-->
         <el-form-item label="邮箱" prop="officialEmail">
-          <el-input v-model="userRegisterDTO.officialEmail" placeholder="例:5202024320xxx@smail.nju.edu.cn"></el-input>
+          <el-input v-model="userRegisterDTO.officialEmail" placeholder="例:xxx@smail.nju.edu.cn"></el-input>
         </el-form-item>
 
         <!--密码-->
@@ -84,13 +84,9 @@ const roleOptions = [
   {
     label: "教师",
     value: Role.TEACHER,
-    disabled: true
+    disabled: false
   },
-  {
-    label: "管理员",
-    value: Role.ADMIN,
-    disabled: true
-  }
+  
 ]
 
 const formSize = ref<ComponentSize>('default')
@@ -168,7 +164,7 @@ const sendVerifyCode = () => {
   apis.sendVerifyCode(userRegisterDTO.officialEmail)
     .then((res: any) => {
       ElMessage({
-        message: '验证码发送成功',
+        message: '验证码发送成功,请前往您的邮箱查看',
         type: 'success',
       })
     })