index.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <template>
  2. <div class="part-box is-filter">
  3. <a-space class="filter-line" :size="12" wrap>
  4. <SelectSemester
  5. v-model="searchModel.semesterId"
  6. :clearable="false"
  7. select-default
  8. placeholder="请选择"
  9. prefix
  10. @change="semesterChange"
  11. />
  12. <SelectExam
  13. v-model="searchModel.examId"
  14. :semester-id="searchModel.semesterId"
  15. :clearable="false"
  16. select-default
  17. placeholder="请选择"
  18. prefix
  19. @default-selected="toPage(1)"
  20. @change="examChange"
  21. />
  22. <SelectCourse
  23. v-model="searchModel.courseId"
  24. :semester-id="searchModel.semesterId"
  25. :exam-id="searchModel.examId"
  26. placeholder="请选择"
  27. prefix
  28. @change="courseChange"
  29. />
  30. <a-button type="primary" @click="toPage(1)">查询</a-button>
  31. </a-space>
  32. </div>
  33. <div class="part-box">
  34. <a-space class="part-action" :size="6">
  35. <a-button type="text" @click="toBatchDownload">
  36. <template #icon>
  37. <svg-icon name="icon-import" />
  38. </template>
  39. 批量下载
  40. </a-button>
  41. <a-button type="text" @click="toSet">
  42. <template #icon>
  43. <svg-icon name="icon-add" />
  44. </template>
  45. 下载设置
  46. </a-button>
  47. </a-space>
  48. <a-table
  49. class="page-table"
  50. :columns="columns"
  51. :data="dataList"
  52. :pagination="pagination"
  53. :scroll="{ x: 600 }"
  54. :bordered="false"
  55. >
  56. <template #courseCode="{ record }">
  57. {{ courseNameCodeFilter(record) }}
  58. </template>
  59. <template #action="{ record }">
  60. <a-button type="text" class="btn-primary" @click="toDownload(record)"
  61. >下载</a-button
  62. >
  63. </template>
  64. </a-table>
  65. </div>
  66. <!-- ModifySet -->
  67. <ModifySet ref="modifySetRef" />
  68. <TaskProgress ref="taskProgressRef" />
  69. <!-- data loading tips -->
  70. <TaskDetailBuildProgess
  71. ref="taskDetailBuildProgessRef"
  72. :task-id="trackTaskId"
  73. :task-stop="detailBuildStop"
  74. />
  75. </template>
  76. <script setup lang="ts">
  77. import { ref, reactive } from 'vue';
  78. import { Message, TableColumnData } from '@arco-design/web-vue';
  79. import useTable from '@/hooks/table';
  80. import useLoading from '@/hooks/loading';
  81. import { courseNameCodeFilter } from '@/utils/filter';
  82. import { CourseItem, TrackExportItem } from '@/api/types/task';
  83. import { trackExportListPage } from '@/api/task';
  84. import { TrackConfigType } from '@/store/modules/app/types';
  85. import { useAppStore, useUserStore } from '@/store';
  86. import { OptionListItem } from '@/types/global';
  87. import useTask from './useTask';
  88. import TaskDetailBuildProgess from './taskDetailBuildProgess.vue';
  89. import ModifySet from './modifySet.vue';
  90. import TaskProgress from './taskProgress.vue';
  91. defineOptions({
  92. name: 'TrackExport',
  93. });
  94. const appStore = useAppStore();
  95. const userStore = useUserStore();
  96. const searchModel = reactive({
  97. semesterId: '',
  98. examId: '',
  99. courseId: '',
  100. });
  101. const columns: TableColumnData[] = [
  102. {
  103. title: '课程(代码)',
  104. slotName: 'courseCode',
  105. },
  106. {
  107. title: '试卷编号',
  108. dataIndex: 'paperNumber',
  109. },
  110. {
  111. title: '参考人数',
  112. dataIndex: 'studentCount',
  113. width: 100,
  114. },
  115. {
  116. title: '操作',
  117. slotName: 'action',
  118. width: 80,
  119. fixed: 'right',
  120. cellClass: 'action-column',
  121. },
  122. ];
  123. const { dataList, pagination, toPage } = useTable<TrackExportItem>(
  124. trackExportListPage,
  125. searchModel,
  126. false
  127. );
  128. const seNames = {
  129. semesterName: '',
  130. examName: '',
  131. courseName: '',
  132. courseCode: '',
  133. };
  134. function semesterChange(val: OptionListItem) {
  135. seNames.semesterName = val.label;
  136. seNames.examName = '';
  137. seNames.courseName = '';
  138. seNames.courseCode = '';
  139. }
  140. function examChange(val: OptionListItem) {
  141. seNames.examName = val.label;
  142. seNames.courseName = '';
  143. seNames.courseCode = '';
  144. }
  145. function courseChange(val: CourseItem) {
  146. seNames.courseName = val.name;
  147. seNames.courseCode = val.code;
  148. }
  149. // table action
  150. const modifySetRef = ref();
  151. function toSet() {
  152. modifySetRef.value?.open();
  153. }
  154. const {
  155. trackTaskId,
  156. createTrackTask,
  157. updateTrackTaskReady,
  158. getTrackExportDetailList,
  159. getTrackExportList,
  160. } = useTask();
  161. const taskProgressRef = ref();
  162. const taskDetailBuildProgessRef = ref();
  163. const detailBuildStop = ref(false);
  164. function checkTrackConfigExist() {
  165. return Boolean(
  166. appStore.trackConfig.outputDir && appStore.trackConfig.pictureType.length
  167. );
  168. }
  169. // 下载前的检查
  170. async function downloadCheck() {
  171. if (!checkTrackConfigExist()) {
  172. Message.error('请先编辑下载设置');
  173. return false;
  174. }
  175. if (!appStore.trackConfig.outputDirIsDefault) {
  176. const result = await window.electron.dialogSelectFile({
  177. title: '选择保存目录',
  178. properties: ['openDirectory'],
  179. });
  180. if (result.canceled) return false;
  181. appStore.setInfo({
  182. trackConfig: {
  183. ...appStore.trackConfig,
  184. curOutputDir: result.filePaths[0],
  185. },
  186. });
  187. }
  188. return true;
  189. }
  190. const { loading, setLoading } = useLoading();
  191. // 批量下载
  192. async function toBatchDownload() {
  193. detailBuildStop.value = false;
  194. if (loading.value) return;
  195. const res = await downloadCheck();
  196. if (!res) return;
  197. setLoading(true);
  198. let result = true;
  199. await createTrackTask({
  200. ...searchModel,
  201. ...seNames,
  202. paperNumber: null,
  203. schoolId: userStore.curSchoolInfo.id,
  204. pictureType: appStore.trackConfig.pictureType.join(),
  205. outputDir: appStore.trackConfig.curOutputDir,
  206. status: 0,
  207. }).catch(() => {
  208. result = false;
  209. setLoading(false);
  210. });
  211. if (!result) {
  212. Message.error('创建任务错误!');
  213. return;
  214. }
  215. // 构建任务提示
  216. taskDetailBuildProgessRef.value?.open();
  217. // 开始构建任务
  218. let tRes = true;
  219. await getTrackExportList(searchModel).catch((error) => {
  220. console.log(error);
  221. tRes = false;
  222. });
  223. setLoading(false);
  224. if (!tRes) {
  225. detailBuildStop.value = true;
  226. Message.error('创建任务详情错误!');
  227. return;
  228. }
  229. await updateTrackTaskReady();
  230. detailBuildStop.value = true;
  231. // taskProgressRef.value?.open();
  232. }
  233. // 单个课程下载
  234. async function toDownload(row: TrackExportItem) {
  235. detailBuildStop.value = false;
  236. if (loading.value) return;
  237. const res = await downloadCheck();
  238. if (!res) return;
  239. setLoading(true);
  240. let result = true;
  241. await createTrackTask({
  242. ...searchModel,
  243. ...seNames,
  244. courseCode: row.courseCode,
  245. courseName: row.courseName,
  246. paperNumber: row.paperNumber,
  247. schoolId: userStore.curSchoolInfo.id,
  248. pictureType: appStore.trackConfig.pictureType.join(),
  249. outputDir: appStore.trackConfig.curOutputDir,
  250. status: 0,
  251. }).catch(() => {
  252. result = false;
  253. setLoading(false);
  254. });
  255. if (!result) {
  256. Message.error('创建任务错误!');
  257. return;
  258. }
  259. // 构建任务提示
  260. taskDetailBuildProgessRef.value?.open();
  261. // 开始构建任务
  262. let tRes = true;
  263. await getTrackExportDetailList(row).catch((error) => {
  264. console.log(error);
  265. tRes = false;
  266. });
  267. setLoading(false);
  268. if (!tRes) {
  269. Message.error('创建任务详情错误!');
  270. return;
  271. }
  272. await updateTrackTaskReady();
  273. detailBuildStop.value = true;
  274. taskProgressRef.value?.open();
  275. }
  276. async function initData() {
  277. const res = await window.db.getDict('trackConfig');
  278. if (res) {
  279. const trackConfig = JSON.parse(res) as TrackConfigType;
  280. appStore.setInfo({ trackConfig });
  281. }
  282. }
  283. initData();
  284. </script>