index.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <template>
  2. <a-card>
  3. <div class="paper-list">
  4. <!-- 任务中心开始 -->
  5. <div class="task-center" style="margin-bottom: 24px">
  6. <h3 style="border-left: solid 4px #3651d4; padding-left: 8px; margin-bottom: 12px; font-size: 18px">
  7. <div>{{ examName }}</div>
  8. </h3>
  9. <a-spin :spinning="taskLoading">
  10. <a-table
  11. ref="paperTableRef"
  12. :columns="taskColumns"
  13. :data-source="taskList"
  14. :expand-row-by-click="true"
  15. :pagination="pagination"
  16. >
  17. <template #bodyCell="{ column, record }">
  18. <template v-if="record.examType && column.key === 'examType'">
  19. {{ examTypeName(record.examType) || '--' }}
  20. </template>
  21. <template v-if="record.startTime && column.key === 'startTime'">
  22. {{ formatDateTime(record.startTime) || '--' }}
  23. </template>
  24. <template v-if="record.endTime && column.key === 'endTime'">
  25. {{ formatDateTime(record.endTime) || '--' }}
  26. </template>
  27. <template v-if="record.paperType && column.key === 'paperType'">
  28. {{ paperTypeEnum(record.paperType) }}
  29. </template>
  30. <template v-if="column.key === 'status'">
  31. <a-tag :color="statusTagFormatter(record.status)" size="small">
  32. {{ statusTextFormatter(record.status) }}
  33. </a-tag>
  34. </template>
  35. <template v-if="column.key === 'action'">
  36. <router-link
  37. v-if="record.status == 0"
  38. :to="{ path: '/student/do', query: { id: record.paperId ? record.paperId : record.id } }"
  39. target="_blank"
  40. >
  41. <a-button type="link" size="small">{{ examType == 4 ? `开始答题` : `填写${examName}` }}</a-button>
  42. </router-link>
  43. <router-link
  44. v-if="record.status == 2"
  45. :to="{ path: '/student/read', query: { id: record.answerId } }"
  46. target="_blank"
  47. >
  48. <a-button type="link" size="small">查看结果</a-button>
  49. </router-link>
  50. </template>
  51. </template>
  52. </a-table>
  53. </a-spin>
  54. </div>
  55. </div>
  56. </a-card>
  57. </template>
  58. <script setup>
  59. import { useExamStore } from '@/store/exam'
  60. import examPaperApi from '@/api/student/examPaper'
  61. import taskApi from '@/api/student/examPaper'
  62. import { useRoute } from 'vue-router'
  63. import tool from '@/utils/tool'
  64. import { parseTime } from '@/utils/exam'
  65. const route = useRoute()
  66. const formatDateTime = (val) => {
  67. if (!val) return ''
  68. return parseTime(val, '{y}-{m}-{d} {h}:{i}:{s}')
  69. }
  70. // store
  71. const examStore = useExamStore()
  72. const paperTypeEnum = computed(() => {
  73. return (key) => {
  74. return examStore.paperTypeEnum.filter((item) => item.key == key)[0]?.value
  75. }
  76. })
  77. const examNameOption = tool.dictList('EXAM_TYPE')
  78. const examTypeName = computed(() => {
  79. return (id) => {
  80. return examNameOption.filter((r) => r.value == id)[0].label
  81. }
  82. })
  83. const examName = computed(() => {
  84. switch (examType.value) {
  85. case '1':
  86. return '考试'
  87. break
  88. case '2':
  89. return '章节测验'
  90. break
  91. case '3':
  92. return '调查问卷'
  93. break
  94. case '4':
  95. return '我的作业'
  96. break
  97. }
  98. })
  99. // 任务中心相关
  100. const taskList = ref([])
  101. const taskLoading = ref(false)
  102. // 选中表格的表格common
  103. const selectedCommons = [
  104. {
  105. title: '操作',
  106. dataIndex: 'action',
  107. align: 'center',
  108. width: 80
  109. },
  110. {
  111. title: '机构名',
  112. dataIndex: 'name',
  113. ellipsis: true
  114. }
  115. ]
  116. const taskColumns = computed(() =>
  117. taskAllColumns.value.filter((r) => r.columnsType.includes(parseFloat(examType.value)))
  118. )
  119. const taskAllColumns = ref([
  120. { title: '课程名称', dataIndex: 'courseName', key: 'courseName', columnsType: [4] },
  121. { title: '章节名称', dataIndex: 'chapterName', key: 'chapterName', columnsType: [4] },
  122. { title: '课时名称', dataIndex: 'hourName', key: 'hourName', columnsType: [4] },
  123. { title: '作业名称', dataIndex: 'name', key: 'name', columnsType: [4] },
  124. { title: '试卷类型', dataIndex: 'paperType', key: 'paperType', width: 120, columnsType: [4] },
  125. { title: '问卷名称', dataIndex: 'examName', key: 'examName', columnsType: [1, 2, 3] },
  126. { title: '问卷类型', dataIndex: 'examType', key: 'examType', width: 120, columnsType: [1, 2, 3] },
  127. { title: '开始时间', dataIndex: 'startTime', key: 'startTime', width: 180, columnsType: [1, 2, 3] },
  128. { title: '结束时间', dataIndex: 'endTime', key: 'endTime', width: 180, columnsType: [1, 2, 3] },
  129. { title: '状态', dataIndex: 'status', key: 'status', width: 90, columnsType: [1, 2, 3, 4] },
  130. { title: '操作', key: 'action', align: 'right', width: 120, columnsType: [1, 2, 3, 4] }
  131. ])
  132. const statusTextFormatter = (status) => {
  133. if (status === 0) return '未答题'
  134. if (status === 1) return '待判分'
  135. if (status === 2) return '已完成'
  136. return ''
  137. }
  138. const statusTagFormatter = (status) => {
  139. if (status === 2) return 'blue'
  140. if (status === 1) return 'green'
  141. if (status === 0) return 'gray'
  142. return 'default'
  143. }
  144. const getTaskList = async () => {
  145. taskLoading.value = true
  146. try {
  147. let res = []
  148. const params = {
  149. current: pagination.value.current,
  150. size: pagination.value.pageSize,
  151. subjectId: pagination.value.subjectId,
  152. courseId: route.query.id,
  153. paperType: paperType.value,
  154. examType: examType.value
  155. }
  156. if (examType.value == 4) {
  157. res = await examPaperApi.newPageList(params)
  158. } else {
  159. res = await taskApi.pageExamList(params)
  160. }
  161. taskList.value = res?.records || []
  162. pagination.value.total = res.total
  163. } catch (e) {
  164. taskList.value = []
  165. }
  166. taskLoading.value = false
  167. }
  168. // 学科分类
  169. const pagination = ref({
  170. current: 1,
  171. pageSize: 10,
  172. onChange: (current) => {
  173. pagination.value.current = current
  174. getTaskList()
  175. }
  176. })
  177. const handleChange = (value) => {
  178. pagination.value.subjectId = value
  179. getTaskList()
  180. }
  181. // lifecycle
  182. const examType = ref()
  183. const paperType = ref(2)
  184. const channel = new BroadcastChannel('getTaskList')
  185. channel.onmessage = function (event) {
  186. if (event.data.type == 1) {
  187. getTaskList()
  188. }
  189. }
  190. onMounted(() => {
  191. examType.value = route.params && route.params.examType
  192. getTaskList()
  193. })
  194. onUnmounted(() => {
  195. channel.onmessage = null
  196. channel.close()
  197. })
  198. </script>
  199. <style lang="less" scoped>
  200. .paper-list {
  201. margin-top: 10px;
  202. .task-center {
  203. margin-bottom: 24px;
  204. }
  205. }
  206. </style>