form.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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="gradeLevel" :rules="rules.gradeLevel">
  13. <a-select v-model:value="form.gradeLevel" placeholder="请选择年级" @change="levelChange">
  14. <a-select-option v-for="item in levelEnum" :key="item.key" :value="item.key">
  15. {{ item.value }}
  16. </a-select-option>
  17. </a-select>
  18. </a-form-item>
  19. <a-form-item label="标题" name="title" :rules="rules.title">
  20. <a-input v-model:value="form.title" placeholder="请输入任务标题" />
  21. </a-form-item>
  22. <a-form-item label="试卷">
  23. <a-table :dataSource="form.paperItems" :columns="paperColumns" rowKey="id" bordered :pagination="false">
  24. <template #bodyCell="{ column, record }">
  25. <template v-if="column.key === 'subjectId'">
  26. {{ subjectEnumFormat(record.subjectId) }}
  27. </template>
  28. <template v-else-if="column.key === 'action'">
  29. <a-button type="link" danger @click="removePaper(record)">删除</a-button>
  30. </template>
  31. </template>
  32. </a-table>
  33. </a-form-item>
  34. <a-form-item>
  35. <a-space>
  36. <a-button type="primary" @click="submitForm">提交</a-button>
  37. <a-button @click="resetForm">重置</a-button>
  38. <a-button type="dashed" @click="addPaper">添加试卷</a-button>
  39. </a-space>
  40. </a-form-item>
  41. </a-form>
  42. <a-modal
  43. v-model:visible="paperPage.showDialog"
  44. width="70%"
  45. title="选择试卷"
  46. @ok="confirmPaperSelect"
  47. @cancel="() => (paperPage.showDialog = false)"
  48. >
  49. <a-form layout="inline">
  50. <a-form-item label="学科">
  51. <a-select v-model:value="paperPage.queryParam.subjectId" allowClear style="width: 200px">
  52. <a-select-option v-for="item in paperPage.subjectFilter" :key="item.id" :value="item.id">
  53. {{ item.name }} ( {{ item.levelName }} )
  54. </a-select-option>
  55. </a-select>
  56. </a-form-item>
  57. <a-form-item>
  58. <a-button type="primary" @click="examPaperSubmitForm">查询</a-button>
  59. </a-form-item>
  60. </a-form>
  61. <a-table
  62. :dataSource="paperPage.tableData"
  63. :columns="modalColumns"
  64. rowKey="id"
  65. :loading="paperPage.listLoading"
  66. :rowSelection="rowSelection"
  67. bordered
  68. :pagination="false"
  69. style="margin-top: 16px"
  70. >
  71. <template #bodyCell="{ column, record }">
  72. <template v-if="column.key === 'subjectId'">
  73. {{ subjectEnumFormat(record.subjectId) }}
  74. </template>
  75. </template>
  76. </a-table>
  77. <a-pagination
  78. v-show="paperPage.total > 0"
  79. :total="paperPage.total"
  80. :current="paperPage.queryParam.pageIndex"
  81. :pageSize="paperPage.queryParam.pageSize"
  82. @change="onPageChange"
  83. @showSizeChange="onPageSizeChange"
  84. show-size-changer
  85. style="margin-top: 16px; text-align: right"
  86. />
  87. </a-modal>
  88. </div>
  89. </template>
  90. <script setup>
  91. import { ref, reactive, onMounted } from 'vue'
  92. import { useExamStore } from '@/store/exam.js'
  93. import taskApi from '@/api/exam/paper/task.js'
  94. import examPaperApi from '@/api/exam/paper/examPaperApi.js'
  95. const emit = defineEmits(['success'])
  96. const props = defineProps({
  97. id: {
  98. type: Number,
  99. default: null
  100. }
  101. })
  102. const formRef = ref()
  103. const examStore = useExamStore()
  104. const { subjectEnumFormat } = examStore
  105. const levelEnum = computed(() => examStore.getLevelEnum)
  106. const formLoading = ref(false)
  107. const form = reactive({
  108. id: null,
  109. gradeLevel: null,
  110. title: '',
  111. paperItems: []
  112. })
  113. const rules = {
  114. gradeLevel: [{ required: true, message: '请选择年级', trigger: 'change' }],
  115. title: [{ required: true, message: '请输入任务标题', trigger: 'blur' }]
  116. }
  117. const paperColumns = [
  118. { title: '学科', dataIndex: 'subjectId', key: 'subjectId', width: 120 },
  119. { title: '名称', dataIndex: 'name', key: 'name' },
  120. { title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 160 },
  121. { title: '操作', key: 'action', width: 100 }
  122. ]
  123. const modalColumns = [
  124. { title: 'Id', dataIndex: 'id', key: 'id', width: 90 },
  125. { title: '学科', dataIndex: 'subjectId', key: 'subjectId', width: 120 },
  126. { title: '名称', dataIndex: 'name', key: 'name' },
  127. {
  128. title: '创建时间',
  129. dataIndex: 'createTimeStr',
  130. key: 'createTimeStr',
  131. width: 200
  132. }
  133. ]
  134. const paperPage = reactive({
  135. subjectFilter: [],
  136. multipleSelection: [],
  137. showDialog: false,
  138. queryParam: {
  139. subjectId: null,
  140. level: null,
  141. paperType: 6,
  142. pageIndex: 1,
  143. pageSize: 5
  144. },
  145. listLoading: false,
  146. tableData: [],
  147. total: 0
  148. })
  149. // 试卷选择表格多选
  150. const selectedRowKeys = ref([])
  151. const rowSelection = reactive({
  152. selectedRowKeys: selectedRowKeys,
  153. onChange: (selectedRowKeysVal, selectedRows) => {
  154. selectedRowKeys.value = selectedRowKeysVal
  155. paperPage.multipleSelection = selectedRows
  156. }
  157. })
  158. // 初始化学科
  159. const initSubject = async (cb) => {
  160. await examStore.initSubject()
  161. paperPage.subjectFilter = examStore.subjects
  162. if (cb) cb()
  163. }
  164. // 年级变更
  165. const levelChange = () => {
  166. paperPage.queryParam.subjectId = null
  167. paperPage.subjectFilter = examStore.subjects.filter((data) => data.level === form.gradeLevel)
  168. }
  169. // 添加试卷
  170. const addPaper = () => {
  171. paperPage.queryParam.level = form.gradeLevel
  172. paperPage.showDialog = true
  173. search()
  174. }
  175. // 查询试卷
  176. const search = async () => {
  177. paperPage.listLoading = true
  178. paperPage.showDialog = true
  179. const params = {
  180. ...paperPage.queryParam,
  181. current: paperPage.queryParam.pageIndex,
  182. size: paperPage.queryParam.pageSize
  183. }
  184. delete params.pageIndex
  185. delete params.pageSize
  186. const data = await examPaperApi.taskExamPage(params)
  187. const re = data
  188. paperPage.tableData = re.records
  189. paperPage.total = re.total
  190. paperPage.queryParam.pageIndex = re.current
  191. paperPage.listLoading = false
  192. }
  193. // 确认选择试卷
  194. const confirmPaperSelect = () => {
  195. paperPage.multipleSelection.forEach((ep) => {
  196. if (!form.paperItems.some((item) => item.id === ep.id)) {
  197. form.paperItems.push(ep)
  198. }
  199. })
  200. paperPage.showDialog = false
  201. selectedRowKeys.value = []
  202. }
  203. // 分页
  204. const onPageChange = (page) => {
  205. paperPage.queryParam.pageIndex = page
  206. search()
  207. }
  208. const onPageSizeChange = (current, size) => {
  209. paperPage.queryParam.pageSize = size
  210. paperPage.queryParam.pageIndex = 1
  211. search()
  212. }
  213. // 查询按钮
  214. const examPaperSubmitForm = () => {
  215. paperPage.queryParam.pageIndex = 1
  216. search()
  217. }
  218. // 删除试卷
  219. const removePaper = (row) => {
  220. const idx = form.paperItems.findIndex((item) => item.id === row.id)
  221. if (idx !== -1) form.paperItems.splice(idx, 1)
  222. }
  223. // 提交表单
  224. const submitForm = () => {
  225. formRef.value.validate().then(async () => {
  226. formLoading.value = true
  227. try {
  228. await taskApi.edit(form)
  229. emit('success')
  230. } catch (e) {
  231. //
  232. } finally {
  233. formLoading.value = false
  234. }
  235. })
  236. }
  237. // 重置表单
  238. const resetForm = () => {
  239. const lastId = form.id
  240. formRef.value.resetFields()
  241. form.id = lastId
  242. form.gradeLevel = null
  243. form.title = ''
  244. form.paperItems = []
  245. }
  246. // 初始化
  247. onMounted(() => {
  248. initSubject(() => {
  249. paperPage.subjectFilter = examStore.subjects
  250. })
  251. const id = props.id
  252. if (id && parseInt(id) !== 0) {
  253. formLoading.value = true
  254. taskApi.select(id).then((re) => {
  255. Object.assign(form, re)
  256. formLoading.value = false
  257. })
  258. }
  259. })
  260. </script>
  261. <style lang="less" scoped>
  262. .app-container {
  263. padding: 24px;
  264. background: #fff;
  265. }
  266. </style>