소스 검색

作品评分

lvmax 9 달 전
부모
커밋
496025dc23
5개의 변경된 파일727개의 추가작업 그리고 495개의 파일을 삭제
  1. 217 406
      package-lock.json
  2. 3 1
      package.json
  3. 3 0
      src/api/work/score/index.ts
  4. 3 1
      src/main.ts
  5. 501 87
      src/views/work/score/index.vue

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 217 - 406
package-lock.json


+ 3 - 1
package.json

@@ -31,7 +31,7 @@
     "@iconify/iconify": "^3.1.1",
     "@microsoft/fetch-event-source": "^2.0.1",
     "@videojs-player/vue": "^1.0.0",
-    "@vue-office/pdf": "^2.0.2",
+    "@vue-office/pdf": "^2.0.6",
     "@vueuse/core": "^10.9.0",
     "@wangeditor/editor": "^5.1.23",
     "@wangeditor/editor-for-vue": "^5.1.10",
@@ -69,8 +69,10 @@
     "url": "^0.11.3",
     "video.js": "^7.21.5",
     "vue": "3.4.21",
+    "vue-demi": "^0.14.6",
     "vue-dompurify-html": "^4.1.4",
     "vue-i18n": "9.10.2",
+    "vue-pdf": "^4.3.0",
     "vue-pdf-embed": "^2.1.0",
     "vue-router": "^4.3.0",
     "vue-types": "^5.1.1",

+ 3 - 0
src/api/work/score/index.ts

