index.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <template>
  2. <div class="task-container">
  3. <a-form layout="inline" :model="queryParam">
  4. <a-form-item label="考试类型:">
  5. <a-select v-model:value="queryParam.examType" placeholder="请选择试卷类型" @change="examTypeChange">
  6. <a-select-option v-for="item in examTypeEnum" :key="item.value" :value="item.value">
  7. {{ item.label }}
  8. </a-select-option>
  9. </a-select>
  10. </a-form-item>
  11. <a-form-item label="考试标题:">
  12. <a-input v-model:value="queryParam.examName" placeholder="请输入考试标题" style="min-width: 200px" allowClear />
  13. </a-form-item>
  14. <a-form-item label="考试状态:">
  15. <a-select style="min-width: 150px" v-model:value="queryParam.examStatus" allowClear placeholder="考试状态">
  16. <a-select-option :value="0">未开始</a-select-option>
  17. <a-select-option :value="1">已开始</a-select-option>
  18. <a-select-option :value="2">已结束</a-select-option>
  19. </a-select>
  20. </a-form-item>
  21. <a-form-item>
  22. <a-button type="primary" @click="submitForm">查询</a-button>
  23. <a-button style="margin-left: 20px" type="primary" @click="createTask">创建考试</a-button>
  24. </a-form-item>
  25. </a-form>
  26. <a-table
  27. :loading="listLoading"
  28. :data-source="tableData"
  29. :pagination="false"
  30. row-key="id"
  31. bordered
  32. style="margin-top: 16px"
  33. >
  34. <!-- <a-table-column title="Id" dataIndex="id" key="id" width="100" /> -->
  35. <a-table-column title="考试标题" dataIndex="examName" key="examName" />
  36. <a-table-column title="考试状态" dataIndex="examStatus" key="examStatus">
  37. <template #default="{ record }">
  38. <a-tag :color="record.examStatus === 0 ? 'default' : record.examStatus === 1 ? 'processing' : 'success'">
  39. {{ record.examStatus === 0 ? '未开始' : record.examStatus === 1 ? '已开始' : '已结束' }}
  40. </a-tag>
  41. </template>
  42. </a-table-column>
  43. <a-table-column title="开始时间" dataIndex="startTime" key="startTime">
  44. <template #default="{ record }">
  45. {{ formatDateTime(record.startTime) }}
  46. </template>
  47. </a-table-column>
  48. <a-table-column title="结束时间" dataIndex="endTime" key="endTime">
  49. <template #default="{ record }">
  50. {{ formatDateTime(record.endTime) }}
  51. </template>
  52. </a-table-column>
  53. <a-table-column title="创建时间" dataIndex="createTime" key="createTime">
  54. <template #default="{ record }">
  55. {{ formatDateTime(record.createTime) }}
  56. </template>
  57. </a-table-column>
  58. <a-table-column title="操作" key="action" align="center" :width="220">
  59. <template #default="{ record }">
  60. <a-button size="small" @click="editTask(record)">编辑</a-button>
  61. <a-button size="small" danger style="margin-left: 8px" @click="deleteTask(record)">删除</a-button>
  62. <a-button size="small" style="margin-left: 8px" @click="statistic(record)">统计分析</a-button>
  63. </template>
  64. </a-table-column>
  65. </a-table>
  66. <a-pagination
  67. v-show="total > 0"
  68. :total="total"
  69. :current="queryParam.pageIndex"
  70. :pageSize="queryParam.pageSize"
  71. @change="onPageChange"
  72. @showSizeChange="onPageSizeChange"
  73. :showSizeChanger="true"
  74. :pageSizeOptions="['10', '20', '50', '100']"
  75. style="margin-top: 16px; text-align: right"
  76. />
  77. <a-drawer
  78. :visible="drawerVisible"
  79. :title="drawerTitle"
  80. placement="right"
  81. width="900"
  82. @close="closeDrawer"
  83. destroyOnClose
  84. >
  85. <TaskEdit v-if="drawerVisible" :id="editId" @success="onEditSuccess" />
  86. </a-drawer>
  87. <a-modal
  88. :visible="statisticVisible"
  89. :title="statisticTitle"
  90. :footer="null"
  91. width="80%"
  92. @cancel="closeStatisticDrawer"
  93. >
  94. <StatisticAnalysis :paperId="statisticPaperId" :paperName="statisticExamName" examType="exam" />
  95. </a-modal>
  96. </div>
  97. </template>
  98. <script setup>
  99. import { ref, reactive, onMounted } from 'vue'
  100. import { message, Modal } from 'ant-design-vue'
  101. import examManagerApi from '@/api/exam/paper/examManager.js'
  102. import StatisticAnalysis from './StatisticAnalysis.vue'
  103. import TaskEdit from './form.vue'
  104. import { useExamStore } from '@/store/exam.js'
  105. import { storeToRefs } from 'pinia'
  106. import { parseTime } from '@/utils/exam'
  107. import tool from '@/utils/tool'
  108. const examStore = useExamStore()
  109. const { levelEnum, enumFormat } = storeToRefs(examStore)
  110. const drawerVisible = ref(false)
  111. const drawerTitle = ref('')
  112. const statisticExamName = ref(null)
  113. const editId = ref(null)
  114. // 统计分析
  115. const statisticVisible = ref(false)
  116. const statisticTitle = ref('')
  117. const statisticPaperId = ref(null)
  118. const examTypeEnum = tool.dictList('EXAM_TYPE').filter((item) => item.value !== '3')
  119. const queryParam = reactive({
  120. examName: null,
  121. examStatus: null,
  122. pageIndex: 1,
  123. pageSize: 10,
  124. examType: '1'
  125. })
  126. const listLoading = ref(false)
  127. const tableData = ref([])
  128. const total = ref(0)
  129. const fetchList = async () => {
  130. listLoading.value = true
  131. try {
  132. const params = {
  133. ...queryParam,
  134. current: queryParam.pageIndex,
  135. size: queryParam.pageSize
  136. }
  137. delete params.pageIndex
  138. delete params.pageSize
  139. const data = await examManagerApi.pageList(params)
  140. tableData.value = data.records || []
  141. total.value = data.total || 0
  142. queryParam.pageIndex = data.current || 1
  143. } finally {
  144. listLoading.value = false
  145. }
  146. }
  147. const statistic = async (record) => {
  148. statisticVisible.value = true
  149. statisticTitle.value = '统计分析'
  150. statisticExamName.value = record.examName
  151. statisticPaperId.value = record.paperId
  152. }
  153. const closeStatisticDrawer = () => {
  154. statisticVisible.value = false
  155. }
  156. onMounted(() => {
  157. fetchList()
  158. })
  159. const submitForm = () => {
  160. queryParam.pageIndex = 1
  161. fetchList()
  162. }
  163. const onPageChange = (page, pageSize) => {
  164. queryParam.pageIndex = page
  165. queryParam.pageSize = pageSize
  166. fetchList()
  167. }
  168. const onPageSizeChange = (current, size) => {
  169. queryParam.pageIndex = 1
  170. queryParam.pageSize = size
  171. fetchList()
  172. }
  173. const editTask = (record) => {
  174. drawerVisible.value = true
  175. drawerTitle.value = '编辑考试'
  176. editId.value = record.id
  177. }
  178. const deleteTask = (record) => {
  179. Modal.confirm({
  180. title: '确认删除该考试吗?',
  181. onOk: async () => {
  182. try {
  183. await examManagerApi.deleteExam([{ id: record.id }])
  184. fetchList()
  185. } catch (e) {
  186. message.error(e.msg || '删除失败')
  187. }
  188. }
  189. })
  190. }
  191. const levelFormatter = ({ text }) => {
  192. return enumFormat.value(levelEnum.value, text)
  193. }
  194. const createTask = () => {
  195. drawerVisible.value = true
  196. drawerTitle.value = '创建考试'
  197. editId.value = null
  198. }
  199. const onEditSuccess = () => {
  200. editId.value = null
  201. drawerVisible.value = false
  202. fetchList()
  203. }
  204. const closeDrawer = () => {
  205. drawerVisible.value = false
  206. }
  207. const formatDateTime = (val) => {
  208. if (!val) return ''
  209. return parseTime(val, '{y}-{m}-{d} {h}:{i}:{s}')
  210. }
  211. </script>
  212. <style lang="less" scoped>
  213. .task-container {
  214. background: #fff;
  215. padding: 24px;
  216. border-radius: 8px;
  217. }
  218. </style>