Przeglądaj źródła

一波需求提测

刘洋 2 lat temu
rodzic
commit
b636e572bb
33 zmienionych plików z 615 dodań i 214 usunięć
  1. 3 2
      src/api/api-types/statistics.d.ts
  2. BIN
      src/assets/images/bel_img.png
  3. BIN
      src/assets/images/logout.png
  4. BIN
      src/assets/images/tanchu.png
  5. 1 1
      src/assets/styles/var.scss
  6. 7 3
      src/components/common/ColorPicker.vue
  7. 25 2
      src/components/common/ContentEditAble.vue
  8. 11 2
      src/components/common/LockEntry.vue
  9. 2 1
      src/components/shared/CurrentTime.vue
  10. 38 13
      src/components/shared/MarkHeader.vue
  11. 37 7
      src/components/shared/ScoringPanelItem.vue
  12. 19 5
      src/components/shared/UserInfo.vue
  13. 18 2
      src/components/shared/message/Message.vue
  14. 147 0
      src/components/shared/message/MessageHeadList.vue
  15. 32 89
      src/components/shared/message/MessageList.vue
  16. 25 15
      src/components/shared/message/MessageSend.vue
  17. 23 3
      src/components/shared/message/MessageWindow.vue
  18. 15 11
      src/hooks/useMarkHeader.ts
  19. 77 25
      src/layout/main/MainHeader.vue
  20. 10 3
      src/modules/analysis/group-monitoring-detail/index.vue
  21. 2 1
      src/modules/expert/assess/index.vue
  22. 1 1
      src/modules/expert/expert/index.vue
  23. 1 1
      src/modules/expert/sample/index.vue
  24. 2 1
      src/modules/expert/standard/index.vue
  25. 2 1
      src/modules/expert/training/index.vue
  26. 8 1
      src/modules/marking/assess/index.vue
  27. 4 2
      src/modules/marking/mark/index.vue
  28. 7 1
      src/modules/marking/similar/index.vue
  29. 20 2
      src/modules/monitor/training-monitoring/index.vue
  30. 50 8
      src/modules/quality/ending-check/components/EndCheck.vue
  31. 14 11
      src/modules/quality/subjective-check/index.vue
  32. 11 0
      src/router/expert.ts
  33. 3 0
      src/router/index.ts

+ 3 - 2
src/api/api-types/statistics.d.ts

@@ -221,7 +221,8 @@ export namespace Statistics {
     secretNumber: string
     taskId: number
   }
