Browse Source

release and bug fix

刘洋 2 years ago
parent
commit
444009922c

+ 4 - 0
src/api/api-types/statistics.d.ts

@@ -393,6 +393,7 @@ export namespace Statistics {
     std: number
     /** 相关系数 */
     xyRelate: number
+    queryStage: any
   }
   type GetTrainingMonitor = BaseDefine<TrainingMonitorParams, { data: TrainingMonitorResponse[]; header: number[] }>
 
@@ -533,6 +534,8 @@ export namespace Statistics {
   /** 决策分析-监控统计-主观题分数分布(按评卷员) */
   type GetStatisticSubjectiveByMarker = BaseDefine<StatisticByMarker, StatisticResult>
 
+  type GetProvinceProcess = BaseDefine<any, any>
+
   interface ApiMap {
     /** 质量统计-自查一致性分析 */
     selfCheckAnalysis: SelfCheckAnalysis
@@ -617,5 +620,6 @@ export namespace Statistics {
     getStatisticSubjectiveByGroup: GetStatisticSubjectiveByGroup
     /** 决策分析-监控统计-主观题分数分布(按评卷员) */
     getStatisticSubjectiveByMarker: GetStatisticSubjectiveByMarker
+    getProvinceProcess: GetProvinceProcess
   }
 }

+ 5 - 0
src/api/statistics.ts

@@ -151,6 +151,11 @@ const StatisticsApi: DefineApiModule<Statistics.ApiMap> = {
       'Content-Type': 'application/json',
     },
   },
+  getProvinceProcess: {
+    url: '/api/statistic/marking/progress/by/province/export',
+    download: true,
+    timeout: 0,
+  },
 }
 
 export default StatisticsApi

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

@@ -108,7 +108,7 @@ a {
 
 #app {
   height: 100%;
-  min-width: 1350px;
+  min-width: 1300px;
 }
 
 

+ 10 - 2
src/components/element/BaseDialog.vue

@@ -1,7 +1,7 @@
 <template>
   <el-dialog
+    custom-class="can-resize"
     custom
-    append-to-body
     align-center
     :close-on-click-modal="false"
     :close-on-press-escape="false"
@@ -12,7 +12,14 @@
     </template>
     <slot />
     <template v-if="props.footer !== false" #footer>
-      <slot name="footer"></slot>
+      <template v-if="!!props.canResize">
+        <div v-dialogResize="true" class="foot-box">
+          <slot name="footer"></slot>
+        </div>
+      </template>
+      <template v-else>
+        <slot name="footer"></slot>
+      </template>
     </template>
   </el-dialog>
 </template>
@@ -24,6 +31,7 @@ const props = withDefaults(
   defineProps<{
     header?: boolean
     footer?: boolean
+    canResize?: boolean
   }>(),
   { header: true, footer: true }
 )

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

@@ -6,6 +6,7 @@
     modal-class="no-mask"
     :width="useVW(560)"
     :modal="false"
+    :can-resize="true"
     @close="onToggleClick"
   >
     <div class="scoring-panel-box" :class="getClass('modal-box')">

+ 53 - 50
src/directives/dialogChange.ts

