index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <template>
  2. <div class="store-page">
  3. <Breadcrumb />
  4. <a-card title="抢课批次管理">
  5. <div class="toolbar">
  6. <a-button v-if="canManage" type="primary" @click="openModal()">
  7. <template #icon><icon-plus /></template>
  8. 新建批次
  9. </a-button>
  10. <a-button @click="getList()">
  11. <template #icon><icon-refresh /></template>
  12. 刷新
  13. </a-button>
  14. </div>
  15. <a-alert type="info" class="info-alert">
  16. 停用批次会自动收回该批次下所有进行中的任务;修改批次 ID 后会自动将已分配任务重新放回待分配队列。
  17. </a-alert>
  18. <a-table
  19. :data="data"
  20. :bordered="false"
  21. hoverable
  22. class="table"
  23. :loading="loading"
  24. :pagination="false"
  25. :scroll="{ x: 980 }"
  26. >
  27. <template #columns>
  28. <a-table-column title="ID" data-index="id" :width="80" />
  29. <a-table-column title="名称" data-index="name" :width="180" ellipsis tooltip />
  30. <a-table-column title="批次 ID" data-index="jx0502zbid" :width="260" ellipsis tooltip />
  31. <a-table-column title="状态" :width="100">
  32. <template #cell="{ record }">
  33. <a-tag :color="record.enabled ? 'green' : 'gray'">{{ record.enabled ? '启用' : '停用' }}</a-tag>
  34. </template>
  35. </a-table-column>
  36. <a-table-column title="更新时间" :width="180">
  37. <template #cell="{ record }">{{ formatTime(record.update_time) }}</template>
  38. </a-table-column>
  39. <a-table-column title="操作" :width="100" :fixed="tableFixed('right')">
  40. <template #cell="{ record }">
  41. <a-button v-if="canManage" type="text" size="small" @click="openModal(record)">编辑</a-button>
  42. </template>
  43. </a-table-column>
  44. </template>
  45. <template #empty>
  46. <a-empty description="暂无抢课批次" />
  47. </template>
  48. </a-table>
  49. </a-card>
  50. <a-modal
  51. v-model:visible="visible"
  52. :title="form.id ? '编辑批次' : '新建批次'"
  53. :width="560"
  54. @ok="submitBatch"
  55. >
  56. <a-form :model="form" layout="vertical">
  57. <a-form-item label="批次名称" required>
  58. <a-input v-model="form.name" placeholder="例如:2025春公选课" allow-clear />
  59. </a-form-item>
  60. <a-form-item label="批次 ID(jx0502zbid)" required>
  61. <a-input v-model="form.jx0502zbid" placeholder="教务系统选课批次 ID" allow-clear />
  62. </a-form-item>
  63. <a-form-item label="是否启用">
  64. <a-switch v-model="form.enabled" />
  65. </a-form-item>
  66. </a-form>
  67. </a-modal>
  68. </div>
  69. </template>
  70. <script setup>
  71. import { computed, onMounted, reactive, ref } from 'vue'
  72. import { Notification } from '@arco-design/web-vue'
  73. import { IconPlus, IconRefresh } from '@arco-design/web-vue/es/icon'
  74. import { adminQkBatchList, adminQkBatchSave } from '@/api/qk'
  75. import { hasPermission } from '@/utils/permission'
  76. import { useResponsiveTable } from '@/hooks/useResponsiveTable'
  77. const { tableFixed } = useResponsiveTable()
  78. const canManage = computed(() => hasPermission('action.qk.admin.batchManage'))
  79. const data = ref([])
  80. const loading = ref(false)
  81. const visible = ref(false)
  82. const form = reactive({
  83. id: '',
  84. name: '',
  85. jx0502zbid: '',
  86. enabled: true
  87. })
  88. const formatTime = (time) => {
  89. if (!time) return '-'
  90. return new Date(Number(time)).toLocaleString('zh-CN')
  91. }
  92. const resetForm = () => {
  93. Object.assign(form, {
  94. id: '',
  95. name: '',
  96. jx0502zbid: '',
  97. enabled: true
  98. })
  99. }
  100. const openModal = (record) => {
  101. resetForm()
  102. if (record) {
  103. Object.assign(form, {
  104. id: record.id,
  105. name: record.name,
  106. jx0502zbid: record.jx0502zbid,
  107. enabled: !!record.enabled
  108. })
  109. }
  110. visible.value = true
  111. }
  112. const getList = async () => {
  113. loading.value = true
  114. try {
  115. const res = await adminQkBatchList()
  116. if (!res || res.code !== 0) {
  117. Notification.error({ title: '获取批次失败', content: res?.msg || '请稍后再试' })
  118. return
  119. }
  120. data.value = res.data || []
  121. } catch (error) {
  122. Notification.error({ title: '获取批次失败', content: error.message || '请稍后再试' })
  123. } finally {
  124. loading.value = false
  125. }
  126. }
  127. const submitBatch = async () => {
  128. const res = await adminQkBatchSave({
  129. id: form.id || undefined,
  130. name: form.name,
  131. jx0502zbid: form.jx0502zbid,
  132. enabled: form.enabled
  133. })
  134. if (!res || res.code !== 0) {
  135. Notification.error({ title: '保存失败', content: res?.msg || '请稍后再试' })
  136. return false
  137. }
  138. Notification.success({ title: '保存成功' })
  139. visible.value = false
  140. getList()
  141. }
  142. onMounted(() => {
  143. getList()
  144. })
  145. </script>
  146. <style scoped lang="less">
  147. @import '@/styles/store-theme.less';
  148. .toolbar {
  149. display: flex;
  150. gap: 10px;
  151. margin-bottom: 12px;
  152. }
  153. .info-alert {
  154. margin-bottom: 16px;
  155. }
  156. .table {
  157. margin-top: 4px;
  158. }
  159. </style>