Jelajahi Sumber

feat:完成作文内容存储与展示

白白 1 tahun lalu
induk
melakukan
e470edb7f9

+ 55 - 8
src/components/QuillEditor/Editor.vue

@@ -5,25 +5,31 @@
                  v-model:content="data.content"
                  :options="data.editorOption"
                  contentType="delta"
+                 @update:content="setValue()"
     />
   </div>
 </template>
 
-<script setup>
-  import { QuillEditor, Quill } from '@vueup/vue-quill'
+<script setup lang="ts">
+import {QuillEditor, Quill, Delta} from '@vueup/vue-quill'
   import { reactive, onMounted, ref, toRaw, watch, defineProps } from 'vue'
   import '@vueup/vue-quill/dist/vue-quill.snow.css'
   import emitter from '@/utils/emitter'
   import dayjs from 'dayjs'
-
+  import useApis from "@/apis";
+  import {useRoute} from "vue-router";
+  import {useStore} from "@/store";
+  import type {engagementVO} from "@/types/vo.js";
+
+  const apis = useApis()
+  const store = useStore()
+  const route = useRoute();
   const props = defineProps(['value', 'onTextChangeRef', 'onSelectionChangeRef', 'onGetHTML', 'onGetText', 'onGetQuill'])
-  const emit = defineEmits(['updateValue'])
 
-  const content = ref('')
+  const assignmentId = Number(route.params.assignmentId);
   const myQuillEditorRef = ref()