-  type UnMarkPaperList = BaseDefine<MultipleQuery<BaseParams>, MultipleResult<UnMarkPaper>>
+  // type UnMarkPaperList = BaseDefine<MultipleQuery<BaseParams>, MultipleResult<UnMarkPaper>>
+  type UnMarkPaperList = BaseDefine<BaseParams, MultipleResult<UnMarkPaper>>
   /** 质量统计-收尾检查-未处理雷同卷列表 */
   interface UnProcessSimilar {
     questionMainName: string
@@ -238,7 +239,7 @@ export namespace Statistics {
   }
   type UnProcessProblemList = BaseDefine<BaseParams, UnProcessProblem[]>
 
-  type ChangeTaskMarker = BaseDefine<{ loginName: string; taskId?: number }>
+  type ChangeTaskMarker = BaseDefine<{ loginName: string; taskIds?: number[] }>
 
   /** 小组监控 */
   interface GroupMonitor {

BIN
src/assets/images/bel_img.png


BIN
src/assets/images/logout.png


BIN
src/assets/images/tanchu.png


+ 1 - 1
src/assets/styles/var.scss

@@ -49,7 +49,7 @@ $PrimaryPlusFontColor: map-get($ep-text-color, 'primary-plus');
 $BlockTitleColor: map-get($ep-text-color, 'primary');
 
 /** layout */
-$MainLayoutHeaderHeight: 56px;
+$MainLayoutHeaderHeight: 86px;
 // $MainLayoutHeaderBg: $color--white;
 $MainLayoutHeaderBg: #333;
 $MainLayoutHeaderLogoFontSize: map-get($ep-font-size, 'medium');

+ 7 - 3
src/components/common/ColorPicker.vue

@@ -62,6 +62,10 @@ const emits = defineEmits<{ (e: 'update:modelValue', color: string): void }>()
 const visible = ref<boolean>(false)
 
 const defaultColors = [
+  '#c5dbc2',
+  '#ffffff',
+  '#000000',
+
   '#fe7e7d',
   '#feff7e',
   '#81ff81',
@@ -72,15 +76,15 @@ const defaultColors = [
   '#ff7ffd',
   '#fe0002',
   '#fffc00',
-  '#80fe00',
-  '#00ff43',
+  // '#80fe00',
+  // '#00ff43',
   '#04fdfd',
   '#007fc1',
   '#7f81b7',
   '#fe02f3',
   '#803f40',
   '#fb823e',
-  '#05fc03',
+  // '#05fc03',
   '#018184',
   '#043e7b',
   '#817eff',

+ 25 - 2
src/components/common/ContentEditAble.vue

@@ -47,7 +47,9 @@ const paste = (event: any) => {
   //清除回车
   text = text.replace(/\[\d+\]|\n|\r/gi, '')
   // 插入
-  document.execCommand('insertText', false, text)
+  if ((contentValue.value || '').length < 2000) {
+    document.execCommand('insertText', false, text.substr(0, 2000 - (contentValue.value || '').length))
+  }
 }
 
 function updateContent(content: string) {
@@ -61,9 +63,30 @@ function focus() {
     contenteditableEle.value?.focus()
   }
 }
-
+function placeCaretAtEnd(el: any) {
+  el.focus()
+  if (window.getSelection) {
+    if (typeof window.getSelection != 'undefined' && typeof document.createRange != 'undefined') {
+      var range = document.createRange()
+      range.selectNodeContents(el)
+      range.collapse(false)
+      var sel: any = window.getSelection()
+      sel.removeAllRanges()
+      sel.addRange(range)
+    } else if (typeof (document.body as any).createTextRange != 'undefined') {
+      var textRange = (document.body as any).createTextRange()
+      textRange.moveToElementText(el)
+      textRange.collapse(false)
+      textRange.select()
+    }
+  }
+}
 function inputChange(event: Event) {
   const target = event.target as HTMLElement
+  if (target.innerHTML.length > 2000) {
+    target.innerHTML = target.innerHTML.substr(0, 2000)
+    placeCaretAtEnd(target)
+  }
   contentValue.value = target.innerHTML
 }
 

+ 11 - 2
src/components/common/LockEntry.vue

@@ -1,8 +1,9 @@
 <template>
   <el-tooltip class="lock-entry" effect="light" content="锁屏" placement="bottom">
-    <div class="lock-box flex direction-column" @click="lockOpen">
+    <div class="lock-box flex direction-column items-center" @click="lockOpen">
       <!-- <img src="../../assets/images/lock_screen.png" class="lock" title="锁屏" /> -->
       <svg-icon name="suo"></svg-icon>
+      <p class="tip">锁屏</p>
     </div>
   </el-tooltip>
 </template>
@@ -18,8 +19,16 @@ const lockOpen = () => {
 <style lang="scss" scoped>
 .lock-box {
   cursor: pointer;
-  justify-content: flex-end;
+  // justify-content: flex-end;
   font-size: 18px;
+  text-align: center;
+  &:hover {
+    opacity: 0.7;
+  }
+  .tip {
+    font-size: 12px;
+    margin-top: 3px;
+  }
   .lock {
     height: 22px;
   }

+ 2 - 1
src/components/shared/CurrentTime.vue

@@ -13,6 +13,7 @@ const time = useTime()
 
 <style scoped lang="scss">
 .current-time-box {
-  width: 110px;
+  width: 130px;
+  text-align: center;
 }
 </style>

+ 38 - 13
src/components/shared/MarkHeader.vue

@@ -10,7 +10,7 @@
         >
           <svg-icon
             :name="attrs['icon-' + button.type] as string || 'mark-' + button.type"
-            style="font-size: 15px"
+            style="font-size: 18px"
           ></svg-icon>
         </div>
         <p class="icon-title">{{ button.smallTitle || button.title }}</p>
@@ -22,12 +22,16 @@
     <div class="flex flex-1 items-center mark-header">
       <slot></slot>
       <span class="data-item">
-        <lock-entry />
-      </span>
-      <span class="data-item">
-        <message :reply-user-id="props.replyUserId" :paper-path="props.paperPath"></message>
+        <div class="icon-item">
+          <lock-entry />
+        </div>
+        <div class="icon-item">
+          <message :reply-user-id="props.replyUserId" :paper-path="props.paperPath"></message>
+        </div>
+        <div class="icon-item">
+          <user-info></user-info>
+        </div>
       </span>
-      <span class="data-item m-r-base"><user-info></user-info></span>
 
       <!-- <div class="grid pointer close-icon" @click="willLogout">
         <el-icon><close /></el-icon>
@@ -341,17 +345,18 @@ const willLogout = async () => {
   height: $MainLayoutHeaderHeight;
   background-color: $MainLayoutHeaderBg;
   .btn-item {
-    width: 52px;
+    width: 60px;
     text-align: center;
   }
   .icon-title {
-    font-size: 13px;
+    font-size: 14px;
     transform: scale(0.9);
     color: #999;
+    margin-top: 5px;
   }
   .operation-button {
-    width: 30px;
-    height: 30px;
+    width: 40px;
+    height: 40px;
     place-items: center;
     color: $RegularFontColor;
     background-color: rgba(255, 255, 255, 0.1);
@@ -366,16 +371,36 @@ const willLogout = async () => {
   .mark-header {
     margin-left: auto;
     // color: $RegularFontColor;
+    height: 100%;
     color: #999;
     font-size: $SmallFont;
     font-weight: bold;
+    padding: 12px 0;
     ::v-deep(.data-item) {
+      // padding-left: 20px;
       padding-left: 20px;
-      // display: flex;
-      // align-items: center;
+      padding-right: 20px;
+      position: relative;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      .icon-item {
+        padding: 0 10px;
+      }
       &:first-child {
         margin-left: auto;
       }
+      &:not(:last-child) {
+        &:after {
+          content: '';
+          position: absolute;
+          right: 0;
+          top: 0;
+          width: 1px;
+          height: 100%;
+          background-color: #464646;
+        }
+      }
       // &:not(:last-child):after {
       //   content: '';
       //   margin-left: 20px;
@@ -393,7 +418,7 @@ const willLogout = async () => {
         font-weight: bold;
         color: $color--primary;
         margin-bottom: 5px;
-        max-width: 135px;
+        max-width: 130px;
       }
     }
 

+ 37 - 7
src/components/shared/ScoringPanelItem.vue

@@ -56,12 +56,16 @@
       </div>
     </toggle-dialog-render>
     <toggle-dialog-render>
-      <svg-icon
+      <!-- <svg-icon
         class="pointer toggle-icon"
         :class="{ visible: props.toggleModal }"
         name="toggle-panel"
         @click="onToggleClick"
-      ></svg-icon>
+      ></svg-icon> -->
+      <div class="toggle-icon-box" :class="{ visible: props.toggleModal }" @click="onToggleClick">
+        <img src="../../assets/images/tanchu.png" />
+        <p>弹出</p>
+      </div>
     </toggle-dialog-render>
   </div>
 </template>
@@ -300,7 +304,9 @@ const onToggleClick = () => {
   }
   &.sticky {
     align-items: center;
-    padding: 12px 20px;
+    // padding: 12px 20px;
+    padding: 5px 20px;
+    height: 56px;
   }
 
   // .dialog-name {
@@ -403,14 +409,38 @@ const onToggleClick = () => {
     }
   }
 
-  .toggle-icon {
-    align-self: flex-start;
-    margin-top: 6px;
-    margin-left: 6px;
+  // .toggle-icon {
+  //   align-self: flex-start;
+  //   margin-top: 6px;
+  //   margin-left: 6px;
+  //   opacity: 0;
+  //   &.visible {
+  //     opacity: 1;
+  //   }
+  // }
+  .toggle-icon-box {
+    cursor: pointer;
+    background-color: #0091ff;
+    width: 70px;
+    border-radius: 6px;
+    text-align: center;
+    color: #fff;
     opacity: 0;
+    height: 100%;
+    transition: all 0.3s;
+    &:hover {
+      background-color: rgba(0, 145, 255, 0.8);
+    }
     &.visible {
       opacity: 1;
     }
+    img {
+      height: 20px;
+      margin-top: 4px;
+    }
+    p {
+      font-size: 12px;
+    }
   }
 }
 </style>

+ 19 - 5
src/components/shared/UserInfo.vue

@@ -11,11 +11,14 @@
         </div>
       </div>
     </template>
-    <svg-icon
-      name="user"
-      style="font-size: 17px; position: relative; bottom: -1px; cursor: pointer"
-      @click="visibleUpdatePwd = true"
-    ></svg-icon>
+    <div class="user-box">
+      <svg-icon
+        name="user"
+        style="font-size: 17px; position: relative; bottom: -2px"
+        @click="visibleUpdatePwd = true"
+      ></svg-icon>
+      <p class="tip">个人</p>
+    </div>
   </el-tooltip>
 
   <update-user-pwd v-model="visibleUpdatePwd" :user-name="info.name || ''"></update-user-pwd>
@@ -42,6 +45,17 @@ const visibleUpdatePwd = ref<boolean>(false)
 </script>
 
 <style scoped lang="scss">
+.user-box {
+  text-align: center;
+  cursor: pointer;
+  &:hover {
+    opacity: 0.7;
+  }
+  .tip {
+    font-size: 12px;
+    margin-top: 2px;
+  }
+}
 .user-info {
   // color: $RegularFontColor;
   // color: #999;

+ 18 - 2
src/components/shared/message/Message.vue

@@ -7,7 +7,11 @@
       <!-- <svg-icon v-if="inLayout" name="message" class="bell"></svg-icon> -->
       <!-- <svg-icon v-else name="message2" class="bell"></svg-icon> -->
       <el-tooltip effect="light" content="消息" placement="bottom">
-        <svg-icon name="message" class="bell"></svg-icon>
+        <div class="msg-box">
+          <img v-if="inLayout" class="bell-img" src="../../../assets/images/bel_img.png" />
+          <svg-icon v-else name="message" class="bell"></svg-icon>
+          <p class="tip">消息</p>
+        </div>
       </el-tooltip>
     </div>
     <el-popover
@@ -203,8 +207,20 @@ bus.on('fast-send-msg', () => {
   place-items: center;
   font-size: $LargeFont;
   position: relative;
-  .bell {
+  .msg-box {
+    text-align: center;
     cursor: pointer;
+    &:hover {
+      opacity: 0.7;
+    }
+    .tip {
+      font-size: 12px;
+    }
+  }
+  .bell-img {
+    height: 16px;
+  }
+  .bell {
     &:hover {
       color: #fff;
     }

+ 147 - 0
src/components/shared/message/MessageHeadList.vue

@@ -0,0 +1,147 @@
+<template>
+  <div class="message-list p-base scroll-y-auto">
+    <template v-if="!!(messageList || []).length">
+      <div
+        v-for="message in messageList"
+        :key="message.id"
+        class="radius-base fill-blank p-base m-b-mini relative message-item"
+        :class="{ active: currentMessage?.sendUserId === message.sendUserId, 'un-read': message.unReadCount > 0 }"
+        @click="checkMessage(message)"
+      >
+        <div class="flex items-center m-b-base message-title">
+          <div class="message-send-user">{{ message.sendUserName }}</div>
+          <div class="m-l-auto message-send-time">{{ dayjs(message.sendTime).format('HH:mm') }}</div>
+        </div>
+
+        <pre class="message-content">{{ transHtmlContent(message.content) }}</pre>
+      </div>
+    </template>
+    <div v-else class="none-msg-box">
+      <div class="center-box">
+        <svg-icon name="none_message" style="font-size: 120px"></svg-icon>
+        <p class="tip">暂无消息</p>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref, watch } from 'vue'
+import useFetch from '@/hooks/useFetch'
+import bus from '@/utils/bus'
+import { transHtmlContent } from '@/utils/common'
+import dayjs from 'dayjs'
+import SvgIcon from '@/components/common/SvgIcon.vue'
+import useMainStore from '@/store/main'
+const mainStore = useMainStore()
+
+const emits = defineEmits(['leftMsgClick'])
+const props = defineProps<{ curMsg: any; mode: string; replyUserId: any }>()
+
+const currentMessage = ref<any>()
+const { fetch: getMessageList, result: messageList } = useFetch('getMessageList')
+const checkMessage = (msg: any) => {
+  currentMessage.value = msg
+  bus.emit('clickChangeMsg', msg)
+  emits('leftMsgClick', msg)
+}
+
+getMessageList().then((result) => {
+  //   currentMessage.value = result?.[0]
+  if (props.mode !== 'view' && !props.replyUserId) {
+    return
+  }
+  if (result?.length) {
+    let target: any = result[0]
+    if (props.curMsg) {
+      target = result.find((item: any) => {
+        return item.id == props.curMsg.id
+      })
+    }
+    currentMessage.value = target
+    bus.emit('clickChangeMsg', target)
+  }
+  //   if (result[0]) {
+  //     bus.emit('clickChangeMsg', result[0])
+  //   }
+})
+watch(
+  () => mainStore.newMsgs,
+  () => {
+    getMessageList().then((res) => {
+      if (res && Array.isArray(res)) {
+        let find = res.find((item) => item.sendUserId == currentMessage.value?.sendUserId)
+        if (!!find) {
+          currentMessage.value = find
+          bus.emit('clickChangeMsg', find)
+        }
+      }
+    })
+  }
+)
+</script>
+<style scoped lang="scss">
+.message-list {
+  width: 260px;
+  height: 446px;
+  background: #fafafa;
+  box-shadow: 0px 6px 6px 0px rgba(0, 0, 0, 0.1);
+  .none-msg-box {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    .center-box {
+      text-align: center;
+      .tip {
+        color: #999;
+        margin-top: 5px;
+      }
+    }
+  }
+  .message-item {
+    &.un-read:after {
+      content: '';
+      position: absolute;
+      right: 0;
+      top: 0;
+      border-radius: 50%;
+      width: 8px;
+      height: 8px;
+      background-color: $DangerColor;
+    }
+    &.active {
+      background-color: $color--primary;
+      color: $color--white;
+    }
+    &:not(.active) {
+      .message-title {
+        color: $NormalColor;
+        .message-send-time {
+          color: $RegularFontColor;
+        }
+      }
+      .message-content {
+        color: $RegularFontColor;
+      }
+    }
+    .message-title {
+      font-size: $BaseFont;
+      .message-send-time {
+        font-size: $SmallFont;
+        font-weight: 400;
+      }
+    }
+    .message-content {
+      font-weight: 400;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      display: -webkit-box;
+      -webkit-line-clamp: 2;
+      -webkit-box-orient: vertical;
+      font-size: $SmallFont;
+      white-space: pre-wrap;
+    }
+  }
+}
+</style>

+ 32 - 89
src/components/shared/message/MessageList.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="flex radius-base message-list-modal">
-    <div class="message-list p-base scroll-y-auto">
+    <slot></slot>
+    <!-- <div class="message-list p-base scroll-y-auto">
       <template v-if="!!(messageList || []).length">
         <div
           v-for="message in messageList"
@@ -13,7 +14,7 @@
             <div class="message-send-user">{{ message.sendUserName }}</div>
             <div class="m-l-auto message-send-time">{{ dayjs(message.sendTime).format('HH:mm') }}</div>
           </div>
-          <!-- <pre class="message-content" v-html="message.content"></pre> -->
+        
           <pre class="message-content">{{ transHtmlContent(message.content) }}</pre>
         </div>
       </template>
@@ -23,7 +24,7 @@
           <p class="tip">暂无消息</p>
         </div>
       </div>
-    </div>
+    </div> -->
     <div class="radius-base message-info-container">
       <div class="flex direction-column message-info">
         <div class="flex items-center p-base message-info-header">
@@ -62,16 +63,13 @@
 /** 消息列表*/
 import { ref, watch, onUnmounted } from 'vue'
 import { ElButton, ElIcon } from 'element-plus'
-import dayjs from 'dayjs'
 import { Close } from '@element-plus/icons-vue'
 import useFetch from '@/hooks/useFetch'
 import MessageHistory from '@/components/shared/message/MessageHistory.vue'
 import ImagePreview from '../ImagePreview.vue'
 import useMainStore from '@/store/main'
-import uesFetch from '@/hooks/useFetch'
 import { setLastMsgs } from '@/hooks/useMessageLoop'
-import SvgIcon from '@/components/common/SvgIcon.vue'
-import { transHtmlContent } from '@/utils/common'
+import bus from '@/utils/bus'
 import type { ExtractApiResponse } from '@/api/api'
 type MessageType = ExtractArrayValue<ExtractApiResponse<'getMessageList'>>
 const mainStore = useMainStore()
@@ -101,9 +99,12 @@ watch(currentMessage, () => {
   }
 })
 
-const checkMessage = (message: MessageType) => {
-  currentMessage.value = message
-}
+// const checkMessage = (message: MessageType) => {
+//   currentMessage.value = message
+// }
+bus.on('clickChangeMsg', (msg: any) => {
+  currentMessage.value = msg
+})
 
 const toggleHistory = () => {
   showHistory.value = !showHistory.value
@@ -127,22 +128,27 @@ const onContentClick = (e: Event) => {
   }
 }
 
-getMessageList().then((result) => (currentMessage.value = result?.[0]))
-watch(
-  () => mainStore.newMsgs,
-  () => {
-    getMessageList().then((res) => {
-      if (res && Array.isArray(res)) {
-        let find = res.find((item) => item.sendUserId == currentMessage.value?.sendUserId)
-        if (!!find) {
-          currentMessage.value = find
-        }
-      }
-    })
-  }
-)
+// getMessageList().then((result) => {
+//   currentMessage.value = result?.[0]
+//   if (result[0]) {
+//     bus.emit('getCurMsg', result[0])
+//   }
+// })
+// watch(
+//   () => mainStore.newMsgs,
+//   () => {
+//     getMessageList().then((res) => {
+//       if (res && Array.isArray(res)) {
+//         let find = res.find((item) => item.sendUserId == currentMessage.value?.sendUserId)
+//         if (!!find) {
+//           currentMessage.value = find
+//         }
+//       }
+//     })
+//   }
+// )
 onUnmounted(() => {
-  uesFetch('getUnReadMessage')
+  useFetch('getUnReadMessage')
     .fetch()
     .then((res) => {
       setLastMsgs(res)
@@ -154,70 +160,7 @@ onUnmounted(() => {
 .message-list-modal {
   width: 750px;
   background-color: transparent;
-  .message-list {
-    width: 260px;
-    height: 446px;
-    background: #fafafa;
-    box-shadow: 0px 6px 6px 0px rgba(0, 0, 0, 0.1);
-    .none-msg-box {
-      width: 100%;
-      height: 100%;
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      .center-box {
-        text-align: center;
-        .tip {
-          color: #999;
-          margin-top: 5px;
-        }
-      }
-    }
-    .message-item {
-      &.un-read:after {
-        content: '';
-        position: absolute;
-        right: 0;
-        top: 0;
-        border-radius: 50%;
-        width: 8px;
-        height: 8px;
-        background-color: $DangerColor;
-      }
-      &.active {
-        background-color: $color--primary;
-        color: $color--white;
-      }
-      &:not(.active) {
-        .message-title {
-          color: $NormalColor;
-          .message-send-time {
-            color: $RegularFontColor;
-          }
-        }
-        .message-content {
-          color: $RegularFontColor;
-        }
-      }
-      .message-title {
-        font-size: $BaseFont;
-        .message-send-time {
-          font-size: $SmallFont;
-          font-weight: 400;
-        }
-      }
-      .message-content {
-        font-weight: 400;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        display: -webkit-box;
-        -webkit-line-clamp: 2;
-        -webkit-box-orient: vertical;
-        font-size: $SmallFont;
-        white-space: pre-wrap;
-      }
-    }
-  }
+
   .message-info-container {
     // width: 600px;
     width: calc(100% - 260px);

+ 25 - 15
src/components/shared/message/MessageSend.vue

@@ -1,5 +1,6 @@
 <template>
   <div class="flex radius-base overflow-hidden message-list-modal">
+    <slot></slot>
     <div v-show="showCheckUser" class="flex direction-column p-base fill-lighter tree-box">
       <el-input v-model="filterText" placeholder="输入评卷员账号或名称筛选" clearable></el-input>
       <div class="flex-1 m-t-base scroll-y-auto">
@@ -32,12 +33,16 @@
           </div>
         </div>
         <div class="flex-1 p-base overflow-hidden">
-          <div class="full-h radius-base p-base scroll-y-auto message-info-content">
-            <content-edit-able
-              v-model="messageContent"
-              class="full content-edit-able"
-              @click="onContentClick"
-            ></content-edit-able>
+          <div class="full-h radius-base p-base message-info-content">
+            <div style="height: calc(100% - 18px)" class="scroll-y-auto">
+              <content-edit-able
+                v-model="messageContent"
+                class="full content-edit-able"
+                @click="onContentClick"
+              ></content-edit-able>
+            </div>
+
+            <div class="limit-tip">{{ messageContent.length }} / 2000</div>
           </div>
         </div>
         <div class="p-base flex items-center justify-end">
@@ -268,7 +273,7 @@ const toggleHistory = () => {
 <style scoped lang="scss">
 .message-list-modal {
   background-color: transparent;
-  width: 750px;
+  width: 950px;
   .tree-box {
     width: 260px;
     height: 446px;
@@ -302,18 +307,18 @@ const toggleHistory = () => {
       }
     }
   }
-  .message-list {
-    width: 260px;
-    height: 446px;
-    background: #fafafa;
-    box-shadow: 0px 6px 6px 0px rgba(0, 0, 0, 0.1);
-  }
+  // .message-list {
+  //   width: 260px;
+  //   height: 446px;
+  //   background: #fafafa;
+  //   box-shadow: 0px 6px 6px 0px rgba(0, 0, 0, 0.1);
+  // }
   .message-info-container {
     // width: 600px;
     // flex: 1;
-    width: calc(100% - 260px);
+    width: calc(100% - 520px);
     &.big {
-      width: 750px;
+      width: 690px;
     }
     .message-info {
       height: 446px;
@@ -361,6 +366,11 @@ const toggleHistory = () => {
         ::v-deep(textarea.el-textarea__inner) {
           height: 100%;
         }
+        .limit-tip {
+          text-align: right;
+          height: 18px;
+          padding-top: 3px;
+        }
       }
     }
   }

+ 23 - 3
src/components/shared/message/MessageWindow.vue

@@ -8,17 +8,26 @@
       @close="onClose"
       @change-type="onChangeType"
       @reply="onReply"
-    ></component>
+    >
+      <message-head-list
+        :mode="props.type"
+        :cur-msg="currentMessage"
+        :reply-user-id="replyUserId"
+        @left-msg-click="leftMsgClick"
+      ></message-head-list>
+    </component>
   </base-dialog>
 </template>
 
 <script setup lang="ts" name="MessageWindow">
 /** 发送/回复消息 */
-import { ref, computed, withDefaults } from 'vue'
+import { ref, computed, withDefaults, nextTick } from 'vue'
 import useVModel from '@/hooks/useVModel'
 import BaseDialog from '@/components/element/BaseDialog.vue'
 import MessageHistory from '@/components/shared/message/MessageList.vue'
 import MessageSend from '@/components/shared/message/MessageSend.vue'
+import MessageHeadList from './MessageHeadList.vue'
+import bus from '@/utils/bus'
 
 type ModalType = 'view' | 'send'
 const replyUserName = ref<string | null>('')
@@ -31,7 +40,7 @@ const props = withDefaults(
   }>(),
   { type: 'view', replyUserId: null, paperPath: null }
 )
-
+const currentMessage = ref<any>(null)
 const visible = useVModel(props, 'modelValue')
 
 const modalType = useVModel(props, 'type')
@@ -46,6 +55,7 @@ const onClose = () => {
   visible.value = false
   replyUserId.value = null
   replyUserName.value = null
+  currentMessage.value = null
 }
 
 const onChangeType = (type: ModalType) => {
@@ -57,6 +67,16 @@ const onReply = (userId: number, userName: string) => {
   replyUserId.value = userId
   replyUserName.value = userName
 }
+
+const leftMsgClick = (msg: any) => {
+  currentMessage.value = msg
+  if (modalType.value != 'view') {
+    modalType.value = 'view'
+    nextTick(() => {
+      bus.emit('clickChangeMsg', msg)
+    })
+  }
+}
 </script>
 
 <style lang="scss">

+ 15 - 11
src/hooks/useMarkHeader.ts

@@ -83,18 +83,22 @@ const useMarkHeader = () => {
       e.preventDefault()
       bus.emit('mark-method-toggle')
     } else if (e.code === 'Space') {
-      const imgWrap = document.querySelector('.img-wrap')
-      if (!imgWrap) {
-        return
+      if (e.target.tagName === 'INPUT' || (e.target.className || '').includes('contenteditable-ele')) {
+        return false
       } else {
-        const pWrap = getParentNodeIsScroll(imgWrap)
-        let t = (pWrap as any).scrollTop
-        t += 100
-        pWrap.scrollTo({
-          left: 0,
-          top: t,
-          behavior: 'smooth',
-        })
+        const imgWrap = document.querySelector('.img-wrap')
+        if (!imgWrap) {
+          return
+        } else {
+          const pWrap = getParentNodeIsScroll(imgWrap)
+          let t = (pWrap as any).scrollTop
+          t += 100
+          pWrap.scrollTo({
+            left: 0,
+            top: t,
+            behavior: 'smooth',
+          })
+        }
       }
     } else if (e.keyCode == 36) {
       const imgWrap = document.querySelector('.img-wrap')

+ 77 - 25
src/layout/main/MainHeader.vue

@@ -8,23 +8,32 @@
     </div>
     <div class="flex-1 flex items-center header-info-view">
       <div>当前考试: {{ mainStore?.myUserInfo?.examName }}</div>
-      <current-time class="m-l-auto m-r-base"></current-time>
-      <div class="m-r-base m-l-base">
-        <lock-entry></lock-entry>
+      <div class="data-item m-l-auto">
+        <current-time class="m-r-base"></current-time>
       </div>
-      <div class="m-r-base m-l-base">
-        <message
-          :reply-user-id="props.replyUserId"
-          :message-visible="props.messageVisible"
-          :in-layout="inLayout"
-        ></message>
-      </div>
-
-      <div class="m-r-base m-l-base">
-        <user-info></user-info>
-      </div>
-      <div class="grid fill-light-gray pointer close-icon m-l-base" @click="logout()">
-        <el-icon><close /></el-icon>
+      <div class="data-item flex">
+        <div class="m-r-small m-l-small">
+          <lock-entry></lock-entry>
+        </div>
+        <div v-if="mainStore?.myUserInfo?.role !== 'ADMIN'" class="m-r-small m-l-small">
+          <message
+            :reply-user-id="props.replyUserId"
+            :message-visible="props.messageVisible"
+            :in-layout="inLayout"
+          ></message>
+        </div>
+        <div class="m-r-small m-l-small">
+          <user-info></user-info>
+        </div>
+        <div class="grid pointer close-icon m-l-small" @click="logout()">
+          <!-- <el-icon><close /></el-icon> -->
+          <el-tooltip effect="light" placement="bottom" content="退出登录">
+            <div class="close-box">
+              <img src="../../assets/images/logout.png" />
+              <p class="tip">退出</p>
+            </div>
+          </el-tooltip>
+        </div>
       </div>
     </div>
   </div>
@@ -58,6 +67,9 @@ const mainStore = useMainStore()
   background-color: $MainLayoutHeaderBg;
   padding: 0 $BaseGapSpace 0 $ExtraSmallGapSpace;
   border-bottom: $OnePixelLine;
+  :deep(p.tip) {
+    color: #8a8a8a;
+  }
   &.in-layout {
     background-color: #fff;
     :deep(.user-info) {
@@ -74,18 +86,58 @@ const mainStore = useMainStore()
     color: $RegularFontColor;
     font-size: $SmallFont;
     font-weight: bold;
+    height: 62px;
+    .data-item {
+      height: 100%;
+      display: flex;
+      align-items: center;
+      position: relative;
+      padding-left: 20px;
+      padding-right: 20px;
+      &:not(:last-child) {
+        &:after {
+          content: '';
+          position: absolute;
+          right: 0;
+          top: 0;
+          width: 1px;
+          height: 100%;
+          background-color: #eee;
+        }
+      }
+      &:last-child {
+        padding-right: 10px;
+        padding-left: 10px;
+      }
+    }
     .close-icon {
-      width: 32px;
-      height: 32px;
-      font-size: 1.4em;
-      border-radius: 50%;
-      place-items: center;
-      color: #666;
-      transition: all 0.3s ease-in-out;
       &:hover {
-        background-color: #dfdfdf;
-        color: #444;
+        opacity: 0.7;
       }
+      .close-box {
+        text-align: center;
+        img {
+          height: 16px;
+          position: relative;
+          bottom: -2px;
+        }
+        .tip {
+          font-size: 12px;
+          margin-top: 3px;
+        }
+      }
+
+      // width: 32px;
+      // height: 32px;
+      // font-size: 1.4em;
+      // border-radius: 50%;
+      // place-items: center;
+      // color: #666;
+      // transition: all 0.3s ease-in-out;
+      // &:hover {
+      //   background-color: #dfdfdf;
+      //   color: #444;
+      // }
     }
   }
 }

+ 10 - 3
src/modules/analysis/group-monitoring-detail/index.vue

@@ -2,11 +2,11 @@
   <div class="flex direction-column full">
     <div class="flex items-center p-extra-small fill-blank header-view">
       <el-button class="m-r-auto" size="small" plain @click="back()">返回</el-button>
-      <div class="m-r-base m-l-base">
+      <div class="m-r-small m-l-small rt">
         <lock-entry></lock-entry>
       </div>
-      <message class="m-r-base m-l-base" :paper-path="current?.filePath"></message>
-      <div class="m-r-base m-l-base">
+      <message class="m-r-small m-l-small rt" :paper-path="current?.filePath" :in-layout="true"></message>
+      <div class="m-r-small m-l-small rt">
         <user-info></user-info>
       </div>
     </div>
@@ -341,6 +341,13 @@ fetchTable()
 }
 .header-view {
   border-bottom: $OnePixelLine;
+  :deep(p.tip) {
+    color: #8a8a8a;
+    font-size: 12px;
+  }
+  .rt {
+    color: #666;
+  }
 }
 .detail-info {
   height: 280px;

+ 2 - 1
src/modules/expert/assess/index.vue

@@ -16,10 +16,11 @@
         <span class="preview" @click="onPreview">
           <svg-icon name="preview"></svg-icon>
         </span>
+        <p v-if="currentAssessPaper" class="absolute mark-score">{{ currentAssessPaper.score }}</p>
+
         <right-button class="next-button" @click="checkNext" />
         <div class="flex-1 p-base scroll-auto mark-content-paper img-wrap relative">
           <img :src="dataUrl" alt="" class="paper-img" :style="{ 'background-color': frontColor }" />
-          <p v-if="currentAssessPaper" class="absolute mark-score">{{ currentAssessPaper.score }}</p>
         </div>
         <!-- <scoring-panel-with-confirm
           v-model:visible="editScoreVisible"

+ 1 - 1
src/modules/expert/expert/index.vue

@@ -16,10 +16,10 @@
         <span class="preview" @click="onPreview">
           <svg-icon name="preview"></svg-icon>
         </span>
+        <p v-if="currentExpertPaper" class="absolute mark-score">{{ currentExpertPaper.score }}</p>
         <right-button class="next-button" @click="checkNext" />
         <div class="flex-1 p-base scroll-auto mark-content-paper img-wrap relative">
           <img :src="dataUrl" alt="" class="paper-img" :style="{ 'background-color': frontColor }" />
-          <p v-if="currentExpertPaper" class="absolute mark-score">{{ currentExpertPaper.score }}</p>
         </div>
         <!-- <scoring-panel-with-confirm
           v-model:visible="editScoreVisible"

+ 1 - 1
src/modules/expert/sample/index.vue

@@ -16,10 +16,10 @@
         <span class="preview" @click="onPreview">
           <svg-icon name="preview"></svg-icon>
         </span>
+        <p v-if="currentRfPaper" class="absolute mark-score">{{ currentRfPaper.score }}</p>
         <right-button class="next-button" @click="checkNext" />
         <div class="flex-1 p-base scroll-auto mark-content-paper img-wrap relative">
           <img :src="dataUrl" alt="" class="paper-img" :style="{ 'background-color': frontColor }" />
-          <p v-if="currentRfPaper" class="absolute mark-score">{{ currentRfPaper.score }}</p>
         </div>
         <!-- <scoring-panel-with-confirm
           v-model:visible="editScoreVisible"

+ 2 - 1
src/modules/expert/standard/index.vue

@@ -8,10 +8,11 @@
         <span class="preview" @click="onPreview">
           <svg-icon name="preview"></svg-icon>
         </span>
+        <p v-if="currentStandardPaper" class="absolute mark-score">{{ currentStandardPaper.score }}</p>
+
         <right-button class="next-button" @click="checkNext" />
         <div class="flex-1 p-base scroll-auto mark-content-paper img-wrap relative">
           <img :src="dataUrl" alt="" class="paper-img" :style="{ 'background-color': frontColor }" />
-          <p v-if="currentStandardPaper" class="absolute mark-score">{{ currentStandardPaper.score }}</p>
         </div>
       </div>
       <div class="flex direction-column p-base radius-base fill-blank scroll-auto m-l-base table-view">

+ 2 - 1
src/modules/expert/training/index.vue

@@ -14,10 +14,11 @@
         <span class="preview" @click="onPreview">
           <svg-icon name="preview"></svg-icon>
         </span>
+        <p v-if="current" class="absolute mark-score">{{ current.score }}</p>
+
         <right-button class="next-button" @click="checkNext" />
         <div class="flex-1 p-base scroll-auto mark-content-paper img-wrap relative">
           <img :src="dataUrl" alt="" class="paper-img" :style="{ 'background-color': frontColor }" />
-          <p v-if="current" class="absolute mark-score">{{ current.score }}</p>
         </div>
       </div>
       <div class="flex direction-column p-base radius-base fill-blank m-l-base table-view">

+ 8 - 1
src/modules/marking/assess/index.vue

@@ -15,7 +15,14 @@
       <div class="flex-1 radius-base fill-blank tree-card">
         <div class="flex items-center justify-between">
           <span>选择评卷员</span>
-          <el-button :loading="loading" size="small" type="primary" @click="sendHandler">分发考核卷</el-button>
+          <el-button
+            :disabled="!model.forceGroupNumber"
+            :loading="loading"
+            size="small"
+            type="primary"
+            @click="sendHandler"
+            >分发考核卷</el-button
+          >
         </div>
         <!-- <div class="flex direction-column m-t-extra-base p-base radius-base fill-lighter tree-box"> -->
         <div class="flex direction-column tree-box">

+ 4 - 2
src/modules/marking/mark/index.vue

@@ -7,8 +7,10 @@
       </div>
       <!-- <span v-show="currentTask" class="data-item">密号: {{ currentTask?.secretNumber }}</span> -->
       <div v-show="currentTask" class="data-item">
-        <p class="main-ques-info truncate">{{ currentTask?.mainNumber }}-{{ currentTask?.mainTitle }}</p>
-        <p>密号: {{ currentTask?.secretNumber }}</p>
+        <div>
+          <p class="main-ques-info truncate">{{ currentTask?.mainNumber }}-{{ currentTask?.mainTitle }}</p>
+          <p>密号: {{ currentTask?.secretNumber }}</p>
+        </div>
       </div>
       <div class="data-item">
         <current-time></current-time>

+ 7 - 1
src/modules/marking/similar/index.vue

@@ -12,7 +12,7 @@
           <img :src="dataUrl" alt="" class="paper-img" />
         </div>
         <div class="flex-1 p-base m-t-base scroll-auto radius-base fill-blank mark-content-paper">
-          <img :src="dataUrl" alt="" class="paper-img" />
+          <img :src="dataUrlSame" alt="" class="paper-img" />
         </div>
       </div>
       <div class="flex direction-column p-base radius-base fill-blank m-l-base table-view">
@@ -193,8 +193,14 @@ const imgOption = computed<SetImgBgOption>(() => {
     image: currentSamePaper?.value?.filePath,
   }
 })
+const sameImgOption = computed<SetImgBgOption>(() => {
+  return {
+    image: currentSamePaper?.value?.sameFilePath,
+  }
+})
 
 const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
+const { drawing: drawingSame, dataUrl: dataUrlSame } = useSetImgBg(sameImgOption, frontColor, setFrontColor)
 </script>
 
 <style scoped lang="scss">

+ 20 - 2
src/modules/monitor/training-monitoring/index.vue

@@ -48,6 +48,7 @@
           :columns="columns"
           :data="trainingMonitor?.data"
           :row-class-name="rowClassName"
+          class="examine-table"
           @selection-change="onSectionChange"
           @row-dblclick="onDbClick"
         >
@@ -122,8 +123,17 @@ const columns = computed<EpTableColumn<TableDataType>[]>(() => {
   return [
     {
       type: 'selection',
-      selectable(row) {
-        return !!row.markerId
+      selectable(row: any) {
+        let canCheck =
+          (((currentDataType === 'SAMPLE_A' && row.stage === 'SAMPLE_A') ||
+            (currentDataType === 'SAMPLE_B' && row.stage === 'SAMPLE_B')) &&
+            row.needAudit) ||
+          (currentDataType === 'FORCE' &&
+            row.stage === 'FORCE' &&
+            row.needAudit &&
+            !!row.forceGroupMarkerId &&
+            row.forceGroupNumber == curForceGroupNumber)
+        return !!row.markerId && canCheck
       },
       width: 60,
       fixed: 'left',
@@ -166,6 +176,7 @@ const columns = computed<EpTableColumn<TableDataType>[]>(() => {
 })
 
 let currentDataType: TableDataType['stage'] = 'SAMPLE_A'
+let curForceGroupNumber: any = undefined
 
 /** 刷新按钮 */
 async function onSearch() {
@@ -174,8 +185,10 @@ async function onSearch() {
     if (valid) {
       const { diffShow, ...params } = model || {}
       const dataType = model.markStage
+      const fGroupNumber = model.forceGroupNumber
       getTrainingMonitor(params).then(() => {
         currentDataType = dataType
+        curForceGroupNumber = fGroupNumber
       })
     }
   } catch (error) {
@@ -228,6 +241,11 @@ onOptionInit(onSearch)
   :deep(.el-form-item--small) {
     margin-bottom: 10px;
   }
+  .examine-table {
+    :deep(.el-checkbox__input.is-disabled .el-checkbox__inner) {
+      background-color: #eee;
+    }
+  }
   :deep(.el-table) {
     .cell {
       overflow: visible;

+ 50 - 8
src/modules/quality/ending-check/components/EndCheck.vue

@@ -12,9 +12,12 @@
         <div class="flex items-center m-b-base table-title">
           <span class="label">在评卷员手中</span>
           <span class="data-count">{{ unMarkPaperList?.result?.length }}</span>
-          <el-button type="primary" size="small" @click="onTaskChangeMarker">任务指定</el-button>
+          <el-button :disabled="!multipleSelection1.length" type="primary" size="small" @click="onTaskChangeMarker"
+            >任务指定</el-button
+          >
         </div>
-        <base-table
+        <!-- <base-table
+          ref="table1"
           v-loading="loading1"
           border
           stripe
@@ -23,15 +26,28 @@
           :data="unMarkPaperList?.result"
           highlight-current-row
           @current-change="onCheckTask"
+        ></base-table> -->
+        <base-table
+          ref="table1"
+          v-loading="loading1"
+          border
+          stripe
+          size="small"
+          :columns="columns1"
+          :data="unMarkPaperList?.result"
+          @selection-change="handleSelectionChange1"
         ></base-table>
       </div>
       <div class="radius-base fill-blank p-base overflow-hidden m-l-base flex-1">
         <div class="flex items-center m-b-base table-title">
           <span class="label">打回中的试卷</span>
           <span class="data-count">{{ unMarkBackPaperList?.result?.length }}</span>
-          <el-button type="primary" size="small" @click="onTaskChangeMarker2">任务指定</el-button>
+          <el-button :disabled="!multipleSelection2.length" type="primary" size="small" @click="onTaskChangeMarker2"
+            >任务指定</el-button
+          >
         </div>
-        <base-table
+        <!-- <base-table
+          ref="table2"
           v-loading="loading4"
           border
           stripe
@@ -40,6 +56,16 @@
           :data="unMarkBackPaperList?.result"
           highlight-current-row
           @current-change="onCheckTask2"
+        ></base-table> -->
+        <base-table
+          ref="table2"
+          v-loading="loading4"
+          border
+          stripe
+          size="small"
+          :columns="columns1"
+          :data="unMarkBackPaperList?.result"
+          @selection-change="handleSelectionChange2"
         ></base-table>
       </div>
       <div class="radius-base fill-blank p-base overflow-hidden m-l-base flex-1">
@@ -124,6 +150,17 @@ import useForm from '@/hooks/useForm'
 import type { ExtractApiParams, ExtractMultipleApiResponse } from '@/api/api'
 import type { EpFormItem, EpTableColumn, EpFormRules } from 'global-type'
 
+const table1 = ref()
+const table2 = ref()
+const multipleSelection1 = ref<any[]>([])
+const multipleSelection2 = ref<any[]>([])
+const handleSelectionChange1 = (val: any[]) => {
+  multipleSelection1.value = val
+}
+const handleSelectionChange2 = (val: any[]) => {
+  multipleSelection2.value = val
+}
+
 /** 指定评卷员 */
 const visibleChangeMarker = ref<boolean>(false)
 const visibleChangeMarker2 = ref<boolean>(false)
@@ -210,6 +247,7 @@ const items = computed<EpFormItem[]>(() => [
 
 /** 未评卷 table */
 const columns1: EpTableColumn[] = [
+  { type: 'selection', width: 55 },
   { label: '评卷员', prop: 'markerName' },
   { label: '密号', prop: 'secretNumber' },
   { label: '大题', prop: 'questionMainName' },
@@ -228,8 +266,10 @@ const columns3: EpTableColumn[] = [
 
 /** 开始检查 */
 const onStartCheck = () => {
-  getUnMarkPaperList({ pageNumber: 1, pageSize: 20, ...model })
-  getUnMarkBackPaperList({ pageNumber: 1, pageSize: 20, ...model })
+  // getUnMarkPaperList({ pageNumber: 1, pageSize: 20, ...model })
+  getUnMarkPaperList({ ...model })
+  // getUnMarkBackPaperList({ pageNumber: 1, pageSize: 20, ...model })
+  getUnMarkBackPaperList({ ...model })
   getUnProcessProblemList(model)
   getUnProcessSimilarList(model)
 }
@@ -259,7 +299,8 @@ const onSubmitChangeMarker = async () => {
     const valid = await elFormRef?.value?.validate()
     if (valid) {
       await useFetch('changeTaskMarker').fetch({
-        taskId: currentTask.value.taskId,
+        // taskId: currentTask.value.taskId,
+        taskIds: multipleSelection1.value.map((item: any) => item.taskId),
         loginName: changeMarkerModel.loginName,
       })
       visibleChangeMarker.value = false
@@ -277,7 +318,8 @@ const onSubmitChangeMarker2 = async () => {
     const valid = await elFormRef?.value?.validate()
     if (valid) {
       await useFetch('changeBackTaskMarker').fetch({
-        taskId: currentTask2.value.taskId,
+        // taskId: currentTask2.value.taskId,
+        taskIds: multipleSelection2.value.map((item: any) => item.taskId),
         loginName: changeMarkerModel2.loginName,
       })
       visibleChangeMarker2.value = false

+ 14 - 11
src/modules/quality/subjective-check/index.vue

@@ -43,7 +43,7 @@
       </div>
       <div class="p-base radius-base fill-blank scroll-auto m-l-base table-view">
         <splitpanes class="default-theme" horizontal style="height: 100%">
-          <pane max-size="100" size="70" style="overflow: auto">
+          <pane max-size="100" size="70" style="display: flex; flex-direction: column">
             <base-form
               size="small"
               :model="formModel"
@@ -61,16 +61,19 @@
                 <span class="m-l-extra-small detail-info-label-num">{{ tableData.length }}</span>
               </el-button>
             </div>
-            <base-table
-              ref="tableRef"
-              border
-              stripe
-              size="small"
-              :data="tableData"
-              :columns="columns"
-              highlight-current-row
-              @current-change="onCurrentChange"
-            ></base-table>
+            <div class="flex-1 scroll-auto">
+              <base-table
+                ref="tableRef"
+                height="100%"
+                border
+                stripe
+                size="small"
+                :data="tableData"
+                :columns="columns"
+                highlight-current-row
+                @current-change="onCurrentChange"
+              ></base-table>
+            </div>
           </pane>
           <pane max-size="100" size="30">
             <base-table

+ 11 - 0
src/router/expert.ts

@@ -25,6 +25,17 @@ const routes: RouteRecordRaw[] = [
           menuId: 'expert-nav',
         },
       },
+      {
+        name: 'ExpertMarkStandard',
+        path: '/expert/mark_standard',
+        component: () => import('@/modules/marking/marking-standard/index.vue'),
+        meta: {
+          label: '评分标准',
+          menu: true,
+          menuId: 'expert-mark_standard',
+          sort: 6,
+        },
+      },
     ],
   },
 

+ 3 - 0
src/router/index.ts

@@ -44,6 +44,9 @@ const pageJumpsMap: any = {
   MarkingInquiry: ['MarkingInquiryResult'],
   QualitySelfCheck: ['QualitySelfCheckDetail'],
   TrainingMonitoring: ['TrainingDetail'],
+  ExamManage: ['EditExam'],
+  UserManage: ['EditUser'],
+  RoleManage: ['RoleSetting'],
 }
 const keepAliveJupms = (from: any, to: any) => {
   const mStore = useMainStore()