Ver código fonte

教师批改页面demo

xiaoyu 2 anos atrás
pai
commit
e6ba8d3257

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

@@ -1,7 +1,7 @@
 import axios from "axios";
 
 // const BASEURL = 'http://47.111.23.171:8081'
-const BASEURL = 'http://localhost:8080'
+const BASEURL = '/api'
 
 const axiosInstance = axios.create({
     baseURL: BASEURL,

+ 4 - 1
src/apis/engagement.ts

@@ -1,5 +1,5 @@
 import axiosInstance from "@/apis/axios.config";
-
+//提交的后端路径
 const ENGAGE_PREFIX = "/api/assignment/engage"
 
 const engagementApis = {
@@ -26,6 +26,7 @@ const engagementApis = {
             }
         })
     },
+    // 提交作业
     engagementSubmit: (studentId: number, assignmentId: number) => {
         return axiosInstance.put(ENGAGE_PREFIX+"/submit", {}, {
             params: {
@@ -34,6 +35,7 @@ const engagementApis = {
             }
         })
     },
+    // 暂存作业
     engagementStage: (studentId: number, assignmentId: number) => {
         return axiosInstance.put(ENGAGE_PREFIX+"/stage", {}, {
             params: {
@@ -42,6 +44,7 @@ const engagementApis = {
             }
         })
     },
+    //提交批改
     engagementCorrect: (studentId: number, assignmentId: number, correctDTO: {score: number, remark: string}) => {
         return axiosInstance.put(`${ENGAGE_PREFIX}/correct`, correctDTO, {
             params: {

+ 6 - 0
src/router/index.ts

@@ -61,6 +61,12 @@ const router = createRouter({
           name: 'edit',
           component: () => import('../views/EditPage/EditPage.vue')
         },
+        {
+          path: 'assignment/:assignmentId/correct',
+          name: 'correct',
+          component: () => import('../views/CorrectPage/CorrectPage.vue')
+        },
+
       ]
     },
   ]

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

@@ -0,0 +1,115 @@
+<!--
+  Description: 教师批改界面。
+  Author: XiaoYu
+  Created Date: 2024-7-24
+-->
+<template>
+
+    <div class="my-correct">
+      <!-- 写作题目 及 作文内容 -->
+      <div class="my-correct-header">
+        <!-- TODO:将标题和内容改为引用 ?如何从服务器中调取? -->
+        <StudentWritingRequirements/> 
+        <StudentEssay/> 
+      </div>
+      
+      <div class="right-side">
+        <!-- AI评分及写作过程记录:AI对话 字典查询 浏览器搜索 -->
+        <div class="my-correct-item">
+            <h2>AI评分:</h2><br>
+            <ContentSelector/>
+            
+
+        </div>
+        <!-- TODO:提交表单后的逻辑未写 -->
+        <RatingComponent/>
+        <!-- 教师评分、修改意见及评价 -->
+        <div class="my-correct-item">
+            <!-- TODO:将Edit改写乘Remark组件,明确提交逻辑 -->
+            <Remark :engagement="dataForm.engagement"/>              
+        </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 RatingComponent from "./component/RatingComponent.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 apis = useApis()
+const store = useStore()
+
+const dataForm = reactive<{
+  messages: IDialogue[],
+  dialogueId: string;
+  engagement: engagementVO
+}>({
+  messages: [],
+  dialogueId: '',
+  engagement: {} as engagementVO
+})
+
+// 获取数据
+async function fetchData(){
+  await apis.getAIDialogues(assignmentId, store.user.id)
+      .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(store.user.id, 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>

+ 68 - 0
src/views/CorrectPage/component/RatingComponent.vue

@@ -0,0 +1,68 @@
+<!--
+  Description: 批改界面中的评分小组件
+  Author: XiaoYu
+  Created Date: 2024-7-27
+-->
+
+<template>  
+    <div class="rating-component-container">  
+      <div class="rating-label">评分:</div>  
+      <input  
+        type="number"  
+        v-model="score"  
+        :min="1"  
+        :max="100"  
+        placeholder="请输入1~100的数字"  
+        class="rating-input"  
+      />  
+      <el-button type="success" class="submit-button" @click="submitScore">提交</el-button>
+    </div>  
+  </template>
+
+<script>  
+export default {  
+  data() {  
+    return {  
+      score: '', // 用户输入的分数  
+      showTooltip: false, // 控制鼠标悬停提示的显示  
+    };  
+  },  
+  methods: {  
+    submitScore() {  
+      if (this.score >= 1 && this.score <= 100) {  
+        //TODO: 这里可以添加提交分数的逻辑,比如发送到服务器
+          
+        alert(`提交的分数是:${this.score}`);  
+      } else {  
+        alert('请输入有效的分数(1到100之间)');  
+      }  
+    },  
+  },  
+};  
+</script>
+
+<style scoped>  
+.rating-component-container {  
+  display: flex; /* 应用Flexbox布局 */  
+  align-items: center; /* 垂直居中子元素 */   
+  padding: 10px;  
+  border: 1px solid #ccc;  
+  border-radius: 5px;  
+}  
+  
+.rating-label {  
+  margin-right: 10px; /* 右侧间距,以便输入框不会紧贴着文字 */  
+}  
+  
+.rating-input {  
+  /* 输入框的样式 */  
+  width: 300px;
+  padding: 8px;  
+  margin-right: 100px; /* 右侧间距,以便按钮不会紧贴着输入框 */  
+}  
+  
+.submit-button {  
+  /* 提交按钮的样式 */  
+ 
+}  
+</style>

+ 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);
+        height: 40%;
+        //border: 1px solid black;
+        background-color: #fff;
+        
+      }
+
+
+    }
+
+    
+    
+    
+    
+}

+ 101 - 0
src/views/Home/component/ContentSelector/ContentSelector.vue

@@ -0,0 +1,101 @@
+<!--
+  Description: 批改界面中 用于显示写作过程记录的组件
+  Author: XiaoYu
+  Created Date: 2024-7-27
+-->
+<template>  
+  <div class="content-selector">  
+    <!-- 按钮组 -->  
+    <div class="button-group">
+      <el-button type="success" class="submit-button" @click="selectContent(0)">AI对话</el-button>
+      <el-button type="success" class="submit-button" @click="selectContent(1)">字典查询</el-button>
+      <el-button type="success" class="submit-button" @click="selectContent(2)">浏览器搜索</el-button>  
+    </div>  
+  
+    <!-- 内容输入框,带有实线边框 -->  
+    <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>  
+      </div>  
+    </div>  
+  </div>  
+</template>
+
+<script>  
+export default {  
+  name: 'ContentSelector', // 组件名称  
+  data() {  
+    return {  
+      // selectedContent用于跟踪当前选中的内容索引  
+      selectedContent: 0,  
+    };  
+  },  
+  methods: {  
+    // selectContent方法用于更新selectedContent的值  
+    selectContent(index) {  
+      this.selectedContent = index;  
+    },  
+  },  
+};  
+</script>
+
+
+
+<style scoped>
+
+.content-selector {  
+  display: flex;  
+  align-items: flex-start; /* 确保按钮和内容输入框垂直对齐 */  
+  padding: 20px;  
+}  
+  
+.button-group {  
+  display: flex;  
+  flex-direction: column; /* 设置为竖向排列 */  
+  margin-right: 20px; /* 与内容输入框之间保持一定距离 */  
+}   
+  
+.button-group button {  
+  margin: 5px 0;  
+  padding: 10px 20px;  
+  font-size: 16px;  
+  cursor: pointer;  
+  border-radius: 5px;  
+}  
+  
+.button-group button:hover {  
+  background-color: #e0e0e0;  
+}  
+  
+.content-input-box {  
+  flex-grow: 1; /* 占据剩余空间 */  
+  border: 2px solid #ccc; /* 实线边框 */  
+  padding: 10px;  
+  border-radius: 5px;  
+  position: relative; /* 为内部元素定位做准备(如果需要的话) */  
+}  
+  
+.content-item {  
+  /* 这里不需要特别的样式,除非你想对每个内容项进行特定的样式设置 */  
+}  
+  
+.input-area {  
+  width: 100%; /* 宽度占满内容输入框 */  
+  height: 100px; /* 示例高度,可以根据需要调整 */  
+  border: none; /* 移除默认的textarea边框 */  
+  resize: none; /* 禁止用户调整大小 */  
+  background-color: #f9f9f9; /* 可选的背景色 */  
+  padding: 10px;  
+  box-sizing: border-box; /* 使得padding和border不会增加元素的宽度 */  
+}  
+
+
+</style>

+ 46 - 0
src/views/Home/component/ContentSelector/index.scss

@@ -0,0 +1,46 @@
+
+.content-selector {  
+  display: flex;  
+  align-items: flex-start; /* 确保按钮和内容输入框垂直对齐 */  
+  padding: 20px;  
+}  
+  
+.button-group {  
+  margin-right: 20px;  
+}  
+  
+.button-group button {  
+  margin: 5px 0;  
+  padding: 10px 20px;  
+  font-size: 16px;  
+  cursor: pointer;  
+  background-color: lightgreen;  
+  border: 1px solid lightgray;  
+  border-radius: 5px;  
+}  
+  
+.button-group button:hover {  
+  background-color: #e0e0e0;  
+}  
+  
+.content-input-box {  
+  flex-grow: 1; /* 占据剩余空间 */  
+  border: 2px solid #ccc; /* 实线边框 */  
+  padding: 10px;  
+  border-radius: 5px;  
+  position: relative; /* 为内部元素定位做准备(如果需要的话) */  
+}  
+  
+.content-item {  
+  /* 这里不需要特别的样式,除非你想对每个内容项进行特定的样式设置 */  
+}  
+  
+.input-area {  
+  width: 100%; /* 宽度占满内容输入框 */  
+  height: 100px; /* 示例高度,可以根据需要调整 */  
+  border: none; /* 移除默认的textarea边框 */  
+  resize: none; /* 禁止用户调整大小 */  
+  background-color: #f9f9f9; /* 可选的背景色 */  
+  padding: 10px;  
+  box-sizing: border-box; /* 使得padding和border不会增加元素的宽度 */  
+}  

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

@@ -0,0 +1,139 @@
+<!--
+  Description: 批改页面教师评论框,改写自Edit,内含onlyoffice
+  Author: XiaoYu
+  Created Date: 2024-7-28
+-->
+<template>
+    <div class="remark">
+  <!--    <el-message :message="messageApi"></el-message>-->
+      <div class="remark-box">
+        <div>修改意见及评价</div>
+        <div class="remark-root">
+          <WordEditor
+              @value-change="handleValueChange"
+              :document-key="engagement?.fileKey"
+              :document-title="data.fileTitle"
+              :document-url="engagement?.fileUrl"
+              :user-id="store.user.id"
+              :username="store.user.name"
+          ></WordEditor>
+        </div>
+        <div class="button-right">
+          <el-button type="primary" @click="handleSubmit">提交</el-button>
+          <el-button type="primary" @click="handleStage">暂存</el-button>
+        </div>
+      </div>
+    </div>
+  </template>
+  
+  <script lang="ts" setup>
+    import "./index.scss";
+    import type {engagementVO} from "@/types/vo";
+    import {defineProps, onMounted, reactive} from 'vue'
+    import router from '@/router'
+    import useApis from "@/apis";
+    import {useStore} from "@/store";
+    import {ElMessage} from "element-plus";
+    import WordEditor from "@/components/WordEditor/WordEditor.vue";
+  
+    interface IEditProps {
+      engagement: engagementVO
+    }
+  
+    const props = defineProps<{
+      engagement: engagementVO
+    }>()
+  
+    const apis = useApis()
+    const store = useStore()
+    const messageApi = ElMessage;
+  
+    const data = reactive<{
+      isModified: boolean,
+      hasModified: boolean,
+      isModalOpen: boolean,
+      fileTitle: string,
+    }>({
+      isModified: false,
+      hasModified: false,
+      isModalOpen: false,
+      fileTitle: '',
+    });
+  
+    // 设置文件标题
+    onMounted(() => {
+      data.fileTitle = `${store.user.name}_第一次作业.docx`;
+    });
+  
+    // 成功操作的消息提示
+    const success = (msg: string) => {
+      messageApi.success(msg);
+    };
+  
+    // 失败操作的消息提示
+    const error = (msg: string) => {
+      console.log('失败操作', msg);
+      messageApi.error(msg);
+    };
+  
+    // 处理内容修改事件
+    // 用于检查,onlyoffice文本框是否被修改(同步的)
+    const handleValueChange = (state: boolean) => {
+      if (state) data.hasModified = true;
+      data.isModified = state;
+    };
+  
+    // 提交操作
+    const handleSubmit = () => {
+      // 内容已保存,且已经修改过,则可以点击提交
+      if (!data.isModified && data.hasModified) {
+        //TODO:批改提交缺studentID
+        //apis.engagementCorrect()
+        apis.engagementSubmit(store.user.id, 1)
+            .then((_res: any) => {
+              console.log(_res);
+              success(_res.data.data);
+              router.push("/home/myHomework")
+            })
+            .catch((error: any) => {
+              console.error('提交失败', error);
+              error('提交失败');
+            });
+      } else if (data.isModified) {
+        error('编辑内容未保存,请保存后提交!');
+      } else if (!data.hasModified) {
+        error('尚未编辑,不可提交!');
+      } else {
+        error('未知错误!');
+      }
+    };
+  
+    // 暂存操作
+    const handleStage = () => {
+      if (!data.isModified && data.hasModified) {
+        apis.engagementStage(store.user.id, 1)
+            .then((_res: any) => {
+              console.log(_res);
+              success(_res.data.data);
+            })
+            .catch((error: any) => {
+              console.error('暂存失败', error);
+              error('暂存失败');
+            });
+      } else if (data.isModified) {
+        error('编辑内容未保存,请保存后提交!');
+      } else if (!data.hasModified) {
+        error('尚未编辑,不可提交!');
+      } else {
+        error('未知错误!');
+      }
+    };
+  </script>
+  
+  <script lang="ts">
+  export default {
+    name: "Remark"
+  }
+  </script>
+  
+  

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

@@ -0,0 +1,47 @@
+.remark {
+    
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+  }
+  
+  .down {
+    text-align: right;
+  }
+  
+  .remark-box {
+    
+    max-height: 100%;
+    display: flex;
+    gap: 10px;
+    margin-top: 10px;
+    flex-direction: column;
+    height: 100%;
+  }
+  
+  
+  .button-right {
+    display: flex;
+    gap: 20px;
+    justify-content: flex-end;
+  
+  }
+  
+  
+  .edit-toolbar-box {
+    height: 300px;
+    overflow: auto;
+    width: 100%;
+  }
+  
+  .remark-root {
+    border: solid 1px rgba(199, 199, 199, 0.3);
+    height: 100%;
+  }
+  
+  .edit-box-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
+  

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

@@ -0,0 +1,90 @@
+<!--
+  Description: 学生提交的作文内容组件
+  Author: XiaoYu
+  Created Date: 2024-7-24
+-->
+
+
+<template>
+
+  <div class="student-essay">
+    <div class="student-essay-info">
+      <div class="student-essay-text">
+
+        <div class="title">学生作文</div>
+        <div class="item">
+                <span style="font-weight: 600">学生ID: </span>
+                {{data.studentId}}
+        </div>
+
+        <div class="text">
+          
+        <!-- TODO:学生作文暂时不知道怎么调,写了个临时文件exampleText.txt -->
+         <!-- <p>{{ textContent }}</p> -->
+         <p v-html="textContent"></p>
+        </div>
+        
+      </div>
+      
+
+    </div>
+    
+    
+  </div>
+</template>
+
+
+
+
+<script lang="ts" setup>
+import useApis from "@/apis";
+import {useRoute} from "vue-router";
+import {onMounted, reactive, ref} from "vue";
+import type {engagementVO} from "@/types/vo";
+import './studentEssay.scss'
+import exampleText from './exampleText.txt'; 
+
+
+const apis = useApis()
+const route = useRoute()
+const assignmentId = +route.params.assignmentId //string转number
+const studentId = +route.params.studentId//string转number
+const textContent = ref(exampleText);
+
+let data = reactive<engagementVO>({
+  id: null,
+  assignmentId: null,
+  studentId: null,
+  score: null,
+  remark: "",
+  fileUrl: "",
+  version: 0,
+  status: "",
+  fileKey: ""
+})
+
+
+
+const fetchData = () => {
+  apis.getEngagement(studentId, assignmentId)
+      .then((res: any) => {
+        Object.assign(data, res.data.data)
+      })
+}
+
+onMounted(() => {
+  fetchData()
+})
+</script>
+
+
+
+<script lang="ts">
+
+export default {
+  name: "StudentEssay"
+}
+</script>
+
+
+

+ 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>
+  
+  
+  
+  

+ 1 - 0
src/views/Home/component/StudentEssay/exampleText.txt

@@ -0,0 +1 @@
+Exploring the heart of Rural China, we turn our gaze to the fertile grounds of Jiangsu, a province renowned for its timeless beauty akin to the fabled landscapes of Suzhou and Hangzhou. Here, the land nurtures generations with a rich agricultural heritage, where rice paddies glisten under the sun, vegetables thrive in lush gardens, and the fragrance of harvest fills the air. Jiangsu's soil, a testament to China's agricultural prowess, not only sustains its people but also showcases the ingenuity and resilience embedded in every inch of this cherished land.

+ 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 {
+      }
+    }
+
+  }

+ 3 - 0
src/views/LoginPage/LoginPage.vue

@@ -3,6 +3,9 @@
   Author: BaiQi
   Created Date: 2024-6-28
 -->
+<!-- 学生:181250126 xiaosuniubi
+教师:181250127 xiaosuniubi -->
+
 <template>
   <div class="login-container">
     <div class="container-box">

+ 12 - 4
vite.config.ts

@@ -5,6 +5,18 @@ import vue from '@vitejs/plugin-vue'
 
 // https://vitejs.dev/config/
 export default defineConfig({
+  //配置代理,解决跨域问题。详见EAI问题文档
+  server: {
+    host: '127.0.0.1',
+    port: 4000,
+    proxy: {
+      '/api': {  
+        target: 'http://localhost:8080',
+        changeOrigin: true,
+        rewrite: (path) => path.replace(/^\/api/, ''),
+      },
+    },
+  },
   plugins: [
     vue(),
   ],
@@ -12,9 +24,5 @@ export default defineConfig({
     alias: {
       '@': fileURLToPath(new URL('./src', import.meta.url))
     }
-  },
-  server: {
-    host: '127.0.0.1',
-    port: 4000
   }
 })