sample.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <template>
  2. <base-form
  3. ref="formRef"
  4. :label-width="useVW(88)"
  5. :groups="groups"
  6. :rules="rules"
  7. :items="items"
  8. :model="model"
  9. :disabled="loading"
  10. >
  11. <template #form-item-prefix>
  12. <span class="flex items-center">
  13. <el-input v-model="model.prefix"></el-input>
  14. <span class="m-l-mini">0000000</span>
  15. </span>
  16. </template>
  17. <template #form-item-address>
  18. <span class="flex items-center">
  19. {{ filePath }}
  20. </span>
  21. </template>
  22. <template #form-item-upload>
  23. <div class="flex items-center">
  24. <el-input v-model="fileName" disabled placeholder="导入文件"></el-input>
  25. <el-upload
  26. ref="upload"
  27. v-model:file-list="fileList"
  28. :limit="1"
  29. :show-file-list="false"
  30. :on-exceed="onExceed"
  31. :auto-upload="false"
  32. >
  33. <el-button class="m-l-base" type="primary">浏览</el-button>
  34. </el-upload>
  35. </div>
  36. </template>
  37. <template #form-item-progress>
  38. <el-progress v-show="showProgress" class="flex-1" :percentage="percentage" color="#00BA97" />
  39. </template>
  40. <el-form-item class="m-t-base form-footer">
  41. <el-button type="primary" :loading="loading" @click="onSubmit">确定导入</el-button>
  42. </el-form-item>
  43. </base-form>
  44. </template>
  45. <script setup lang="ts" name="ImportSample">
  46. /** 导入培训卷 */
  47. import { reactive, watch, computed, ref } from 'vue'
  48. import { ElFormItem, ElButton, ElUpload, ElInput, ElMessage, ElProgress } from 'element-plus'
  49. import BaseForm from '@/components/element/BaseForm.vue'
  50. import useFetch from '@/hooks/useFetch'
  51. import useForm from '@/hooks/useForm'
  52. import useOptions from '@/hooks/useOptions'
  53. import useUploadFile from '@/hooks/useUploadFile'
  54. import useVW from '@/hooks/useVW'
  55. import type { FormGroup, EpFormItem, EpFormRules } from 'global-type'
  56. import type { ExtractApiParams } from '@/api/api'
  57. const showProgress = ref(false)
  58. const { fileList, upload, percentage, setPercentage, onExceed, onUploadProgress, reset } = useUploadFile()
  59. const { fetch: getImportFilePath, result: filePath } = useFetch('getImportFilePath')
  60. const { fetch, loading } = useFetch('importSamplePaper', { onUploadProgress })
  61. const model = reactive<ExtractApiParams<'importSamplePaper'>>({
  62. file: void 0,
  63. mainNumber: void 0,
  64. paperType: 'SAMPLE_A',
  65. prefix: '',
  66. separator: '',
  67. subjectCode: '',
  68. })
  69. watch([() => model.subjectCode, () => model.mainNumber, () => model.paperType], () => {
  70. /** 获取导入文件路径 */
  71. model.subjectCode &&
  72. model.mainNumber &&
  73. model.paperType &&
  74. getImportFilePath({
  75. filePathType: model.paperType,
  76. subjectCode: model.subjectCode,
  77. mainNumber: model.mainNumber,
  78. })
  79. })
  80. const { subjectList, mainQuestionList, dataModel, changeModelValue } = useOptions(['subject', 'question'])
  81. watch(dataModel, () => {
  82. model.subjectCode = dataModel.subject || ''
  83. model.mainNumber = dataModel.question
  84. })
  85. const { formRef, elFormRef, defineColumn, _ } = useForm()
  86. const fileName = computed(() => fileList.value?.[0]?.name)
  87. watch(
  88. fileList,
  89. () => {
  90. model.file = fileList.value?.[0]?.raw
  91. },
  92. { deep: true }
  93. )
  94. const rules: EpFormRules = {
  95. subjectCode: [{ required: true, message: '请选择科目' }],
  96. mainNumber: [{ required: true, message: '请选择大题' }],
  97. paperType: [{ required: true, message: '请选择分组代码' }],
  98. prefix: [{ required: true, message: '请设置试卷密码前缀' }],
  99. separator: [{ required: true, message: '请设置分隔符' }],
  100. file: [{ required: true, message: '请选择导入文件' }],
  101. }
  102. const groups: FormGroup[] = [
  103. { groupTitle: '选择大题', rowKeys: ['row-1'] },
  104. { groupTitle: '试卷设置', rowKeys: ['row-2', 'row-3', 'row-4', 'row-5'] },
  105. { groupTitle: '选择文件', rowKeys: ['row-6'] },
  106. ]
  107. const span6 = defineColumn(_, '', { span: 6 })
  108. const items = computed<EpFormItem[]>(() => {
  109. return [
  110. span6({
  111. rowKey: 'row-1',
  112. label: '科目',
  113. prop: 'subjectCode',
  114. slotType: 'select',
  115. slot: { placeholder: '选择科目', options: subjectList.value, onChange: changeModelValue('subject') },
  116. }),
  117. span6({
  118. rowKey: 'row-1',
  119. label: '大题',
  120. labelWidth: useVW(100),
  121. prop: 'mainNumber',
  122. slotType: 'select',
  123. slot: { placeholder: '选择大题', options: mainQuestionList.value, onChange: changeModelValue('question') },
  124. }),
  125. span6({
  126. rowKey: 'row-2',
  127. label: '分组代码',
  128. prop: 'paperType',
  129. slotType: 'select',
  130. slot: {
  131. options: [
  132. { label: 'Sample A', value: 'SAMPLE_A' },
  133. { label: 'Sample B', value: 'SAMPLE_B' },
  134. ],
  135. },
  136. itemDescription: { description: 'Sample A/B卷' },
  137. }),
  138. span6({
  139. rowKey: 'row-3',
  140. label: '试卷密码前缀',
  141. prop: 'prefix',
  142. slotName: 'prefix',
  143. itemDescription: { description: '导用区别正常考生说试卷,导入卷密号为8位,如10000000' },
  144. }),
  145. span6({
  146. rowKey: 'row-4',
  147. label: '分隔符',
  148. prop: 'separator',
  149. slotType: 'input',
  150. itemDescription: { description: '文件格式为:图象文件名|标准分数' },
  151. }),
  152. span6({
  153. rowKey: 'row-5',
  154. label: '图片路径',
  155. slotName: 'address',
  156. itemDescription: { description: '试卷图片请按路径存放' },
  157. }),
  158. span6({
  159. rowKey: 'row-6',
  160. label: '导入文件',
  161. prop: 'file',
  162. slotName: 'upload',
  163. }),
  164. span6({
  165. rowKey: 'row-7',
  166. slotName: 'progress',
  167. }),
  168. ]
  169. })
  170. async function onSubmit() {
  171. try {
  172. const valid = await elFormRef?.value?.validate()
  173. if (valid) {
  174. showProgress.value = true
  175. setPercentage(0)
  176. await fetch(model)
  177. setPercentage(100)
  178. ElMessage.success(`导入成功`)
  179. elFormRef?.value?.resetFields()
  180. reset()
  181. }
  182. } catch (error) {
  183. showProgress.value = false
  184. setPercentage(0)
  185. console.error(error)
  186. }
  187. }
  188. </script>
  189. <style scoped lang="scss"></style>