瀏覽代碼

feat: 评卷配置持久保存

chenhao 2 年之前
父節點
當前提交
767f110529

+ 3 - 3
electron/main/main.ts

@@ -1,6 +1,6 @@
-import { app, BrowserWindow, clipboard, dialog, screen } from 'electron'
+import { app, BrowserWindow, clipboard } from 'electron'
 import { resolve } from 'path'
-import installDevTool, { VUEJS3_DEVTOOLS } from 'electron-devtools-installer'
+import installDevTool, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
 import path from 'path'
 
 if (!app.requestSingleInstanceLock()) {
@@ -65,7 +65,7 @@ async function createWindow() {
     // mainWin.loadURL('http://192.168.10.40:7200')
     mainWin.loadURL('http://cet-test.markingtool.cn')
   } else {
-    installDevTool(VUEJS3_DEVTOOLS)
+    installDevTool(VUEJS_DEVTOOLS)
     process.env.WEB_DEV_INDEX_URL && mainWin.loadURL(process.env.WEB_DEV_INDEX_URL)
   }
 }

+ 1 - 0
src/App.vue

@@ -9,6 +9,7 @@ const mainLayoutStore = useMainLayoutStore()
 
 if (mainStore.loginInfo) {
   mainStore.getMyUserInfo()
+  mainStore.getUserMarkConfig()
   mainLayoutStore.getRenderMenuList()
 }
 </script>

+ 11 - 1
src/api/api-types/user.d.ts

@@ -211,10 +211,20 @@ export namespace User {
       }[]
     }
   >
+
+  type MarkConfig = {
+    center: boolean
+    ratio: number
+    rotate: number
+    frontColor: string
+    backgroundColor: string
+  }
+
   /** 设置试卷配置信息 */
   type SetUserMarkConfig = BaseDefine<{ config: string }>
+
   /** 获取试卷配置信息 */
