index.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <template>
  2. <div class="flex direction-column full">
  3. <mark-header
  4. :exclude-operations="['remark', 'problem', 'example', 'delete', 'bookmark']"
  5. :paper-path="current?.url"
  6. @click="onOperationClick"
  7. ></mark-header>
  8. <div class="flex flex-1 overflow-hidden p-base mark-container">
  9. <div
  10. class="flex flex-1 direction-column radius-base fill-blank mark-content"
  11. :class="{ 'text-center': center }"
  12. :style="{ 'background-color': backgroundColor }"
  13. >
  14. <right-button class="next-button" @click="checkNext" />
  15. <div class="flex-1 p-base scroll-auto mark-content-paper">
  16. <img :src="dataUrl" alt="" class="paper-img" :style="{ 'background-color': frontColor }" />
  17. </div>
  18. </div>
  19. <div class="p-base radius-base fill-blank scroll-auto m-l-base table-view">
  20. <base-table
  21. ref="tableRef"
  22. border
  23. stripe
  24. size="small"
  25. :data="tableData"
  26. :columns="columns"
  27. highlight-current-row
  28. @current-change="onCurrentChange"
  29. ></base-table>
  30. </div>
  31. </div>
  32. </div>
  33. </template>
  34. <script setup lang="ts" name="MarkingViewSample">
  35. /** 查看样卷 */
  36. import { computed } from 'vue'
  37. import { useSetImgBg } from '@/hooks/useSetImgBg'
  38. import useFetch from '@/hooks/useFetch'
  39. import useMarkHeader from '@/hooks/useMarkHeader'
  40. import useTableCheck from '@/hooks/useTableCheck'
  41. import MarkHeader from '@/components/shared/MarkHeader.vue'
  42. import BaseTable from '@/components/element/BaseTable.vue'
  43. import MarkHistoryList from '@/components/shared/MarkHistoryList.vue'
  44. import RightButton from '@/components/shared/RightButton.vue'
  45. import type { SetImgBgOption } from '@/hooks/useSetImgBg'
  46. import type { ExtractApiResponse } from '@/api/api'
  47. import type { MarkHeaderInstance, EpTableColumn } from 'global-type'
  48. type RowType = ExtractArrayValue<ExtractApiResponse<'viewSamplePaper'>> & { index: number }
  49. const {
  50. rotate,
  51. scale,
  52. center,
  53. frontColor,
  54. backgroundColor,
  55. onBack,
  56. onScaleChange,
  57. onCenter,
  58. onRotate,
  59. setBackgroundColor,
  60. setFrontColor,
  61. onViewStandard,
  62. } = useMarkHeader()
  63. /** 刷新 */
  64. const onRefresh = () => {
  65. viewSamplePaper()
  66. }
  67. type OperationClick = MarkHeaderInstance['onClick']
  68. type OperationType = Parameters<Exclude<OperationClick, undefined>>[0]['type']
  69. const operationHandles: Partial<Record<OperationType, (...args: any) => void>> = {
  70. back: onBack,
  71. 'scale-change': onScaleChange,
  72. center: onCenter,
  73. rotate: onRotate,
  74. 'front-color': setFrontColor,
  75. 'background-color': setBackgroundColor,
  76. refresh: onRefresh,
  77. standard: onViewStandard,
  78. }
  79. const onOperationClick: OperationClick = ({ type, value }) => {
  80. operationHandles[type]?.(value)
  81. }
  82. /** 样卷 */
  83. const columns: EpTableColumn<RowType>[] = [
  84. { label: '密号', prop: 'secretNumber', width: 100, fixed: 'left' },
  85. { label: '题目', prop: 'mainTitle' },
  86. { label: '分数', prop: 'score', width: 50 },
  87. { label: '提交人', prop: 'markerName' },
  88. // { label: '提交时间', prop: 'markTime' },
  89. { label: '给分说明', prop: 'description' },
  90. { label: '提交时间', prop: 'markTime', width: 160 },
  91. ]
  92. const { fetch: viewSamplePaper, result: samplePaperList } = useFetch('viewSamplePaper')
  93. const { tableRef, tableData, current, next: checkNext, onCurrentChange } = useTableCheck(samplePaperList)
  94. viewSamplePaper()
  95. const imgOption = computed<SetImgBgOption>(() => {
  96. return {
  97. image: current?.value?.url,
  98. rotate: rotate.value,
  99. scale: scale.value,
  100. }
  101. })
  102. const { drawing, dataUrl } = useSetImgBg(imgOption, frontColor, setFrontColor)
  103. </script>
  104. <style scoped lang="scss">
  105. .mark-container {
  106. .mark-content {
  107. position: relative;
  108. .preview {
  109. position: absolute;
  110. cursor: pointer;
  111. top: 10px;
  112. right: 20px;
  113. font-size: 24px;
  114. }
  115. .next-button {
  116. position: absolute;
  117. right: -20px;
  118. top: 300px;
  119. }
  120. .mark-content-paper {
  121. img {
  122. max-width: 100%;
  123. }
  124. }
  125. }
  126. .table-view {
  127. width: 580px;
  128. }
  129. }
  130. </style>