form.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <template>
  2. <div class="app-container">
  3. <a-form
  4. :model="form"
  5. ref="formRef"
  6. :label-col="{ span: 4 }"
  7. :wrapper-col="{ span: 16 }"
  8. :rules="rules"
  9. :loading="formLoading"
  10. layout="horizontal"
  11. >
  12. <a-form-item label="考试标题" name="examName" :rules="rules.examName">
  13. <a-input v-model:value="form.examName" placeholder="请输入考试标题" />
  14. </a-form-item>
  15. <a-form-item label="选择试卷" name="paperId" :rules="rules.paperId">
  16. <a-input-group compact>
  17. <a-input
  18. v-model:value="selectedPaperName"
  19. placeholder="请选择试卷"
  20. readonly
  21. style="width: calc(100% - 100px)"
  22. />
  23. <a-button type="primary" @click="addPaper" style="width: 100px">选择试卷</a-button>
  24. </a-input-group>
  25. </a-form-item>
  26. <a-form-item label="课程" name="chapterId">
  27. <a-select v-model:value="form.chapterId" placeholder="请选择课程(可选)" allowClear>
  28. <a-select-option v-for="item in courseList" :key="item.courseId" :value="item.courseId">
  29. {{ item.courseName }}
  30. </a-select-option>
  31. </a-select>
  32. </a-form-item>
  33. <a-form-item label="开始时间" name="startTime" :rules="rules.startTime">
  34. <a-date-picker
  35. v-model:value="form.startTime"
  36. show-time
  37. format="YYYY-MM-DD HH:mm:ss"
  38. placeholder="请选择开始时间"
  39. style="width: 100%"
  40. :disabledDate="disabledStartDate"
  41. />
  42. </a-form-item>
  43. <a-form-item label="结束时间" name="endTime" :rules="rules.endTime">
  44. <a-date-picker
  45. v-model:value="form.endTime"
  46. show-time
  47. format="YYYY-MM-DD HH:mm:ss"
  48. placeholder="请选择结束时间"
  49. style="width: 100%"
  50. />
  51. </a-form-item>
  52. <a-form-item label="考试状态" name="examStatus">
  53. <a-radio-group v-model:value="form.examStatus">
  54. <a-radio :value="0">未开始</a-radio>
  55. <a-radio :value="1">已开始</a-radio>
  56. <a-radio :value="2">已结束</a-radio>
  57. </a-radio-group>
  58. </a-form-item>
  59. <a-form-item>
  60. <a-space>
  61. <a-button type="primary" @click="submitForm">提交</a-button>
  62. <a-button @click="resetForm">重置</a-button>
  63. </a-space>
  64. </a-form-item>
  65. </a-form>
  66. <a-modal
  67. v-model:visible="paperPage.showDialog"
  68. width="70%"
  69. title="选择试卷"
  70. @ok="confirmPaperSelect"
  71. @cancel="() => (paperPage.showDialog = false)"
  72. >
  73. <a-form layout="inline">
  74. <a-form-item label="试卷类型">
  75. <a-select
  76. v-model:value="paperPage.queryParam.paperType"
  77. placeholder="请选择试卷类型"
  78. @change="paperTypeChange"
  79. >
  80. <a-select-option v-for="item in paperTypeEnum" :key="item.key" :value="item.key">
  81. {{ item.value }}
  82. </a-select-option>
  83. </a-select>
  84. </a-form-item>
  85. <a-form-item>
  86. <a-button type="primary" @click="examPaperSubmitForm">查询</a-button>
  87. </a-form-item>
  88. </a-form>
  89. <a-table
  90. :dataSource="paperPage.tableData"
  91. :columns="modalColumns"
  92. rowKey="id"
  93. :loading="paperPage.listLoading"
  94. :rowSelection="rowSelection"
  95. bordered
  96. :pagination="false"
  97. style="margin-top: 16px"
  98. >
  99. <template #bodyCell="{ column, record }">
  100. <template v-if="column.key === 'subjectId'">
  101. {{ subjectEnumFormat(record.subjectId) }}
  102. </template>
  103. </template>
  104. </a-table>
  105. <a-pagination
  106. v-show="paperPage.total > 0"
  107. :total="paperPage.total"
  108. :current="paperPage.queryParam.pageIndex"
  109. :pageSize="paperPage.queryParam.pageSize"
  110. @change="onPageChange"
  111. @showSizeChange="onPageSizeChange"
  112. show-size-changer
  113. style="margin-top: 16px; text-align: right"
  114. />
  115. </a-modal>
  116. </div>
  117. </template>
  118. <script setup>
  119. import { ref, reactive, onMounted, computed } from 'vue'
  120. import { message } from 'ant-design-vue'
  121. import { useExamStore } from '@/store/exam.js'
  122. import examManagerApi from '@/api/exam/paper/examManager.js'
  123. import examPaperApi from '@/api/exam/paper/examPaperApi.js'
  124. import resourceAuditApi from '@/api/resourceAudit.js'
  125. import dayjs from 'dayjs'
  126. const emit = defineEmits(['success'])
  127. const props = defineProps({
  128. id: {
  129. type: Number,
  130. default: null
  131. }
  132. })
  133. const formRef = ref()
  134. const examStore = useExamStore()
  135. const { subjectEnumFormat } = examStore
  136. const paperTypeEnum = computed(() => examStore.paperTypeEnum)
  137. const formLoading = ref(false)
  138. const courseList = ref([])
  139. const form = reactive({
  140. id: null,
  141. examName: '',
  142. paperId: null,
  143. chapterId: null,
  144. startTime: null,
  145. endTime: null,
  146. examStatus: 0
  147. })
  148. const rules = {
  149. examName: [{ required: true, message: '请输入考试标题', trigger: 'blur' }],
  150. paperId: [{ required: true, message: '请选择试卷', trigger: 'change' }],
  151. startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
  152. endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }]
  153. }
  154. const selectedPaperName = ref('')
  155. const modalColumns = [
  156. { title: 'Id', dataIndex: 'id', key: 'id', width: 90 },
  157. // { title: '学科', dataIndex: 'subjectId', key: 'subjectId', width: 120 },
  158. { title: '名称', dataIndex: 'name', key: 'name' },
  159. {
  160. title: '创建时间',
  161. dataIndex: 'createTimeStr',
  162. key: 'createTimeStr',
  163. width: 200
  164. }
  165. ]
  166. const paperPage = reactive({
  167. subjectFilter: [],
  168. selectedPaper: null,
  169. showDialog: false,
  170. queryParam: {
  171. subjectId: null,
  172. paperType: null,
  173. pageIndex: 1,
  174. pageSize: 5
  175. },
  176. listLoading: false,
  177. tableData: [],
  178. total: 0
  179. })
  180. // 试卷选择表格单选
  181. const selectedRowKeys = ref([])
  182. const rowSelection = reactive({
  183. type: 'radio',
  184. selectedRowKeys: selectedRowKeys,
  185. onChange: (selectedRowKeysVal, selectedRows) => {
  186. selectedRowKeys.value = selectedRowKeysVal
  187. paperPage.selectedPaper = selectedRows[0] || null
  188. }
  189. })
  190. // 禁用开始时间大于今天的日期
  191. const disabledStartDate = (current) => {
  192. // 禁用大于今天的日期
  193. return current && current < dayjs().endOf('day')
  194. }
  195. // 试卷类型变更
  196. const paperTypeChange = () => {
  197. paperPage.queryParam.subjectId = null
  198. form.paperId = null
  199. selectedPaperName.value = ''
  200. }
  201. // 选择试卷
  202. const addPaper = () => {
  203. paperPage.showDialog = true
  204. search()
  205. }
  206. // 查询试卷
  207. const search = async () => {
  208. paperPage.listLoading = true
  209. paperPage.showDialog = true
  210. const params = {
  211. ...paperPage.queryParam,
  212. current: paperPage.queryParam.pageIndex,
  213. size: paperPage.queryParam.pageSize,
  214. paperType: paperPage.queryParam.paperType
  215. }
  216. delete params.pageIndex
  217. delete params.pageSize
  218. const data = await examPaperApi.pageList(params)
  219. const re = data
  220. paperPage.tableData = re.records
  221. paperPage.total = re.total
  222. paperPage.queryParam.pageIndex = re.current
  223. paperPage.listLoading = false
  224. }
  225. // 确认选择试卷
  226. const confirmPaperSelect = () => {
  227. if (!paperPage.selectedPaper) {
  228. message.warning('请选择一个试卷')
  229. return
  230. }
  231. form.paperId = paperPage.selectedPaper.id
  232. selectedPaperName.value = paperPage.selectedPaper.name
  233. paperPage.showDialog = false
  234. selectedRowKeys.value = []
  235. }
  236. // 分页
  237. const onPageChange = (page) => {
  238. paperPage.queryParam.pageIndex = page
  239. search()
  240. }
  241. const onPageSizeChange = (current, size) => {
  242. paperPage.queryParam.pageSize = size
  243. paperPage.queryParam.pageIndex = 1
  244. search()
  245. }
  246. // 查询按钮
  247. const examPaperSubmitForm = () => {
  248. paperPage.queryParam.pageIndex = 1
  249. search()
  250. }
  251. // 提交表单
  252. const submitForm = () => {
  253. formRef.value.validate().then(async () => {
  254. formLoading.value = true
  255. try {
  256. const submitData = {
  257. ...form,
  258. startTime: form.startTime ? form.startTime.format('YYYY-MM-DD HH:mm:ss') : null,
  259. endTime: form.endTime ? form.endTime.format('YYYY-MM-DD HH:mm:ss') : null
  260. }
  261. if (form.id) {
  262. await examManagerApi.edit(submitData)
  263. } else {
  264. await examManagerApi.createExam(submitData)
  265. }
  266. emit('success')
  267. } catch (e) {
  268. console.error(e)
  269. } finally {
  270. formLoading.value = false
  271. }
  272. })
  273. }
  274. // 重置表单
  275. const resetForm = () => {
  276. const lastId = form.id
  277. formRef.value.resetFields()
  278. form.id = lastId
  279. form.examName = ''
  280. form.paperId = null
  281. form.chapterId = null
  282. form.startTime = null
  283. form.endTime = null
  284. form.examStatus = 0
  285. selectedPaperName.value = ''
  286. paperPage.queryParam.paperType = null
  287. }
  288. // 初始化
  289. onMounted(() => {
  290. const id = props.id
  291. if (id && parseInt(id) !== 0) {
  292. formLoading.value = true
  293. examManagerApi.select(id).then((re) => {
  294. Object.assign(form, {
  295. ...re,
  296. startTime: re.startTime ? dayjs(re.startTime) : null,
  297. endTime: re.endTime ? dayjs(re.endTime) : null
  298. })
  299. // 如果有试卷ID,需要获取试卷名称显示
  300. if (re.paperId) {
  301. // 这里可以根据需要调用接口获取试卷名称
  302. selectedPaperName.value = '已选择试卷'
  303. }
  304. formLoading.value = false
  305. })
  306. }
  307. resourceAuditApi.courseAllList().then((re) => {
  308. if (re.code === 200) {
  309. courseList.value = re.data
  310. }
  311. })
  312. })
  313. </script>
  314. <style lang="less" scoped>
  315. .app-container {
  316. padding: 24px;
  317. background: #fff;
  318. }
  319. </style>