index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. <template>
  2. <div>
  3. <a-card style="width: 100%;" class="titleCard">
  4. <div style="font-size: 18px">
  5. <div>我的{{ examName }}</div>
  6. </div>
  7. </a-card>
  8. <a-card style="width: 100%" class="mt-3">
  9. <div class="flc mb-4">
  10. <div class="fcc mr-1">分类:</div>
  11. <a-select
  12. v-if="examType == 1"
  13. v-model:value="examTypeSelect"
  14. placeholder="所有分类"
  15. style="width: 110px"
  16. :options="typeOptionsVal"
  17. @change="handleChangeVal"
  18. allowClear
  19. ></a-select>
  20. </div>
  21. <a-spin :spinning="taskLoading">
  22. <a-table
  23. ref="paperTableRef"
  24. :columns="taskColumns"
  25. :data-source="taskList"
  26. :expand-row-by-click="true"
  27. :pagination="pagination"
  28. >
  29. <template #headerCell="{ column }">
  30. <template v-if="column.dataIndex === 'examName'">
  31. {{ examName + column.title }}
  32. </template>
  33. <template v-if="column.dataIndex === 'examType'">
  34. {{ examName + column.title }}
  35. </template>
  36. </template>
  37. <template #bodyCell="{ column, record }">
  38. <template v-if="record.examType && column.key === 'examType'">
  39. {{ examTypeName(record.examType) || '--' }}
  40. </template>
  41. <template v-if="record.startTime && column.key === 'startTime'">
  42. {{ formatDateTime(record.startTime) || '--' }}
  43. </template>
  44. <template v-if="record.endTime && column.key === 'endTime'">
  45. {{ formatDateTime(record.endTime) || '--' }}
  46. </template>
  47. <template v-if="record.paperType && column.key === 'paperType'">
  48. <span v-if="!examPaperType">{{ examTypeName(record.paperType) }}</span>
  49. <span v-if="examPaperType">{{ paperTypeEnum(record.paperType) }}</span>
  50. </template>
  51. <template v-if="column.key === 'status'">
  52. <a-tag :color="statusTagFormatter(record.status)" size="small">
  53. {{ statusTextFormatter(record.status) }}
  54. </a-tag>
  55. </template>
  56. <template v-if="column.key === 'action'">
  57. <router-link
  58. v-if="record.status == 0"
  59. :to="{ path: '/student/do', query: { id: record.paperId ? record.paperId : record.id } }"
  60. target="_blank"
  61. >
  62. <a-button type="link" size="small">{{ examType == 4 ? `开始答题` : `填写${examName}` }}</a-button>
  63. </router-link>
  64. <router-link
  65. v-if="record.status == 2"
  66. :to="{ path: '/student/read', query: { id: record.answerId } }"
  67. target="_blank"
  68. >
  69. <a-button type="link" size="small">查看结果</a-button>
  70. </router-link>
  71. </template>
  72. </template>
  73. </a-table>
  74. </a-spin>
  75. </a-card>
  76. </div>
  77. </template>
  78. <script setup>
  79. import { useExamStore } from '@/store/exam'
  80. import examPaperApi from '@/api/student/examPaper'
  81. import { useRoute } from 'vue-router'
  82. import tool from '@/utils/tool'
  83. import { parseTime } from '@/utils/exam'
  84. import Broadcast from '@/utils/Broadcast.js'
  85. const route = useRoute()
  86. const formatDateTime = (val) => {
  87. if (!val) return ''
  88. return parseTime(val, '{y}-{m}-{d} {h}:{i}:{s}')
  89. }
  90. // store
  91. const examStore = useExamStore()
  92. const paperTypeEnum = computed(() => {
  93. return (key) => {
  94. return examStore.paperTypeEnum.find((item) => item.key == key)?.value
  95. }
  96. })
  97. const examNameOption = tool.dictList('EXAM_TYPE')
  98. const examTypeName = computed(() => {
  99. return (id) => {
  100. return examNameOption.find((r) => r.value == id).label
  101. }
  102. })
  103. const typeOptionsVal = ref([
  104. {
  105. label: '考试',
  106. title: '任务',
  107. value: '1',
  108. paperType: '6'
  109. },
  110. {
  111. label: '章节测验',
  112. title: '章节测验',
  113. value: '2',
  114. paperType: '3',
  115. funcType: '5'
  116. },
  117. {
  118. label: '调查问卷',
  119. title: '调查问卷',
  120. value: '3',
  121. paperType: '5'
  122. },
  123. {
  124. label: '作业',
  125. title: '作业',
  126. value: '4',
  127. paperType: '2',
  128. funcType: '4'
  129. }
  130. ])
  131. const examName = computed(() => {
  132. return examType.value ? typeOptionsVal.value.find((e) => e.value == examType.value).title : ''
  133. })
  134. const handleChangeVal = (value) => {
  135. pagination.value.current = 1
  136. getTaskList()
  137. }
  138. // 任务中心相关
  139. const taskList = ref([])
  140. const taskLoading = ref(false)
  141. // 选中表格的表格common
  142. const selectedCommons = [
  143. {
  144. title: '操作',
  145. dataIndex: 'action',
  146. align: 'center',
  147. width: 80
  148. },
  149. {
  150. title: '机构名',
  151. dataIndex: 'name',
  152. ellipsis: true
  153. }
  154. ]
  155. const taskColumns = computed(() =>
  156. taskAllColumns.value.filter((r) => r.columnsType.includes(parseFloat(examType.value)))
  157. )
  158. const taskAllColumns = ref([
  159. { title: '课程名称', dataIndex: 'courseName', key: 'courseName', columnsType: [2, 4] },
  160. { title: '章节名称', dataIndex: 'chapterName', key: 'chapterName', columnsType: [2, 4] },
  161. { title: '课时名称', dataIndex: 'hourName', key: 'hourName', columnsType: [2, 4] },
  162. { title: '作业名称', dataIndex: 'name', key: 'name', columnsType: [2, 4] },
  163. { title: '试卷类型', dataIndex: 'paperType', key: 'paperType', width: 120, columnsType: [2, 4] },
  164. { title: '名称', dataIndex: 'examName', key: 'examName', columnsType: [1, 3] },
  165. { title: '类型', dataIndex: 'examType', key: 'examType', width: 120, columnsType: [1, 3] },
  166. { title: '开始时间', dataIndex: 'startTime', key: 'startTime', width: 180, columnsType: [1, 3] },
  167. { title: '结束时间', dataIndex: 'endTime', key: 'endTime', width: 180, columnsType: [1, 3] },
  168. { title: '状态', dataIndex: 'status', key: 'status', width: 90, columnsType: [1, 2, 3, 4] },
  169. { title: '操作', key: 'action', align: 'left', width: 120, columnsType: [1, 2, 3, 4] }
  170. ])
  171. const statusTextFormatter = (status) => {
  172. if (status === 0) return '未答题'
  173. if (status === 1) return '待判分'
  174. if (status === 2) return '已完成'
  175. return ''
  176. }
  177. const statusTagFormatter = (status) => {
  178. if (status === 2) return 'blue'
  179. if (status === 1) return 'green'
  180. if (status === 0) return 'red'
  181. return 'default'
  182. }
  183. const examPaperType = computed(() => {
  184. if (examType.value == 2 || examType.value == 4) {
  185. //章节/作业(固定试卷)
  186. return true
  187. } else {
  188. //任务试卷
  189. return false
  190. }
  191. })
  192. const getTaskList = async () => {
  193. taskLoading.value = true
  194. try {
  195. let res = []
  196. const params = {
  197. current: pagination.value.current,
  198. size: pagination.value.pageSize,
  199. subjectId: pagination.value.subjectId,
  200. courseId: route.query.id
  201. }
  202. if (examPaperType.value) {
  203. //章节/作业(固定试卷)
  204. params.paperType = typeOptionsVal.value.find((d) => d.value == examType.value).paperType
  205. params.funcType = typeOptionsVal.value.find((d) => d.value == examType.value).funcType
  206. res = await examPaperApi.newPageList(params)
  207. } else {
  208. //任务试卷
  209. params.examType = examType.value == 1 ? examTypeSelect.value : examType.value
  210. res = await examPaperApi.pageExamList(params)
  211. }
  212. taskList.value = res?.records || []
  213. pagination.value.total = res.total
  214. } catch (e) {
  215. taskList.value = []
  216. }
  217. taskLoading.value = false
  218. }
  219. // 学科分类
  220. const pagination = ref({
  221. current: 1,
  222. pageSize: 10,
  223. onChange: (current) => {
  224. pagination.value.current = current
  225. getTaskList()
  226. }
  227. })
  228. const handleChange = (value) => {
  229. pagination.value.subjectId = value
  230. getTaskList()
  231. }
  232. // lifecycle
  233. const examType = ref()
  234. const examTypeSelect = ref()
  235. const paperType = ref(2)
  236. // 监听消息
  237. const stopListening = Broadcast.on('getTaskList', (event) => {
  238. if (event.type == 1) {
  239. getTaskList()
  240. }
  241. })
  242. onMounted(() => {
  243. examType.value = route.params && route.params.examType
  244. getTaskList()
  245. })
  246. onBeforeUnmount(() => {
  247. stopListening()
  248. })
  249. </script>
  250. <style lang="less" scoped>
  251. .flc {
  252. display: flex;
  253. justify-content: flex-start;
  254. align-items: center;
  255. }
  256. .fcc {
  257. display: flex;
  258. justify-content: center;
  259. align-items: center;
  260. }
  261. :deep(.titleCard .ant-card-body){
  262. padding:16px 24px;
  263. }
  264. </style>