-  type GetUserMarkConfig = BaseDefine<null, string>
+  type GetUserMarkConfig = BaseDefine<null, Record<string, MarkConfig>>
 
   /** >>> user api end <<< */
   export interface ApiMap {

+ 40 - 16
src/components/shared/MarkHeader.vue

@@ -26,8 +26,9 @@
 </template>
 
 <script setup lang="ts" name="MarkHeader">
-import { reactive, ref, computed, useAttrs, watch } from 'vue'
-import useFetch from '@/hooks/useFetch'
+import { reactive, ref, computed, useAttrs, watch, onUnmounted } from 'vue'
+import { useRoute } from 'vue-router'
+import useMainStore from '@/store/main'
 import SvgIcon from '@/components/common/SvgIcon.vue'
 import ColorPicker from '@/components/common/ColorPicker.vue'
 import Message from '@/components/shared/message/Message.vue'
@@ -74,6 +75,13 @@ const emits = defineEmits<{
   (e: 'background-color', color: number[]): void
 }>()
 
+const props = defineProps<{
+  excludeOperations?: ButtonType[]
+  includeOperations?: ButtonType[]
+  replyUserId?: number | null
+  paperPath?: string | null
+}>()
+
 const buttons: HeaderButton[] = [
   { title: '返回', type: 'back' },
   { title: '放大', type: 'scale-up' },
@@ -91,13 +99,6 @@ const buttons: HeaderButton[] = [
   { title: '设置专家卷', type: 'bookmark' },
 ]
 
-const props = defineProps<{
-  excludeOperations?: ButtonType[]
-  includeOperations?: ButtonType[]
-  replyUserId?: number | null
-  paperPath?: string | null
-}>()
-
 const refs = reactive<Partial<Record<ButtonType, Element>>>({
   'front-color': void 0,
   'background-color': void 0,
@@ -118,6 +119,14 @@ const usedOperations = computed(() => {
 
 const attrs = useAttrs()
 
+const mainStore = useMainStore()
+
+const { fullPath } = useRoute()
+
+const userMarkConfig = computed(() => {
+  return mainStore.userMarkConfig?.[fullPath]
+})
+
 /** center */
 const center = ref<boolean>(false)
 
@@ -190,14 +199,29 @@ const setCurrentConfig = (config: MarkConfig) => {
   backgroundColor.value = config.backgroundColor ?? backgroundColor.value
 }
 
-const loadUserConfig = async () => {
-  try {
-    const configStr = await useFetch('getUserMarkConfig').fetch()
-    const config = JSON.parse(configStr)
-  } catch (error) {
-    console.error(error)
+watch(
+  userMarkConfig,
+  () => {
+    if (userMarkConfig.value) {
+      setCurrentConfig(userMarkConfig.value)
+    }
+  },
+  { immediate: true }
+)
+
+onUnmounted(() => {
+  if (fullPath) {
+    mainStore.setUserMarkConfig({
+      [fullPath]: {
+        center: center.value,
+        ratio: ratio.value,
+        rotate: rotate.value,
+        frontColor: frontColor.value,
+        backgroundColor: backgroundColor.value,
+      },
+    })
   }
-}
+})
 </script>
 
 <style scoped lang="scss">

+ 7 - 7
src/components/shared/ScoringPanel.vue

@@ -4,7 +4,7 @@
     draggable
     title="键盘给分"
     modal-class="no-mask"
-    :width="useVW(550)"
+    :width="useVW(560)"
     :modal="false"
     @close="onToggleClick"
   >
@@ -51,8 +51,9 @@ const props = withDefaults(
     score: (number | string)[]
     mainNumber?: number | null
     id?: number | null
+    autoVisible: boolean | undefined
   }>(),
-  { modal: false, toggleModal: true, score: () => [], mainNumber: null, id: null }
+  { modal: false, toggleModal: true, score: () => [], mainNumber: null, id: null, autoVisible: true }
 )
 
 const emits = defineEmits(['submit', 'update:score', 'update:visible'])
@@ -91,13 +92,12 @@ watch(modalVisible, () => {
 
 const { fetch: getQuestionStruct, reset: resetQuestionStruct, result: questionStruct } = useFetch('getQuestionStruct')
 
-watch(
-  () => props.id,
-  () => {
+watch([() => props.id, () => props.autoVisible], () => {
+  if (props.autoVisible) {
     modalVisible.value = !!props.id
-    scoreValues.value = []
   }
-)
+  scoreValues.value = []
+})
 
 watch(
   () => props.mainNumber,

+ 1 - 0
src/components/shared/ScoringPanelItem.vue

@@ -332,6 +332,7 @@ const onToggleClick = () => {
     color: $color--white;
     font-size: 32px;
     outline: none;
+    margin-left: 6px;
     .score-input {
       background: inherit;
       color: inherit;

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

@@ -53,13 +53,13 @@
         <span class="preview" @click="onPreview">
           <svg-icon name="preview"></svg-icon>
         </span>
-        <scoring-panel-with-confirm-vue
+        <scoring-panel-with-confirm
           :id="current?.taskId"
           v-model:visible="scoringPanelVisible"
           v-model:score="modelScore"
           :main-number="current?.mainNumber"
           @submit="onSubmit"
-        ></scoring-panel-with-confirm-vue>
+        ></scoring-panel-with-confirm>
       </div>
       <div class="radius-base p-extra-small fill-blank m-l-base overflow-auto paper-mark-record">
         <mark-history-list :id="current?.taskId" :model-value="true" :modal="false"></mark-history-list>
@@ -81,7 +81,7 @@ import VueEcharts from 'vue-echarts'
 import BaseTable from '@/components/element/BaseTable.vue'
 import Message from '@/components/shared/message/Message.vue'
 import UserInfo from '@/components/shared/UserInfo.vue'
-import ScoringPanelWithConfirmVue from '@/components/shared/ScoringPanelWithConfirm.vue'
+import ScoringPanelWithConfirm from '@/components/shared/ScoringPanelWithConfirm.vue'
 import ImagePreview from '@/components/shared/ImagePreview.vue'
 import MarkHistoryList from '@/components/shared/MarkHistoryList.vue'
 import SvgIcon from '@/components/common/SvgIcon.vue'

+ 1 - 0
src/modules/analysis/view-marked-detail/index.vue

@@ -64,6 +64,7 @@
     v-model:score="modelScore"
     :main-number="current?.mainNumber"
     modal
+    :auto-visible="false"
     :toggle-modal="false"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>

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

@@ -54,6 +54,7 @@
     :main-number="currentAssessPaper?.mainNumber"
     modal
     :toggle-modal="false"
+    :auto-visible="false"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>
 </template>

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

@@ -53,6 +53,7 @@
     v-model:score="modelScore"
     modal
     :toggle-modal="false"
+    :auto-visible="false"
     :main-number="currentExpertPaper?.mainNumber"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>

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

@@ -54,6 +54,7 @@
     v-model:score="modelScore"
     modal
     :toggle-modal="false"
+    :auto-visible="false"
     :main-number="currentRfPaper?.mainNumber"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>

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

@@ -91,7 +91,7 @@ const { mainQuestionList, dataModel, changeModelValue, onOptionInit } = useOptio
 
 const formModel = reactive<ExtractApiParams<'getStandardList'>>({
   mainNumber: dataModel.question,
-  dispensed: '',
+  dispensed: true,
   scoreStart: '',
   scoreEnd: '',
   pageNumber: 1,

+ 1 - 0
src/modules/marking/inquiry-result/index.vue

@@ -61,6 +61,7 @@
     :main-number="current?.mainNumber"
     modal
     :toggle-modal="false"
+    :auto-visible="false"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>
   <base-dialog v-model="setExpertPaperVisible" title="设置专家卷" :footer="false" :width="useVW(540)">

+ 1 - 0
src/modules/monitor/system-check/index.vue

@@ -58,6 +58,7 @@
     v-model:score="modelScore"
     modal
     :toggle-modal="false"
+    :auto-visible="false"
     :main-number="currentSystemCheckPaper?.mainNumber"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>

+ 39 - 16
src/modules/quality/self-check-detail/index.vue

@@ -51,6 +51,7 @@
     :main-number="current?.mainNumber"
     modal
     :toggle-modal="false"
+    :auto-visible="false"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>
   <image-preview v-model="previewModalVisible" :url="current?.filePath"></image-preview>
@@ -96,6 +97,8 @@ const sendBackVisible = ref<boolean>(false)
 /** 分数 */
 const modelScore = ref<number[]>([])
 
+const { fetch: getSelfCheckDataDetail, result: selfCheckDataDetail } = useFetch('getSelfCheckDataDetail')
+
 const {
   rotate,
   scale,
@@ -155,15 +158,13 @@ const onOperationClick: OperationClick = ({ type, value }) => {
 
 const columns: EpTableColumn<RowType>[] = [
   { label: '密号', prop: 'secretNumber' },
-  { label: '标准分', prop: 'score' },
-  { label: '评卷给分', prop: 'scoreLevel' },
-  { label: '分组', prop: 'createName' },
-  { label: '评卷员', prop: 'createTime' },
-  { label: '评卷时间', prop: 'createTime' },
+  { label: '评卷员', prop: 'markerName' },
+  { label: '离差', prop: 'diff' },
+  { label: '正式分', prop: 'markerScore' },
+  { label: '自查分', prop: 'selfScore' },
+  { label: '评卷时间', prop: 'markTime' },
 ]
 
-const { fetch: getSelfCheckDataDetail, result: selfCheckDataDetail } = useFetch('getSelfCheckDataDetail')
-
 const {
   tableRef,
   tableData,
@@ -200,15 +201,37 @@ const { drawing, dataUrl } = useSetImgBg(imgOption)
 </script>
 
 <style scoped lang="scss">
-.table-view {
-  width: 480px;
-  .detail-info-label {
-    .detail-info-label-num {
-      min-width: 32px;
-      height: 24px;
-      line-height: 24px;
-      background: #00987b;
-      border-radius: 4px;
+.mark-container {
+  .mark-content {
+    position: relative;
+    .preview {
+      position: absolute;
+      cursor: pointer;
+      top: 10px;
+      right: 20px;
+      font-size: 24px;
+    }
+    .next-button {
+      position: absolute;
+      right: -20px;
+      top: 300px;
+    }
+    .mark-content-paper {
+      img {
+        max-width: 100%;
+      }
+    }
+  }
+  .table-view {
+    width: 480px;
+    .detail-info-label {
+      .detail-info-label-num {
+        min-width: 32px;
+        height: 24px;
+        line-height: 24px;
+        background: #00987b;
+        border-radius: 4px;
+      }
     }
   }
 }

+ 1 - 0
src/modules/quality/subjective-check/index.vue

@@ -64,6 +64,7 @@
     :main-number="currentSubjectiveCheck?.mainNumber"
     modal
     :toggle-modal="false"
+    :auto-visible="false"
     @submit="onSubmit"
   ></scoring-panel-with-confirm>
   <image-preview v-model="previewModalVisible" :url="currentSubjectiveCheck?.filePath"></image-preview>

+ 21 - 0
src/store/main.ts

@@ -10,10 +10,13 @@ interface MainStoreState {
   diffTime: number
   loginInfo?: ExtractApiResponse<'userLogin'>
   myUserInfo?: ExtractApiResponse<'getMyUserInfo'>
+  userMarkConfig: ExtractApiResponse<'getUserMarkConfig'>
 }
 
 interface MainStoreActions {
   getMyUserInfo: () => Promise<ExtractApiResponse<'getMyUserInfo'> | undefined>
+  getUserMarkConfig: () => Promise<ExtractApiResponse<'getUserMarkConfig'> | undefined>
+  setUserMarkConfig: (config: ExtractApiResponse<'getUserMarkConfig'>) => void
 }
 
 const useMainStore = defineStore<'main', MainStoreState, Record<string, any>, MainStoreActions>('main', {
@@ -31,6 +34,8 @@ const useMainStore = defineStore<'main', MainStoreState, Record<string, any>, Ma
       loginInfo: (sessionStorage.get('LOGIN_RESULT') as ExtractApiResponse<'userLogin'>) ?? void 0,
       /** 当前用户信息 */
       myUserInfo: void 0,
+      /** 用户配置信息 */
+      userMarkConfig: {},
     }
   },
   actions: {
@@ -42,6 +47,22 @@ const useMainStore = defineStore<'main', MainStoreState, Record<string, any>, Ma
         console.warn(error)
       }
     },
+    async getUserMarkConfig() {
+      try {
+        this.userMarkConfig = await useFetch('getUserMarkConfig').fetch()
+        return this.userMarkConfig
+      } catch (error) {
+        console.warn(error)
+      }
+    },
+    async setUserMarkConfig(config: ExtractApiResponse<'getUserMarkConfig'>) {
+      try {
+        this.userMarkConfig = Object.assign({}, this.userMarkConfig, config)
+        await useFetch('setUserMarkConfig').fetch({ config: JSON.stringify(this.userMarkConfig) })
+      } catch (error) {
+        console.warn(error)
+      }
+    },
   },
 })