ModifyPaperStructure.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <template>
  2. <el-dialog
  3. v-model="visible"
  4. :title="title"
  5. width="600px"
  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. <el-form
  14. ref="formRef"
  15. :model="formModel"
  16. :rules="formRules"
  17. label-width="100px"
  18. >
  19. <el-form-item label="试卷类型" prop="paperType">
  20. <el-select
  21. v-model="formModel.paperType"
  22. placeholder="请选择试卷类型"
  23. style="width: 100%"
  24. >
  25. <el-option label="A" value="A" />
  26. <el-option label="B" value="B" />
  27. </el-select>
  28. </el-form-item>
  29. <el-form-item label="大题名称" prop="bigQuestionName">
  30. <el-input
  31. v-model="formModel.bigQuestionName"
  32. placeholder="请输入大题名称"
  33. maxlength="50"
  34. />
  35. </el-form-item>
  36. <el-form-item label="大题昵称" prop="bigQuestionNickname">
  37. <el-input
  38. v-model="formModel.bigQuestionNickname"
  39. placeholder="请输入大题昵称"
  40. maxlength="50"
  41. />
  42. </el-form-item>
  43. <el-form-item label="大题号" prop="bigQuestionNo">
  44. <el-input-number
  45. v-model="formModel.bigQuestionNo"
  46. :min="1"
  47. :max="99"
  48. placeholder="请输入大题号"
  49. style="width: 100%"
  50. />
  51. </el-form-item>
  52. <el-form-item label="小题号" prop="smallQuestionNo">
  53. <el-input-number
  54. v-model="formModel.smallQuestionNo"
  55. :min="1"
  56. :max="999"
  57. placeholder="请输入小题号"
  58. style="width: 100%"
  59. />
  60. </el-form-item>
  61. <el-form-item label="满分" prop="fullScore">
  62. <el-input-number
  63. v-model="formModel.fullScore"
  64. :min="0"
  65. :max="999"
  66. :precision="1"
  67. placeholder="请输入满分"
  68. style="width: 100%"
  69. />
  70. </el-form-item>
  71. <el-form-item label="给分次数" prop="giveScoreCount">
  72. <el-input-number
  73. v-model="formModel.giveScoreCount"
  74. :min="1"
  75. :max="10"
  76. placeholder="请输入给分次数"
  77. style="width: 100%"
  78. />
  79. </el-form-item>
  80. <el-form-item label="是否客观题">
  81. <el-checkbox v-model="formModel.isObjective">客观题</el-checkbox>
  82. </el-form-item>
  83. <el-form-item label="间隔分" prop="intervalScore">
  84. <el-input-number
  85. v-model="formModel.intervalScore"
  86. :min="0"
  87. :max="10"
  88. :precision="1"
  89. placeholder="请输入间隔分"
  90. style="width: 100%"
  91. />
  92. </el-form-item>
  93. <el-form-item label="题型" prop="questionType">
  94. <el-select
  95. v-model="formModel.questionType"
  96. placeholder="请选择题型"
  97. style="width: 100%"
  98. >
  99. <el-option label="单选" value="单选" />
  100. <el-option label="多选" value="多选" />
  101. <el-option label="填空" value="填空" />
  102. <el-option label="简答" value="简答" />
  103. <el-option label="计算" value="计算" />
  104. <el-option label="作文" value="作文" />
  105. </el-select>
  106. </el-form-item>
  107. <el-form-item label="答案" prop="answer">
  108. <el-input
  109. v-model="formModel.answer"
  110. placeholder="请输入答案"
  111. maxlength="200"
  112. />
  113. </el-form-item>
  114. <el-form-item label="判分策略" prop="scoringStrategy">
  115. <el-select
  116. v-model="formModel.scoringStrategy"
  117. placeholder="请选择判分策略"
  118. style="width: 100%"
  119. >
  120. <el-option label="无" value="无" />
  121. <el-option label="全对全错" value="全对全错" />
  122. <el-option label="按步给分" value="按步给分" />
  123. </el-select>
  124. </el-form-item>
  125. <el-form-item label="分组" prop="grouping">
  126. <el-input
  127. v-model="formModel.grouping"
  128. placeholder="请输入分组信息(可选)"
  129. maxlength="10"
  130. />
  131. </el-form-item>
  132. </el-form>
  133. <template #footer>
  134. <div class="dialog-footer">
  135. <el-button @click="onClose">取消</el-button>
  136. <el-button type="primary" :loading="loading" @click="confirm">
  137. 确定
  138. </el-button>
  139. </div>
  140. </template>
  141. </el-dialog>
  142. </template>
  143. <script setup lang="ts">
  144. import { reactive, ref, computed } from 'vue';
  145. import { ElMessage } from 'element-plus';
  146. import type { FormInstance, FormRules } from 'element-plus';
  147. import { savePaperStructure } from '@/api/subject';
  148. import type {
  149. PaperStructureItem,
  150. PaperStructureUpdateParams,
  151. } from '@/api/types/subject';
  152. import useModal from '@/hooks/modal';
  153. import useLoading from '@/hooks/loading';
  154. import { objAssign, objModifyAssign } from '@/utils/utils';
  155. defineOptions({
  156. name: 'ModifyPaperStructure',
  157. });
  158. /* modal */
  159. const { visible, open, close } = useModal();
  160. defineExpose({ open, close });
  161. interface Props {
  162. rowData: PaperStructureItem;
  163. subjectId: number;
  164. }
  165. const props = withDefaults(defineProps<Props>(), {
  166. rowData: () => ({} as PaperStructureItem),
  167. subjectId: 0,
  168. });
  169. const emit = defineEmits(['modified']);
  170. const isEdit = computed(() => !!props.rowData.id);
  171. const title = computed(() => `${isEdit.value ? '编辑' : '新增'}试卷结构`);
  172. const formRef = ref<FormInstance>();
  173. const initialFormState: PaperStructureUpdateParams = {
  174. paperType: '',
  175. bigQuestionName: '',
  176. bigQuestionNickname: '',
  177. bigQuestionNo: 1,
  178. smallQuestionNo: 1,
  179. fullScore: 0,
  180. giveScoreCount: 1,
  181. isObjective: false,
  182. intervalScore: 0.5,
  183. questionType: '',
  184. answer: '',
  185. scoringStrategy: '无',
  186. grouping: '',
  187. };
  188. const formModel = reactive<PaperStructureUpdateParams>({
  189. ...initialFormState,
  190. });
  191. const formRules: FormRules<keyof PaperStructureUpdateParams> = {
  192. paperType: [
  193. { required: true, message: '请选择试卷类型', trigger: 'change' },
  194. ],
  195. bigQuestionName: [
  196. { required: true, message: '请输入大题名称', trigger: 'blur' },
  197. { max: 50, message: '大题名称不能超过50个字符', trigger: 'blur' },
  198. ],
  199. bigQuestionNickname: [
  200. { max: 50, message: '大题昵称不能超过50个字符', trigger: 'blur' },
  201. ],
  202. bigQuestionNo: [
  203. { required: true, message: '请输入大题号', trigger: 'blur' },
  204. ],
  205. smallQuestionNo: [
  206. { required: true, message: '请输入小题号', trigger: 'blur' },
  207. ],
  208. fullScore: [{ required: true, message: '请输入满分', trigger: 'blur' }],
  209. giveScoreCount: [
  210. { required: true, message: '请输入给分次数', trigger: 'blur' },
  211. ],
  212. intervalScore: [
  213. { required: true, message: '请输入间隔分', trigger: 'blur' },
  214. ],
  215. questionType: [
  216. { required: true, message: '请选择题型', trigger: 'change' },
  217. ],
  218. answer: [{ max: 200, message: '答案不能超过200个字符', trigger: 'blur' }],
  219. scoringStrategy: [
  220. { required: true, message: '请选择判分策略', trigger: 'change' },
  221. ],
  222. grouping: [
  223. { max: 10, message: '分组信息不能超过10个字符', trigger: 'blur' },
  224. ],
  225. };
  226. const handleClose = () => {
  227. formRef.value?.resetFields();
  228. };
  229. const { loading, setLoading } = useLoading();
  230. const confirm = async () => {
  231. const valid = await formRef.value?.validate().catch(() => false);
  232. if (!valid) return;
  233. setLoading(true);
  234. const datas = objAssign(formModel, {});
  235. if (isEdit.value) {
  236. datas.id = props.rowData.id;
  237. }
  238. let res = true;
  239. await savePaperStructure(datas).catch(() => {
  240. res = false;
  241. });
  242. setLoading(false);
  243. if (!res) return;
  244. ElMessage.success(`${title.value}成功!`);
  245. emit('modified', datas);
  246. close();
  247. };
  248. /* init modal */
  249. function modalBeforeOpen() {
  250. if (props.rowData.id) {
  251. objModifyAssign(formModel, props.rowData);
  252. } else {
  253. objModifyAssign(formModel, initialFormState);
  254. }
  255. }
  256. </script>