Practice-add.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <template>
  2. <el-dialog title="新建练习" v-model="state.dialogVisible" draggable append-to-body destroy-on-close @close="close" width="500px">
  3. <el-form :model="state.ruleForm" ref="ruleFormRef" label-width="80px" v-loading="state.loading">
  4. <el-row :gutter="10">
  5. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  6. <el-form-item label="试题标签" prop="questionTagIds" :rules="[{ required: true, message: '请选择试题标签', trigger: 'change' }]">
  7. <el-tree-select
  8. v-model="state.ruleForm.questionTagIds"
  9. :data="state.tagData"
  10. node-key="id"
  11. :props="{ label: 'name' }"
  12. filterable
  13. multiple
  14. collapse-tags
  15. collapse-tags-tooltip
  16. :max-collapse-tags="2"
  17. :render-after-expand="false"
  18. style="width: 100%"
  19. ref="treeSelectRef"
  20. @change="selQuestionTag"
  21. />
  22. </el-form-item>
  23. </el-col>
  24. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  25. <el-form-item label="出题数量" prop="count" :rules="[{ required: true, message: '请填写出题数量', trigger: 'blur' }]">
  26. <el-input-number v-model="state.ruleForm.count" :min="0" :max="state.totalCount" class="w100" >
  27. <template #suffix>
  28. <span>共{{state.totalCount}}题</span>
  29. </template>
  30. </el-input-number>
  31. </el-form-item>
  32. </el-col>
  33. </el-row>
  34. </el-form>
  35. <template #footer>
  36. <span class="dialog-footer">
  37. <el-button @click="closeDialog" class="default-button">取 消</el-button>
  38. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading">确 定 </el-button>
  39. </span>
  40. </template>
  41. </el-dialog>
  42. </template>
  43. <script setup lang="ts">
  44. import { reactive, ref } from 'vue';
  45. import { ElMessage, FormInstance } from 'element-plus';
  46. import other from '@/utils/other';
  47. import { examTagTreeList } from '@/api/examTrain/tag';
  48. import { addPractice, getTagQuestionCount } from '@/api/examTrain/practice';
  49. // 定义子组件向父组件传值/事件
  50. const emit = defineEmits(['choose']);
  51. // 定义变量内容
  52. const state = reactive<any>({
  53. dialogVisible: false, // 弹窗
  54. ruleForm: {
  55. questionTagIds: [], // 选中的标签id
  56. practiceTagDtos: [], // 试题标签
  57. count: 0, // 出题数量
  58. },
  59. tagData: [], // 试题标签数据
  60. totalCount: 0, // 满足条件试题总数量
  61. loading: false, // 加载
  62. });
  63. // 打开弹窗
  64. const ruleFormRef = ref<any>(); // 表单ref
  65. const openDialog = () => {
  66. state.dialogVisible = true;
  67. getTagData();
  68. };
  69. // 获取标签数据
  70. const getTagData = async () => {
  71. state.loading = true;
  72. try {
  73. const { result } = await examTagTreeList();
  74. state.tagData = result ?? [];
  75. state.loading = false;
  76. } catch (error) {
  77. state.loading = false;
  78. }
  79. };
  80. const close = () => {
  81. ruleFormRef.value?.clearValidate();
  82. ruleFormRef.value?.resetFields();
  83. state.totalCount = 0;
  84. };
  85. // 关闭弹窗
  86. const closeDialog = () => {
  87. state.dialogVisible = false;
  88. state.totalCount = 0;
  89. };
  90. // 选择试题标签
  91. const treeSelectRef = ref<RefType>();
  92. const selQuestionTag = async (value: any) => {
  93. state.ruleForm.practiceTagDtos = [];
  94. state.ruleForm.questionTagIds.forEach(item => {
  95. let tagObj = other.deepClone(treeSelectRef.value.getNode(item).data);
  96. state.ruleForm.practiceTagDtos.push({tagId: tagObj.id});
  97. })
  98. try {
  99. const { result } = await getTagQuestionCount({
  100. tagIds: state.ruleForm.questionTagIds
  101. });
  102. state.totalCount = result.totalCount ?? 0;
  103. if (state.ruleForm.count > state.totalCount){
  104. state.ruleForm.count = 0;
  105. }
  106. } catch (error) {
  107. }
  108. }
  109. // 新增
  110. const onSubmit = async (formEl: FormInstance | undefined) => {
  111. if (!formEl) return;
  112. await formEl.validate((valid: boolean) => {
  113. if (!valid) return;
  114. state.loading = true;
  115. addPractice(state.ruleForm)
  116. .then((res) => {
  117. console.log(res);
  118. emit('choose', res.result);
  119. closeDialog(); // 关闭弹窗
  120. ElMessage.success('操作成功');
  121. state.loading = false;
  122. })
  123. .catch(() => {
  124. state.loading = false;
  125. });
  126. });
  127. };
  128. // 暴露变量
  129. defineExpose({
  130. openDialog,
  131. closeDialog,
  132. });
  133. </script>