IssuePaperTypeDialog.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <template>
  2. <el-dialog
  3. v-model="visible"
  4. title="问题卷分类管理"
  5. width="800px"
  6. :close-on-click-modal="false"
  7. :close-on-press-escape="false"
  8. top="10vh"
  9. append-to-body
  10. @close="handleClose"
  11. @open="modalBeforeOpen"
  12. >
  13. <div class="issue-type-content">
  14. <!-- 操作按钮 -->
  15. <div class="action-bar">
  16. <el-button type="primary" @click="onAdd">新增</el-button>
  17. </div>
  18. <!-- 表格 -->
  19. <el-table :data="typeList" :loading="loading" class="type-table">
  20. <el-table-column property="id" label="编号" width="80" />
  21. <el-table-column property="name" label="分类名称" />
  22. <el-table-column property="type" label="类型" />
  23. <el-table-column label="操作" width="120">
  24. <template #default="scope">
  25. <el-button size="small" link @click="onEdit(scope.row)">
  26. 编辑
  27. </el-button>
  28. <el-button
  29. size="small"
  30. link
  31. type="danger"
  32. @click="onDelete(scope.row)"
  33. >
  34. 删除
  35. </el-button>
  36. </template>
  37. </el-table-column>
  38. </el-table>
  39. </div>
  40. <template #footer> </template>
  41. </el-dialog>
  42. <!-- 新增/编辑问题卷分类弹窗 -->
  43. <ModifyIssuePaperType
  44. ref="modifyTypeRef"
  45. :row-data="curRow"
  46. :exam-id="examId"
  47. @modified="getTypeList"
  48. />
  49. </template>
  50. <script setup lang="ts">
  51. import { ref } from 'vue';
  52. import { ElMessage, ElMessageBox } from 'element-plus';
  53. import type { IssuePaperTypeItem } from '@/api/types/issue-paper';
  54. import {
  55. getIssuePaperTypeList,
  56. deleteIssuePaperType,
  57. } from '@/api/issue-paper';
  58. import useModal from '@/hooks/modal';
  59. import useLoading from '@/hooks/loading';
  60. import { modalConfirm } from '@/utils/ui';
  61. import ModifyIssuePaperType from './ModifyIssuePaperType.vue';
  62. defineOptions({
  63. name: 'IssuePaperTypeDialog',
  64. });
  65. interface Props {
  66. examId: number;
  67. }
  68. const props = withDefaults(defineProps<Props>(), {
  69. examId: 0,
  70. });
  71. /* modal */
  72. const { visible, open, close } = useModal();
  73. defineExpose({ open, close });
  74. const { loading, setLoading } = useLoading();
  75. // 问题卷分类列表
  76. const typeList = ref<IssuePaperTypeItem[]>([]);
  77. // 获取问题卷分类列表
  78. async function getTypeList() {
  79. if (!props.examId) return;
  80. setLoading(true);
  81. try {
  82. const result = await getIssuePaperTypeList(props.examId);
  83. typeList.value = result;
  84. } catch (error) {
  85. console.error('获取问题卷分类列表失败:', error);
  86. ElMessage.error('获取问题卷分类列表失败');
  87. } finally {
  88. setLoading(false);
  89. }
  90. }
  91. // 新增/编辑相关
  92. const curRow = ref({} as IssuePaperTypeItem);
  93. const modifyTypeRef = ref();
  94. function onAdd() {
  95. curRow.value = {} as IssuePaperTypeItem;
  96. modifyTypeRef.value?.open();
  97. }
  98. function onEdit(row: IssuePaperTypeItem) {
  99. curRow.value = row;
  100. modifyTypeRef.value?.open();
  101. }
  102. // 删除
  103. async function onDelete(row: IssuePaperTypeItem) {
  104. const confirm = await modalConfirm(
  105. `确定要删除分类"${row.name}"吗?`,
  106. '删除确认'
  107. ).catch(() => false);
  108. if (!confirm) return;
  109. try {
  110. setLoading(true);
  111. await deleteIssuePaperType(row.id);
  112. ElMessage.success('删除成功');
  113. getTypeList();
  114. } catch (error) {
  115. console.log('删除失败', error);
  116. } finally {
  117. setLoading(false);
  118. }
  119. }
  120. const handleClose = () => {
  121. // 清理数据
  122. };
  123. /* init modal */
  124. function modalBeforeOpen() {
  125. getTypeList();
  126. }
  127. </script>
  128. <style scoped>
  129. .issue-type-content {
  130. min-height: 400px;
  131. }
  132. .action-bar {
  133. margin-bottom: 16px;
  134. display: flex;
  135. justify-content: flex-start;
  136. }
  137. .type-table {
  138. width: 100%;
  139. }
  140. .dialog-footer {
  141. display: flex;
  142. justify-content: flex-end;
  143. }
  144. </style>