@@ -28,6 +28,9 @@ export const ScoreApi = {
   // 修改作品评分
   updateScore: async (data: ScoreVO) => {
     return await request.put({ url: `/work/score/update`, data })
+  }, // 修改作品评分
+  updateScoreStatus: async (data: ScoreVO) => {
+    return await request.put({ url: `/work/score/status`, data })
   },
 
   // 删除作品评分

+ 3 - 1
src/main.ts

@@ -41,7 +41,9 @@ import '@/plugins/tongji' // 百度统计
 import Logger from '@/utils/Logger'
 
 import VueDOMPurifyHTML from 'vue-dompurify-html' // 解决v-html 的安全隐患
-
+//2024年10月14日20:03:01 锚点
+import ElementPlus from 'element-plus'
+import 'element-plus/theme-chalk/index.css'
 // 创建实例
 const setupAll = async () => {
   const app = createApp(App)

+ 501 - 87
src/views/work/score/index.vue

@@ -1,88 +1,417 @@
 <template>
+  <div class="common-layout" style="width: 100%" v-loading="loading">
+    <el-container v-if="pageAndPage">
+      <el-aside width="300" style="margin-right: 10px;margin-top: 20px">
+
+        <el-card class="infinite-list"
+                 style="margin: auto;width: 300px;max-height:700px;min-height:80px;padding: 1px">
+          <div style="width:200px;margin: auto">
+            作品类型
+          </div>
+          <el-menu
+            active-text-color="#ffd04b"
+            style="overflow-y:auto;padding: 1px"
+            default-active="2"
+            text-color="#000"
+          >
+            <el-radio-group v-model="startType">
+              <template v-for="(o)  in typeList" :key="o">
+                <el-menu-item style="width: 250px">
+                  <el-radio :value="o" :label="o" border>{{ o.typeName }}</el-radio>
+                  <br/>
+                </el-menu-item>
+              </template>
+            </el-radio-group>
+          </el-menu>
 
-  <div class="common-layout" style="width: 100%">
-    <el-container >
-      <el-aside width="300" style="margin-right: 10px">
-        <div style="width:200px;margin: auto">
-          作品类型
-        </div>
-        <el-divider style="width:220px;margin-top: 15px;margin-bottom: 5px"/>
-        <el-card class="infinite-list" style="margin: auto;width: 200px;max-height:700px;min-height:80px;overflow-y:auto">
-          <el-tree
-            style="max-width: 280px;"
-            :data="typeList"
-            :props="defaultProps"
-            @node-click="handleNodeClick"
-          />
         </el-card>
+
       </el-aside>
       <el-main>
-        <el-row>
-          <el-col :span="3" style="background-color: white;padding: 10px;margin-right: 10px">
-            <el-table v-loading="loading" :data="workList" :stripe="true"
-                      :show-overflow-tooltip="true" style="height:700px">
-              <el-table-column label="作品" align="left" prop="workName">
-                <template #default="scope">
-                  <el-button
-                    link
-                    @click="lookWork(scope.row)"
-                    type="primary"
-                  >
-                    {{ scope.row.workName }}
-                  </el-button>
-                </template>
-              </el-table-column>
-            </el-table>
+        <el-row style="background-color: #ffffff;min-width: 840px">
+          <el-col :span="8" style="padding: 20px;">
+            <el-card style="height: 100px;">
+              总作品数量
+            </el-card>
           </el-col>
-          <el-col :span="16" style="background-color: white;padding: 10px;margin-right: 10px">
-            <el-row>
-              <el-col :span="16">
-                <p>正在评分作品:{{ file.workName }}</p>
-                <audio v-if="file.format==='mp3'" :src="file.url" controls>
-                </audio>
-                <video v-if="file.format==='mp4'"
-                       :src="file.url" controls></video>
-                <img v-if="file.format==='jpg'||file.format==='png'"
-                     :src="file.url" alt=""/>
-                <div v-if="file.format==='pdf'">
-                  <VueOfficePddf :src="file.url" class="docx-class"/>
-                </div>
-              </el-col>
-              <el-col :span="8">
-                <div v-if="file.manuscriptAndMaterial!==''">
-                  <VueOfficePddf :src="file.manuscriptAndMaterial" class="docx-class"/>
-                </div>
-              </el-col>
-            </el-row>
+          <el-col :span="8" style="padding: 20px;">
+            <el-card style="height: 100px;">
+              已评作品数量
+            </el-card>
+          </el-col>
+          <el-col :span="8" style="padding: 20px;">
+            <el-card style="height: 100px;">
+              未评作品数量
+            </el-card>
           </el-col>
         </el-row>
+        <div style="font-size: 30px;margin-top: 15px;text-align: center">
+          当前选择评卷类别:{{ startType.typeName }}
+        </div>
+        <br/>
+        <el-row style="background-color: #ffffff;margin-top: 10px;min-width: 840px">
+
+          <el-col :span="12" style="padding: 20px;">
+            <el-button type="primary"
+                       style="width: 100%;height: 400px;font-size: 90px;min-width: 400px"
+                       @click="handleNodeClick">
+
+              开始评分
+
+            </el-button>
+          </el-col>
+          <el-col :span="12" style="padding: 20px">
+            <el-button style="width: 100%;height: 400px;font-size: 90px;min-width: 400px">
+              查看详情
+            </el-button>
+          </el-col>
+        </el-row>
+
+
+        <!--======================================================================================================-->
+
       </el-main>
     </el-container>
-  </div>
 
+    <el-container v-if="!pageAndPage">
+      <el-aside width="300" style="margin-right: 10px">
+        <el-card class="infinite-list"
+                 style="margin: auto;width: 300px;max-height:700px;min-height:80px;padding: 1px">
+          <div style="width:200px;margin: auto">
+            作品名称
+          </div>
+          <el-menu
+            active-text-color="#ffd04b"
+            style="overflow-y:auto;padding: 1px;height: 680px"
+            default-active="2"
+            text-color="#000"
+          >
+            <el-radio-group v-model="lookWorkOne">
+              <template v-for="(o)  in workList" :key="o">
+                <el-menu-item
+                  :style="'width: 250px;background-color:'+(o.scoreDO.score!==null?'#b6f1bf':'#ffffff')">
+                  <el-radio @click="lookWork(o)" :value="o" :label="o" border>{{
+                      o.workName
+                    }}
+                  </el-radio>
+                  <br/>
+                </el-menu-item>
+              </template>
+            </el-radio-group>
+          </el-menu>
+
+        </el-card>
+
+      </el-aside>
+      <el-container style="background-color: #ffffff">
 
+        <el-header style="justify-content:center; display: flex;height: 20px">
+          <el-radio-group size="large" v-model="tabPosition" style="width: 800px">
+            <el-radio-button value="当前作品" @click="scrollToSection('chapter1')">当前作品
+            </el-radio-button>
+            <el-radio-button value="文稿材料" @click="scrollToSection('chapter2')">文稿材料
+            </el-radio-button>
+          </el-radio-group>
+        </el-header>
+        <el-main>
+          <el-row>
+            <el-col :span="17"
+                    style="height: 670px;background-color: white;margin: auto 5px auto 5px">
+              <el-scrollbar ref="scrollContainer"
+                            style="width: 100% ;height: 670px;overflow-y: auto;">
+
+
+                <div style="width: 90%;margin: 30px auto auto;">
+
+
+                  <div id="chapter1">当前作品名:{{ file.workName }}</div>
+                  <div style="max-width: 800px">
+                    <audio v-if="file.format==='mp3'" :src="file.url" controls>
+                    </audio>
+                  </div>
+
+                  <video v-if="file.format==='mp4'"
+                         :src="file.url" style="max-width: 700px" controls></video>
+                  <img v-if="file.format==='jpg'||file.format==='png'"
+                       :src="file.url" style="max-width: 800px" alt=""/>
+                  <div v-if="file.format==='pdf'">
+                    <VueOfficePdf :src="file.url" style="max-width: 800px" class="docx-class"/>
+                  </div>
+                  <div id="chapter2">
+                    当前材料:{{
+                      file.manuscriptAndMaterial.split("/")[file.manuscriptAndMaterial.split("/").length - 1]
+                    }}
+                  </div>
+                  <el-scrollbar v-if="file.manuscriptAndMaterial!==''"
+                                style="max-width: 850px;max-height: 1000px;overflow-y: auto;">
+                    <VueOfficePdf :src="file.manuscriptAndMaterial" style="height: 670px"/>
+                  </el-scrollbar>
+                </div>
+              </el-scrollbar>
+            </el-col>
+            <el-col :span="6" style="background-color: white;margin-left: 10px">
+              <el-row style="margin-top: 20px">
+                <el-form-item label="评分" style="margin-top: 20px">
+                  <el-input v-model="formDataScope.score" @change="submitScope"
+                            placeholder="请输入评分"/>
+                </el-form-item>
+              </el-row>
+              <el-row>
+                <el-col :span="8" class="button-padd">
+                  <el-button @click="backScope"
+                             type="primary">上一个
+                  </el-button>
+                </el-col>
+                <el-col :span="8" class="button-padd">
+                  <el-button @click="nextScope"
+                             type="primary">下一个
+                  </el-button>
+                </el-col>
+                <el-col :span="8" class="button-padd">
+                  <el-button @click="returnScope"
+                             type="primary">返回
+                  </el-button>
+                </el-col>
+
+
+              </el-row>
+              <el-row>
+                <el-col :span="24" class="button-padd">
+                  <el-button @click="visible=true"
+                             type="primary">提交
+                  </el-button>
+                </el-col>
+              </el-row>
+            </el-col>
+          </el-row>
+
+        </el-main>
+      </el-container>
+    </el-container>
+
+
+    <!--=======================================    -->
+
+
+  </div>
+  <el-dialog title="签字板" v-model="visible" width="1000px" append-to-body>
+    <canvas @mousemove="canvasMove" @mouseup="canvasUp" ref="canvas" width="1000" height="500"
+            @mousedown="mousedown" @mouseleave="canvasLeave"></canvas>
+    <!--    <template #footer>-->
+    <div class="dialog-footer">
+      <el-button type="primary" @click="handleSave">保 存</el-button>
+      <el-button @click="handleClear">重 置</el-button>
+    </div>
+    <!--    </template>-->
+  </el-dialog>
   <!-- 表单弹窗:添加/修改 -->
-  <ScoreForm ref="formRef" @success="getList"/>
 </template>
 
 <script setup lang="ts">
-import type {TabsInstance} from 'element-plus'
-import {dateFormatter} from '@/utils/formatTime'
+
+import {c} from "vite/dist/node/types.d-jgA8ss1A";
+
+const visible = ref(false)
+const isDown = ref(false) // 是否可以绘制
+const canvas = ref(null) // canvas 元素
+const ctx = ref(null) // ctx承接上下文
+
+// 鼠标按下
+const mousedown = (e) => {
+  let {offsetX, offsetY} = e // 拿到x,y坐标
+  ctx.value = canvas.value.getContext('2d') // 上下文
+//   console.log(ctx.value)
+  ctx.value.strokeStyle = '#000'; // 设置线条颜色
+  ctx.value.fillStyle = '#fff'
+  ctx.value.lineWidth = 5; // 线条宽度
+  ctx.value.beginPath(); // 开始绘制路径
+  ctx.value.moveTo(offsetX, offsetY); // 将鼠标移动到某一个坐标,准备绘制
+  isDown.value = true // 打开绘制开关
+}
+// 鼠标移动
+const canvasMove = (e) => {
+  let {offsetX, offsetY} = e // 拿到移动时的坐标信息
+  isDown.value && startDraw(offsetX, offsetY) // 绘制开关为true 开始绘制
+}
+// 鼠标松开
+const canvasUp = () => {
+  console.log('松开');
+  isDown.value = false
+}
+// 鼠标超出canvas绘制区域
+const canvasLeave = () => {
+  console.log('超出canvas');
+  isDown.value = false
+}
+// 绘制方法
+const startDraw = (x, y) => {
+  ctx.value.lineTo(x, y); // 绘制线条
+  ctx.value.stroke(); //
+}
+const handleClear = () => {
+  ctx.value.clearRect(0, 0, 1000, 500)
+}
+const handleSave = () => {
+  formLoading.value = true
+  const base64 = canvas.value.toDataURL()
+  uploadBase64Image(base64)
+  try {
+    const data = formDataScope.value as unknown as ScoreVO
+
+       ScoreApi.updateScoreStatus(data)
+      message.success(t('common.updateSuccess'))
+
+    file.value.score = formDataScope.value.score
+    visible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+    pageAndPage.value=true
+    file.value = {score: undefined, workName: "", manuscriptAndMaterial: "", format: "", url: ""}
+    workList.value=undefined
+  }
+  getTypeList()
+  getList()
+}
+
+const uploadBase64Image = (base64Data, contentType = 'image/png') => {
+  const blob = base64ToBlob(base64Data, contentType);
+  const formData = new FormData();
+  formData.append('file', blob, 'image.png'); // 你可以根据需要更改文件名
+
+  workApi.uploadFiles(formData).then(data => {
+    formDataScope.value.url=data.url
+  })
+}
+const base64ToBlob = (base64Data, contentType = 'image/png') => {
+  const byteString = atob(base64Data.split(',')[1]);
+  const mimeString = contentType;
+  const ab = new ArrayBuffer(byteString.length);
+  const ia = new Uint8Array(ab);
+  for (let i = 0; i < byteString.length; i++) {
+    ia[i] = byteString.charCodeAt(i);
+  }
+  return new Blob([ab], {type: mimeString});
+}
+//=======================================================
+
+import { ElMessage } from 'element-plus'
 import download from '@/utils/download'
 import {ScoreApi, ScoreVO} from '@/api/work/score'
-import ScoreForm from './ScoreForm.vue'
-import {AllocationApi} from "@/api/work/allocation";
-import {handleTree} from "@/utils/tree";
 import {TypeApi} from "@/api/work/type";
 import {workApi} from "@/api/work/work";
 import {ref} from 'vue'
-import VueOfficePddf from '@vue-office/pdf'
+import VueOfficePdf from '@vue-office/pdf'
+
+
+const dialogVisible = ref(false) // 弹窗的是否展示
+const dialogTitle = ref('') // 弹窗的标题
+const lookWorkOne = ref({}) // 作品
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formData = ref({
+  score: ''
+})
+const formRules = reactive({})
+
+/** 返回开始评分界面 */
+const returnScope = () => {
+  pageAndPage.value = true
+  workList.value = []
+}
+/** 提交 */
+const subStatus = () => {
+  pageAndPage.value = true
+  workList.value = []
+}
+/** 下一个 */
+const nextScope = () => {
+  if (indexScore.value === workList.value.length) {
+    return
+  }
+  indexScore.value++
+  file.value.score = undefined
+  formDataScope.value.score = undefined
+  formDataScope.value.id = undefined
+  getWorkLists()
+}
+/** 上一个 */
+const backScope = () => {
+  if (indexScore.value === 0) {
+    return
+  }
+  file.value.score = undefined
+  formDataScope.value.score = undefined
+  formDataScope.value.id = undefined
+  indexScore.value--
+  getWorkLists()
+}
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+  // 提交请求
+  formLoading.value = true
+
+  try {
+    const data = formData.value as unknown as ScoreVO
+    console.log(data)
+    if (formType.value === 'create') {
+      await ScoreApi.createScore(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await ScoreApi.updateScore(data)
+      message.success(t('common.updateSuccess'))
+    }
+
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: undefined,
+    workId: undefined,
+    status: undefined,
+    score: undefined
+  }
+  formRef.value?.resetFields()
+}
+
+
+const tabPosition = ref('当前作品')
+const scrollContainer = ref(null)
+
+const scrollToSection = (sectionId) => {
+  console.log(scrollContainer.value)
+  if (scrollContainer.value && scrollContainer.value.$el) {
+    const targetElement = scrollContainer.value.$el.querySelector(`#${sectionId}`);
+    if (targetElement) {
+      const container = scrollContainer.value.$el.querySelector('.el-scrollbar__wrap');
+      const targetTop = targetElement.offsetTop;
+      container.scrollTop = targetTop; // 直接设置 scrollTop 来滚动到目标位置
+
+    }
+  }
+}
+//=================================
+
+
+const pageAndPage = ref(true)
 
 const file = ref({
   format: '',
   url: '',
   workName: '',
-  manuscriptAndMaterial: ''
+  manuscriptAndMaterial: '',
+  score: undefined
 });
 /** 作品评分 列表 */
 defineOptions({name: 'Score'})
@@ -106,6 +435,7 @@ interface workVO {
   groupAndTopic: string // 组别/选题
   sizeAndDuration: number // 尺寸/时长
   manuscriptAndMaterial: string // 文稿/材料
+  scoreDO: any // 文稿/材料
 }
 
 const message = useMessage() // 消息弹窗
@@ -121,14 +451,14 @@ const loading = ref(true) // 列表的加载中
 const list = ref<ScoreVO[]>([]) // 列表的数据
 const typeList = ref([]) // 列表的数据
 const total = ref(0) // 列表的总页数
-const queryParams = reactive({
+const queryParams = reactive({//评分查询参数
   pageNo: 1,
   pageSize: 10,
   workId: undefined,
   score: undefined,
   createTime: []
 })
-const typeQueryParams = reactive({
+const typeQueryParams = reactive({//类型查询参数
   pageNo: 1,
   pageSize: 10,
   workId: undefined,
@@ -137,62 +467,114 @@ const typeQueryParams = reactive({
 })
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
+/** 开始评分跳转 */
+const handleNodeClick = () => {
 
-const handleNodeClick = (data: Tree) => {
-  file.value = {workName: "", manuscriptAndMaterial: "", format: "", url: ""}
-  workQueryParams.categoryId = data.id
+  file.value = {score: undefined, workName: "", manuscriptAndMaterial: "", format: "", url: ""}
+  workQueryParams.categoryId = startType.value.id
+  if (workQueryParams.categoryId===''){
+    ElMessage({
+      message: '当前没有您要评的作品!',
+      type: 'warning',
+    })
+    return
+  }
+  loading.value = true
+  indexScore.value = 0
   getWorkLists()
 }
 
+/** 评分查看作品内容 */
 const lookWork = (value) => {
-  file.value = {workName: "", manuscriptAndMaterial: "", format: "", url: ""}
+  file.value = {score: undefined, workName: "", manuscriptAndMaterial: "", format: "", url: ""}
   console.log(value)
   file.value.format = value.format
   file.value.url = value.workUrl
   file.value.workName = value.workName
+  formDataScope.value.workId = value.workId
   file.value.manuscriptAndMaterial = value.manuscriptAndMaterial
+  file.value.score = value.scoreDO.score
+  formDataScope.value.score = value.scoreDO.score
+  formDataScope.value.id = value.scoreDO.id
+  formDataScope.value.workId = value.workId
 }
-const workList = ref<workVO[]>([]) // 列表的数据
+const workList = ref<workVO[]>([]) // 作品列表的数据
+
+/** 访问作品类型获取数据 */
 const getTypeList = async () => {
   loading.value = true
   try {
     const datas = await TypeApi.getScoreTreeList(typeQueryParams)
-    console.log(datas.valueOf())
-    typeList.value = handleTreeAll(datas, 'id', 'parentId')
+    typeList.value = handleTreeAll(datas)
     // list.value = data.list
   } finally {
     loading.value = false
   }
 }
-const handleTreeAll=(data,id,parentId) => {
-  let arr=[]
-  let type=''
+/** 类型从子到父的名称拼接 */
+const handleTreeAll = (data) => {
+  let c = true;
+  let b = true
+  let arr = []
+  let type = ''
   for (let i = 0; i < data.length; i++) {
-    strParent(data[i],data)
+    b = true
+    for (let j = 0; j < data.length; j++) {
+      if (data[i].id == data[j].parentId) {
+        b = false
+      }
+    }
+    if (b) {
+      type = data[i].typeName
+      let items = {id: data[i].id, typeName: strParent(type, data[i], data)};
+      arr.push(items)
+      if (c) {
+        c = false
+        startType.value = items
+      }
+    }
   }
   return arr
 }
-const strParent = (obj,data) => {
-
+/** 类型从子到父的名称拼接递归函数 */
+const strParent = (type, obj, data) => {
+  for (let i = 0; i < data.length; i++) {
+    if (obj.parentId == data[i].id) {
+      type = data[i].typeName + '-' + type
+      return strParent(type, data[i], data)
+    }
+  }
+  return type
 }
-
+/** 作品查询参数 */
 const workQueryParams = reactive({
   workName: undefined,
   status: 1,
 })
+/** 类型数据显示 */
+const startType = ref({
+  typeName: undefined,
+  id: '',
+})
+const indexScore = ref(0)
+/** 作品数据 */
 const getWorkLists = async () => {
   loading.value = true
   try {
     const data = await workApi.getworkList(workQueryParams)
     workList.value = data.list
     if (workList.value.length > 0) {
-      file.value.format = workList.value[0].format
-      file.value.url = workList.value[0].workUrl
-      file.value.workName = workList.value[0].workName
-      file.value.manuscriptAndMaterial = workList.value[0].manuscriptAndMaterial
+      lookWorkOne.value = workList.value[indexScore.value]
+      file.value.format = workList.value[indexScore.value].format
+      file.value.url = workList.value[indexScore.value].workUrl
+      file.value.workName = workList.value[indexScore.value].workName
+      file.value.manuscriptAndMaterial = workList.value[indexScore.value].manuscriptAndMaterial
+      file.value.score = workList.value[indexScore.value].scoreDO.score
+      formDataScope.value.score = workList.value[indexScore.value].scoreDO.score
+      formDataScope.value.id = workList.value[indexScore.value].scoreDO.id
+      formDataScope.value.workId = workList.value[indexScore.value].workId
+      pageAndPage.value = false
     }
-
-    console.log(workList.value)
   } finally {
     loading.value = false
   }
@@ -220,11 +602,42 @@ const resetQuery = () => {
   queryFormRef.value.resetFields()
   handleQuery()
 }
-
-/** 添加/修改操作 */
 const formRef = ref()
-const openForm = (type: string, id?: number) => {
-  formRef.value.open(type, id)
+const formDataScope = ref({
+  id: undefined,
+  workId: undefined,
+  status: undefined,
+  score: undefined,
+  url: undefined
+})
+/** 添加/修改操作 */
+const submitScope = async () => {
+  if (file.value.score === null) {
+    formType.value = 'create'
+  } else {
+    formType.value = ''
+  }
+  console.log(file.value)
+  console.log(formType.value)
+  console.log(formDataScope.value)
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formDataScope.value as unknown as ScoreVO
+    if (formType.value === 'create') {
+      formDataScope.value.id = await ScoreApi.createScore(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await ScoreApi.updateScore(data)
+      message.success(t('common.updateSuccess'))
+    }
+    file.value.score = formDataScope.value.score
+    dialogVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
 }
 
 /** 删除按钮操作 */
@@ -263,7 +676,8 @@ onMounted(() => {
 })
 </script>
 <style>
-.docx-class {
-  height: 400px;
+.button-padd {
+  padding: 20px;
 }
+
 </style>

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.