@@ -1,58 +1,61 @@
-import Vue from 'vue'
 export const dialogChange = {
-  mounted(el: any, binding: any, vnode: any, oldVnode: any) {
-    // 自定义属性,判断是否可拉伸
-    if (!binding.value) return
-    const dragDom = el.querySelector('.el-dialog')
-    const dragDomBody = el.querySelector('.el-dialog__body')
-    dragDomBody.style.overflow = 'auto'
-    const minHeight = 300
-    const minWidth = 400
-    // 右下角设置一个图标点击拖拽缩放大小(注意:此处mouse需要与代码中的类名一致,否则会报错)
-    const dragMouse: any = document.querySelector('.mouse')
-    // 鼠标拖拽
-    dragMouse.onmousedown = (e: any) => {
-      // content区域
-      const content = dragDom.parentNode.parentNode.parentNode.parentNode
-      const disX = e.clientX - dragDom.offsetWidth
-      const disY = e.clientY - dragDom.offsetHeight
+  mounted(el: any, binding: any, vnode: any) {
+    setTimeout(() => {
+      // 自定义属性,判断是否可拉伸
+      if (!binding.value) return
+      const dragDom: any = document.querySelector('.can-resize')
+      console.log('dragDom:', dragDom)
 
-      document.onmousemove = function (e) {
-        e.preventDefault() // 移动时禁用默认事件
-        // 通过事件委托,计算移动的距离e
-        let width = e.clientX - disX
-        let height = e.clientY - disY
+      const dragDomBody: any = dragDom.querySelector('.el-dialog__body')
+      dragDomBody.style.overflow = 'auto'
+      const minHeight = 300
+      const minWidth = 400
+      // 右下角设置一个图标点击拖拽缩放大小(注意:此处mouse需要与代码中的类名一致,否则会报错)
+      const dragMouse: any = document.querySelector('.mouse')
+      // 鼠标拖拽
+      dragMouse.onmousedown = (e: any) => {
+        // content区域
+        const content = dragDom.parentNode.parentNode
+        const disX = e.clientX - dragDom.offsetWidth
+        const disY = e.clientY - dragDom.offsetHeight
 
-        if (width > content.offsetWidth && height < content.offsetHeight) {
-          if (height < minHeight) {
-            height = minHeight
-          }
-          dragDom.style.height = `${height}px`
-          // 减去头部高度
-          dragDomBody.style.maxHeight = `${height - 60}px`
-        } else if (width < content.offsetWidth && height > content.offsetHeight) {
-          if (width < minWidth) {
-            width = minWidth
-          }
-          dragDom.style.width = `${width}px`
-        } else if (width < content.offsetWidth && height < content.offsetHeight) {
-          if (height < minHeight) {
-            height = minHeight
-          }
-          if (width < minWidth) {
-            width = minWidth
+        document.onmousemove = function (e) {
+          e.preventDefault() // 移动时禁用默认事件
+          // 通过事件委托,计算移动的距离e
+          let width = e.clientX - disX
+          let height = e.clientY - disY
+
+          if (width > content.offsetWidth && height < content.offsetHeight) {
+            if (height < minHeight) {
+              height = minHeight
+            }
+            dragDom.style.height = `${height}px`
+            // 减去头部高度
+            dragDomBody.style.maxHeight = `${height - 60}px`
+          } else if (width < content.offsetWidth && height > content.offsetHeight) {
+            if (width < minWidth) {
+              width = minWidth
+            }
+            dragDom.style.width = `${width}px`
+          } else if (width < content.offsetWidth && height < content.offsetHeight) {
+            if (height < minHeight) {
+              height = minHeight
+            }
+            if (width < minWidth) {
+              width = minWidth
+            }
+            dragDom.style.width = `${width}px`
+            dragDom.style.height = `${height}px`
+            // 减去头部高度
+            dragDomBody.style.maxHeight = `${height - 60}px`
           }
-          dragDom.style.width = `${width}px`
-          dragDom.style.height = `${height}px`
-          // 减去头部高度
-          dragDomBody.style.maxHeight = `${height - 60}px`
         }
+        document.onmouseup = function (e) {
+          document.onmousemove = null
+          document.onmouseup = null
+        }
+        return false
       }
-      document.onmouseup = function (e) {
-        document.onmousemove = null
-        document.onmouseup = null
-      }
-      return false
-    }
+    }, 50)
   },
 }

+ 182 - 0
src/directives/dialogResize.ts

@@ -0,0 +1,182 @@
+export const dialogResize = {
+  mounted(el: any, binding: any, vnode: any) {
+    console.log('eeeee', el)
+    const resizeEvent = new CustomEvent('drag-resize', {
+      detail: '尺寸变化',
+      bubbles: false,
+    })
+    // 初始化不最大化
+    el.fullscreen = false
+    // 弹框可拉伸最小宽高
+    const minWidth = 1100
+    const minHeight = 570
+    // 当前宽高
+    let nowWidth = minWidth
+    // eslint-disable-next-line no-unused-vars
+    let nowHight = minHeight
+    // 当前顶部高度
+    let nowMarginTop = 0
+    // 获取弹框头部(这部分可双击全屏)
+    let hasSetBodyHight = false
+    // 弹窗
+    const dragDom: any = document.querySelector('.can-resize')
+    const dialogHeaderEl = dragDom.querySelector('.el-dialog__header')
+
+    el.style.overflow = 'initial'
+    dragDom.className += ' el-drag-dialog'
+    console.log(el)
+    // 给弹窗加上overflow auto;不然缩小时框内的标签可能超出dialog;
+    dragDom.style.overflow = 'auto'
+    // 清除选择头部文字效果
+    // eslint-disable-next-line no-new-func
+    dialogHeaderEl.onselectstart = new Function('return false')
+    // 头部加上可拖动cursor
+    dialogHeaderEl.style.cursor = 'move'
+
+    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
+    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
+
+    // 头部插入最大化最小化元素
+    const maxMin = document.createElement('button')
+    maxMin.className += ' el-dialog__headerbtn el-dialog__minmax'
+    maxMin.style.right = '40px'
+    maxMin.style.color = '#ffffff'
+    maxMin.title = el.fullscreen ? '还原' : '最大化'
+    maxMin.innerHTML =
+      '<i class=' +
+      (el.fullscreen ? '"el-icon-crop"' : '"el-icon-full-screen"') +
+      ' onMouseOver="this.style.color=\'#409EFF\'" onMouseOut="this.style.color=\'inherit\'"></i>'
+    dialogHeaderEl.insertBefore(maxMin, dialogHeaderEl.childNodes[1])
+    const moveDown = (e: any) => {
+      // 鼠标按下,计算当前元素距离可视区的距离
+      const disX = e.clientX - dialogHeaderEl.offsetLeft
+      const disY = e.clientY - dialogHeaderEl.offsetTop
+
+      // 获取到的值带px 正则匹配替换
+      let styL: any, styT: any
+
+      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
+      if (sty.left.includes('%')) {
+        styL = +document.body.clientWidth * (+sty.left.replace(/\\%/g, '') / 100)
+        styT = +document.body.clientHeight * (+sty.top.replace(/\\%/g, '') / 100)
+      } else {
+        styL = +sty.left.replace(/\px/g, '')
+        styT = +sty.top.replace(/\px/g, '')
+      }
+
+      document.onmousemove = function (e) {
+        // 通过事件委托,计算移动的距离
+        const l = e.clientX - disX
+        const t = e.clientY - disY
+
+        // 移动当前元素
+        dragDom.style.left = `${l + styL}px`
+        dragDom.style.top = `${t + styT}px`
+
+        // 将此时的位置传出去
+        // binding.value({x:e.pageX,y:e.pageY})
+      }
+
+      document.onmouseup = function (e) {
+        document.onmousemove = null
+        document.onmouseup = null
+      }
+    }
+    // dialogHeaderEl.onmousedown = moveDown
+    let bodyHeight = 'auto'
+
+    function setMaxMin() {
+      if (el.fullscreen) {
+        const i: any = maxMin.querySelector('.el-icon-crop')
+        i.classList.remove('el-icon-crop')
+        i.classList.add('el-icon-full-screen')
+        maxMin.innerHTML = '<i class="el-icon-full-screen"></i>'
+        maxMin.title = '最大化'
+        dragDom.style.height = nowHight + 'px'
+        dragDom.style.width = nowWidth + 'px'
+        dragDom.style.marginTop = window.innerHeight * 0.07 + 'px'
+        el.fullscreen = false
+        dialogHeaderEl.style.cursor = 'move'
+        // dialogHeaderEl.onmousedown = moveDown
+        // dragDom.querySelector('.el-dialog__body').style.height = bodyHeight;
+        hasSetBodyHight = false
+      } else {
+        const i: any = maxMin.querySelector('.el-icon-full-screen')
+        i.classList.remove('el-icon-full-screen')
+        i.classList.add('el-icon-crop')
+        maxMin.title = '还原'
+        bodyHeight = dragDom.querySelector('.el-dialog__body').offsetHeight + 'px'
+        nowHight = dragDom.clientHeight
+        nowWidth = dragDom.clientWidth
+        nowMarginTop = dragDom.style.marginTop
+        dragDom.style.left = 0
+        dragDom.style.top = 0
+        dragDom.style.height = window.innerHeight + 'px'
+        dragDom.style.width = '100VW'
+        dragDom.style.marginTop = 0
+        el.fullscreen = true
+        dialogHeaderEl.style.cursor = 'initial'
+        dialogHeaderEl.onmousedown = null
+        if (!hasSetBodyHight) {
+          const footerHeight =
+            dragDom.querySelector('.el-dialog__footer') && dragDom.querySelector('.el-dialog__footer').offsetHeight
+          dragDom.querySelector('.el-dialog__body').style.height =
+            'calc(100% - ' + (dialogHeaderEl.offsetHeight + footerHeight) + 'px)'
+          /*          dragDom.querySelector('.el-dialog__body').style.height =
+              window.innerHeight*0.9
+               - (dialogHeaderEl.offsetHeight + footerHeight) + 'px'*/
+          hasSetBodyHight = true
+        }
+      }
+      el.dispatchEvent(resizeEvent)
+    }
+
+    // 点击放大缩小效果
+    // maxMin.onclick = setMaxMin
+    // 双击头部效果
+    // dialogHeaderEl.ondblclick = setMaxMin
+    // 拉伸
+    const resizeEl = document.createElement('div')
+    dragDom.appendChild(resizeEl)
+    // 在弹窗右下角加上一个10-10px的控制块
+    resizeEl.style.cursor = 'se-resize'
+    resizeEl.style.position = 'absolute'
+    resizeEl.style.height = '10px'
+    resizeEl.style.width = '10px'
+    resizeEl.style.right = '0px'
+    resizeEl.style.bottom = '0px'
+    resizeEl.style.zIndex = '99'
+    // 鼠标拉伸弹窗
+    resizeEl.onmousedown = (e) => {
+      // 记录初始x位置
+      const clientX = e.clientX
+      // 鼠标按下,计算当前元素距离可视区的距离
+      const disX = e.clientX - resizeEl.offsetLeft
+      const disY = e.clientY - resizeEl.offsetTop
+      document.onmousemove = function (e) {
+        e.preventDefault() // 移动时禁用默认事件
+        // 通过事件委托,计算移动的距离
+        const x = e.clientX - disX + (e.clientX - clientX) // 这里 由于elementUI的dialog控制居中的,所以水平拉伸效果是双倍
+        const y = e.clientY - disY
+        // 比较是否小于最小宽高
+        // dragDom.style.width = x > minWidth ? `${x}px` : minWidth + 'px'
+        // dragDom.style.height = y > minHeight ? `${y}px` : minHeight + 'px'
+        dragDom.style.width = `${x}px`
+        dragDom.style.height = `${y}px`
+        if (!hasSetBodyHight) {
+          const footerHeight =
+            dragDom.querySelector('.el-dialog__footer') && dragDom.querySelector('.el-dialog__footer').offsetHeight
+          dragDom.querySelector('.el-dialog__body').style.height =
+            'calc(100% - ' + (dialogHeaderEl.offsetHeight + footerHeight) + 'px)'
+          hasSetBodyHight = true
+        }
+      }
+      // 拉伸结束
+      document.onmouseup = function (e) {
+        document.onmousemove = null
+        document.onmouseup = null
+        el.dispatchEvent(resizeEvent)
+      }
+    }
+  },
+}

+ 4 - 2
src/directives/index.ts

@@ -1,5 +1,7 @@
-import { dialogChange } from './dialogChange'
+// import { dialogChange } from './dialogChange'
+import { dialogResize } from './dialogResize'
 
 export function setupDirectives(app: any) {
-  app.directive('dialogChange', dialogChange)
+  // app.directive('dialogChange', dialogChange)
+  app.directive('dialogResize', dialogResize)
 }

+ 2 - 1
src/main.ts

@@ -12,8 +12,9 @@ import '@style/app.scss'
 
 import 'element-plus/theme-chalk/src/message.scss'
 
-const app = createApp(App).use(createPinia()).use(router).use(ElLoading)
+const app = createApp(App)
 setupDirectives(app)
+app.use(createPinia()).use(router).use(ElLoading)
 useECharts()
 
 app.mount('#app')

+ 1 - 1
src/modules/admin-data/marking/index.vue

@@ -104,7 +104,7 @@ const { formRef, elFormRef, defineColumn, _ } = useForm()
 
 const model = reactive<ExtractApiParams<'importMarkingData'>>({
   subjectCode: dataModel.subject || '',
-  separator: '',
+  separator: ',',
   mainNumber: dataModel.question,
   packageTaskCount: 5,
   dayNumber: void 0,

+ 1 - 1
src/modules/admin-data/paper/components/rf.vue

@@ -72,7 +72,7 @@ const model = reactive<ExtractApiParams<'importRfPaper'>>({
   subjectCode: dataModel.subject || '',
   mainNumber: dataModel.question,
   prefix: '',
-  separator: '',
+  separator: ',',
 })
 
 watch([() => model.subjectCode, () => model.mainNumber], () => {

+ 2 - 2
src/modules/admin-exam/nav/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="full nav-page">
+  <div class="full nav-page flex justify-center items-center">
     <div class="flex flex-wrap">
       <div class="radius-base nav-card">考试管理</div>
       <router-link v-show="hasPermissions('/exam/manage')" to="/exam/manage">
@@ -31,7 +31,7 @@ const { hasPermissions } = useNavPermissions()
 
 <style scoped lang="scss">
 .nav-page {
-  padding: 160px;
+  // padding: 160px;
   .nav-card {
     width: 420px;
     height: 180px;

+ 1 - 1
src/modules/admin-user/edit-user/index.vue

@@ -218,7 +218,7 @@ function cancel() {
 <style scoped lang="scss">
 .edit-user-view {
   .form-card {
-    padding-right: 1000px;
+    padding-right: calc(100% - 420px);
   }
 }
 </style>

+ 9 - 2
src/modules/analysis/marking-progress/components/GroupProgress.vue

@@ -3,7 +3,10 @@
     <base-form size="small" :items="items" :model="model">
       <template #form-item-operation>
         <el-button class="m-l-base" type="primary" @click="onSearch">查询</el-button>
-        <el-button type="primary" custom-1 @click="onExport">导出</el-button>
+        <el-button :loading="exportLoading" type="primary" custom-1 @click="onExport">导出</el-button>
+        <el-button :loading="provinceExportLoading" custom-1 type="primary" @click="provinceExport"
+          >省份进度导出</el-button
+        >
       </template>
     </base-form>
     <base-table border stripe :columns="columns" :data="result"></base-table>
@@ -38,11 +41,15 @@ const onSearch = () => {
   fetch({ ...model })
 }
 
-const { fetch: exportStatistics } = useFetch('exportMarkProgressByMarker', 'get')
+const { fetch: exportStatistics, loading: exportLoading } = useFetch('exportMarkProgressByMarker', 'get')
+const { fetch: exportProvince, loading: provinceExportLoading } = useFetch('getProvinceProcess', 'get')
 
 const onExport = () => {
   exportStatistics(model)
 }
+const provinceExport = () => {
+  exportProvince({ subjectCode: model.subjectCode })
+}
 
 watch(dataModel, () => {
   model.subjectCode = dataModel.subject || ''

+ 5 - 3
src/modules/analysis/monitoring/index.vue

@@ -5,7 +5,7 @@
       <el-button type="primary" :loading="loading" @click="onRefresh">刷新</el-button>
     </div>
     <div class="flex flex-1 p-base scroll-y-auto">
-      <div class="flex justify-around data-card-view">
+      <div class="flex justify-between data-card-view">
         <div
           v-for="card in cards"
           :key="card.dataField"
@@ -351,11 +351,13 @@ watch([interval, initFinish], () => {
     }
   }
   .data-card-view {
-    width: 1118px;
+    // width: 1118px;
+    width: calc(100% - 291px);
     flex-wrap: wrap;
     align-content: flex-start;
     .data-card {
-      width: 272px;
+      // width: 272px;
+      width: 24%;
       height: 337px;
       padding-top: 2px;
       &.active {

+ 3 - 2
src/modules/analysis/statistics/index.vue

@@ -8,7 +8,7 @@
       </base-form>
     </div>
     <div class="flex-1 p-base scroll-y-auto">
-      <div class="flex justify-around data-card-view">
+      <div class="flex justify-between data-card-view">
         <div
           v-for="card in cards"
           :key="card.dataField"
@@ -270,7 +270,8 @@ onOptionInit(onRefresh)
     flex-wrap: wrap;
     align-content: flex-start;
     .data-card {
-      width: 347px;
+      // width: 347px;
+      width: 24%;
       height: 337px;
       padding-top: 2px;
       margin-bottom: $ExtraSmallGapSpace;

+ 2 - 1
src/modules/bootstrap/check-exam/index.vue

@@ -72,7 +72,8 @@ async function joinOrCreateExam(isCreate: boolean) {
       ElMessage.error(`请选择一个考试批次`)
     }
     mainStore.getMyUserInfo()
-    replace({ name: 'UserManage' })
+    // replace({ name: 'UserManage' })
+    replace({ name: 'ExamNav' })
   }
 }
 </script>

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

@@ -155,7 +155,8 @@ const onDbClick = (row: TableDataType) => {
     push({
       name: 'TrainingDetail',
       query: {
-        stage: row.stage,
+        // stage: row.stage,
+        stage: row.queryStage,
         markerId: row.markerId,
         forceGroupMarkerId: row.forceGroupMarkerId,
       },

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

@@ -29,7 +29,7 @@
             <span class="m-l-extra-small detail-info-label-num">{{ selfCheckDataDetail?.length }}</span>
           </el-button>
         </div>
-        <div class="flex-1 scroll-auto">
+        <div class="flex-1 scroll-auto m-t-mini">
           <base-table
             ref="tableRef"
             border