-
   const data = reactive({
-    content: ``,
+    content: {},
     editorOption: {
       modules: {
         toolbar: [
@@ -43,6 +49,16 @@
     }
   })
 
+  // 抛出更改内容
+  const setValue = () => {
+    const html = toRaw(myQuillEditorRef.value).getHTML()
+    emitter.emit('get-html', html)
+    const text = toRaw(myQuillEditorRef.value).getText()
+    emitter.emit('get-text', text)
+    const content1 = toRaw(myQuillEditorRef.value).getContents()
+    emitter.emit('get-quill-content', content1)
+  }
+
   /**
    * 合并所有insert内容,因为存在attribute的缘故,原内容被分割成很多个insert
    * @param ops
@@ -82,11 +98,14 @@
       Object.assign(props.onTextChangeRef, {...args})
 
       if(deleteOps.length > 0){ //删除操作
+        console.log(delta.ops)
         // 获取删除操作的位置和长度
-        const deleteStart = delta.ops.find(op => 'delete' in op).retain || 0;   // 删除起始位置
+        const deleteStart = delta.ops.find(op => 'retain' in op).retain || 0;   // 删除起始位置
         const deleteLength = delta.ops.find(op => 'delete' in op).delete;       // 删除长度
         const oldContent = processOps(args["1"].ops)// 原内容
         // 提取被删除的具体内容
+        console.log(deleteStart)
+        console.log(deleteLength)
         const deletedContent = oldContent.slice(deleteStart, deleteStart + deleteLength);
 
         emitter.emit('change-record', {
@@ -122,13 +141,41 @@
     });
   }
 
+  const fetchData = () => {
+    apis.getEngagement(store.user.id, assignmentId)
+        .then(res => {
+          const engagementData = res.data.data;
+          const engagement: engagementVO = Object.assign({}, engagementData);
+
+          // data.content = engagement.textContent
+          // const rawEditor = toRaw(myQuillEditorRef.value);
+          // rawEditor.setContents(data.content); // 强制设置内容
+
+          if(engagement.quillContent != null){
+            data.content = new Delta(JSON.parse(engagement.quillContent));
+            const rawEditor = toRaw(myQuillEditorRef.value);
+            rawEditor.setContents(data.content); // 强制设置内容
+          }
+        })
+        .catch(err => {
+          console.log(err)
+        })
+  }
+
 // 初始化编辑器
   onMounted(() => {
     initQuill()
+    fetchData()
   });
 
 </script>
 
+<script lang="ts">
+  export default {
+    name: "Editor"
+  }
+</script>
+
 <style scoped lang="scss">
 // 调整样式
 .main-container {

+ 1 - 3
src/components/QuillEditor/QuillEditor.vue

@@ -28,9 +28,7 @@
 
   let range = reactive({})
   let lastChange = reactive({})
-  let getHTML = ref("")
-  let getText = ref("")
-  let getQuillContent = reactive({})
+
 
   // 新增:用于存储每个按键的down事件信息
   let keyEventMap = reactive({})

+ 74 - 55
src/views/Home/component/Edit/index.vue

@@ -11,8 +11,8 @@
         <QuillEditor/>
       </div>
       <div class="button-right">
-        <el-button type="primary" @click="handleSubmit">提交</el-button>
-        <el-button type="primary" @click="handleStage">暂存</el-button>
+        <el-button type="primary" @click="handleSubmit" :disabled="useBtn">提交</el-button>
+        <el-button type="primary" @click="handleStage" :disabled="useBtn">暂存</el-button>
       </div>
     </div>
   </div>
@@ -20,14 +20,16 @@
 
 <script lang="ts" setup>
   import "./index.scss";
-  import type {engagementVO} from "@/types/vo";
-  import {defineProps, onMounted, reactive} from 'vue'
+  import type {engagementVO, IAssignment} from "@/types/vo";
+  import {defineProps, onMounted, reactive, ref} from 'vue'
   import router from '@/router'
   import useApis from "@/apis";
   import {useStore} from "@/store";
   import {ElMessage} from "element-plus";
   import emitter from "@/utils/emitter";
   import QuillEditor from "@/components/QuillEditor/QuillEditor.vue";
+  import {useRoute} from "vue-router";
+  import dayjs from "dayjs";
 
   interface IEditProps {
     engagement: engagementVO
@@ -39,49 +41,56 @@
 
   const apis = useApis()
   const store = useStore()
-  const messageApi = ElMessage;
 
-  const data = reactive<{
-    isModified: boolean,
-    hasModified: boolean,
-    isModalOpen: boolean,
-    fileTitle: string,
+  let hasStage = ref(true)
+  let data = reactive<{
+    assignment: IAssignment
   }>({
-    isModified: false,
-    hasModified: false,
-    isModalOpen: false,
-    fileTitle: '',
-  });
+    assignment: {} as IAssignment
+  })
+  const route = useRoute()
+  const assignmentId = Number(route.params.assignmentId)
+  let useBtn = ref(true)
 
-  // 设置文件标题
-  onMounted(() => {
-    data.fileTitle = `${store.user.name}_作业.docx`;
-  });
+  let getHTML = ref("")
+  let getText = ref("")
+  let getQuillContent = reactive({})
+
+  emitter.on('get-html', (value: string) => {
+    getHTML.value = value
+  })
+
+  const contentTest = ref('')
+  emitter.on('get-text', (value: string) => {
+    getText.value = value
+  })
+
+  emitter.on('get-quill-content', (value: Object) => {
+    Object.assign(getQuillContent, value)
+  })
 
   // 成功操作的消息提示
   const success = (msg: string) => {
-    messageApi.success(msg);
+    ElMessage.success(msg);
   };
 
   // 失败操作的消息提示
   const error = (msg: string) => {
     console.log('失败操作', msg);
-    messageApi.error(msg);
-  };
-
-  // 处理内容修改事件
-  // 用于检查,onlyoffice文本框是否被修改(同步的)
-  // 修改state为true,保存后变为false
-  const handleValueChange = (state: boolean) => {
-    data.isModified = state
-    data.hasModified = !state;
-    emitter.emit("is-modified", state)
+    ElMessage.error(msg);
   };
 
   // 提交操作
   const handleSubmit = () => {
-    // 内容已保存,且已经修改过,则可以点击提交
-    // if (!data.isModified && data.hasModified) {
+    // 内容已保存,则可以点击提交
+    if (hasStage.value == true) {
+      const endTime = dayjs(data.assignment.endTime); // 假设截止时间在 assignment 的 endTime 属性中
+      const currentTime = dayjs();
+      if (currentTime.isAfter(endTime)) {
+        ElMessage.error('作业已截止,无法提交!');
+        return;
+      }
+      hasStage.value = false
       apis.engagementSubmit(store.user.id, props.engagement.assignmentId, )
           .then((_res: any) => {
             success(_res.data.data);
@@ -91,33 +100,27 @@
             console.error('提交失败', error);
             error('提交失败');
           });
-    // } else if (data.isModified) {
-    //   error('编辑内容未保存,请保存后提交!');
-    // } else if (!data.hasModified) {
-    //   error('尚未编辑,不可提交!');
-    // } else {
-    //   error('未知错误!');
-    // }
+    } else {
+      ElMessage.error('编辑内容未保存,请保存后提交!');
+    }
   };
 
   // 暂存操作
   const handleStage = () => {
-    // if (!data.isModified && data.hasModified) {
-      apis.engagementStage(store.user.id, props.engagement.assignmentId, `{ "ops": [ { "insert": "12334\n" } ] }`, `12334`, "<p>12334</p>")
-          .then((_res: any) => {
-            success(_res.data.data);
-          })
-          .catch((error: any) => {
-            console.error('暂存失败', error);
-            error('暂存失败');
-          });
-    // } else if (data.isModified) {
-    //   error('编辑内容未保存,请保存后暂存!');
-    // } else if (!data.hasModified) {
-    //   error('尚未编辑,不可暂存!');
-    // } else {
-    //   error('未知错误!');
-    // }
+    const endTime = dayjs(data.assignment.endTime); // 假设截止时间在 assignment 的 endTime 属性中
+    const currentTime = dayjs();
+    if (currentTime.isAfter(endTime)) {
+      ElMessage.error('作业已截止,无法暂存!');
+      return;
+    }
+    apis.engagementStage(store.user.id, props.engagement.assignmentId, JSON.stringify(getQuillContent), getText.value, getHTML.value)
+        .then((_res: any) => {
+          success(_res.data.data);
+        })
+        .catch((error: any) => {
+          console.error('暂存失败', error);
+          error('暂存失败');
+        });
   };
 
   // window.onbeforeunload = function(event) {
@@ -136,6 +139,22 @@
   //   e.returnValue = '您编辑的信息尚未保存,您确定要离开吗?';
   // });
 
+  const fetchData = () => {
+    apis.getAssignmentById(assignmentId).then((res: any) => {
+      data.assignment = res.data.data;
+      const endTime = dayjs(data.assignment.endTime); // 假设截止时间在 assignment 的 endTime 属性中
+      const currentTime = dayjs();
+      console.log(currentTime.isBefore(endTime))
+      if (currentTime.isBefore(endTime)) {
+        useBtn.value = false
+      }
+    });
+  };
+
+  onMounted(() => {
+    fetchData()
+  });
+
 
 </script>
 

+ 0 - 17
src/views/Home/component/Silder/index.vue

@@ -171,23 +171,6 @@ import * as path from "node:path";
   // 请求批改
   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()
   };
 

+ 0 - 1
src/views/HomeworkPage/component/HomeworkDetail.vue

@@ -93,7 +93,6 @@ function downloadFile(url:string, fileName:string) {
 async function getEngagement(){
   apis.getEngagement(store.user.id, assignmentId)
       .then((_res:any) => {
-        console.log(_res)
         //还未参加作业,则先加入作业
         if(_res.data.data == null){
           apis.engageAssignment(assignmentId)