BusinessDataExport.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. <template>
  2. <div class="business-data-export">
  3. <div class="part-box part-box-filter">
  4. <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
  5. <template v-if="checkPrivilege('condition', 'condition')">
  6. <el-form-item label="学期:">
  7. <semester-select
  8. v-model.trim="filter.semesterId"
  9. placeholder="学期"
  10. default-select
  11. ></semester-select>
  12. </el-form-item>
  13. <el-form-item label="考试:">
  14. <exam-select
  15. v-model="filter.examId"
  16. :semester-id="filter.semesterId"
  17. default-select
  18. @default-selected="search"
  19. ></exam-select>
  20. </el-form-item>
  21. <el-form-item label="印刷计划:">
  22. <print-plan-select
  23. v-model.trim="filter.printPlanIdList"
  24. placeholder="印刷计划"
  25. clearable
  26. multiple
  27. :semester-id="filter.semesterId"
  28. :exam-id="filter.examId"
  29. @change="printPlanChange"
  30. ></print-plan-select>
  31. </el-form-item>
  32. <el-form-item label="课程(代码):" label-width="110px">
  33. <course-select
  34. v-model.trim="filter.courseId"
  35. :semester-id="filter.semesterId"
  36. :exam-id="filter.examId"
  37. :print-plan-id="filter.printPlanIdList"
  38. placeholder="课程(代码)"
  39. clearable
  40. ></course-select>
  41. </el-form-item>
  42. <el-form-item label="试卷编号:">
  43. <paper-number-select
  44. ref="PaperNumberSelect"
  45. v-model="filter.paperNumber"
  46. :semester-id="filter.semesterId"
  47. :exam-id="filter.examId"
  48. :print-plan-id="filter.printPlanIdList"
  49. :course-id="filter.courseId"
  50. placeholder="试卷编号"
  51. clearable
  52. ></paper-number-select>
  53. </el-form-item>
  54. <el-form-item label="考点:" label-width="55px">
  55. <place-select
  56. v-model.trim="filter.examPlace"
  57. :print-plan-id="filter.printPlanIdList"
  58. placeholder="考点"
  59. clearable
  60. ></place-select>
  61. </el-form-item>
  62. <el-form-item label="考场:" label-width="55px">
  63. <room-select
  64. v-model.trim="filter.examRoom"
  65. :print-plan-id="filter.printPlanIdList"
  66. placeholder="考场"
  67. clearable
  68. ></room-select>
  69. </el-form-item>
  70. <el-form-item label="卷袋号:" label-width="70px">
  71. <el-input
  72. v-model="filter.packageCode"
  73. placeholder="卷袋号"
  74. clearable
  75. ></el-input>
  76. </el-form-item>
  77. <el-form-item label="考试日期:">
  78. <el-date-picker
  79. v-model="createTime"
  80. type="daterange"
  81. :picker-options="pickerOptions"
  82. range-separator="至"
  83. start-placeholder="考试开始日期"
  84. end-placeholder="考试结束日期"
  85. value-format="timestamp"
  86. align="right"
  87. unlink-panels
  88. >
  89. </el-date-picker>
  90. </el-form-item>
  91. </template>
  92. <el-form-item label-width="0px">
  93. <el-button
  94. v-if="checkPrivilege('button', 'select')"
  95. type="primary"
  96. @click="search"
  97. >查询</el-button
  98. >
  99. </el-form-item>
  100. </el-form>
  101. <div class="box-justify">
  102. <div>
  103. <el-button
  104. v-if="checkPrivilege('button', 'export')"
  105. icon="el-icon-download"
  106. type="primary"
  107. :loading="loading"
  108. @click="toExport"
  109. >
  110. 导出
  111. </el-button>
  112. <el-button
  113. v-if="checkPrivilege('button', 'export')"
  114. type="primary"
  115. icon="el-icon-s-order"
  116. @click="toDataTask('EXAMINATION_EXPORT')"
  117. >导出结果查询</el-button
  118. >
  119. </div>
  120. <div>
  121. <el-button
  122. v-if="checkPrivilege('button', 'import')"
  123. type="success"
  124. icon="el-icon-upload2"
  125. @click="toImport"
  126. >导入考务数据</el-button
  127. >
  128. <el-button
  129. v-if="checkPrivilege('button', 'import')"
  130. type="primary"
  131. icon="el-icon-s-order"
  132. @click="toDataTask('EXAMINATION_IMPORT')"
  133. >导入结果查询</el-button
  134. >
  135. </div>
  136. </div>
  137. </div>
  138. <div class="part-box part-box-pad">
  139. <el-table class="mb-2" ref="TableList" :data="dataList">
  140. <el-table-column
  141. type="index"
  142. label="序号"
  143. width="70"
  144. :index="indexMethod"
  145. ></el-table-column>
  146. <!-- <el-table-column
  147. prop="semesterName"
  148. label="学期"
  149. min-width="210"
  150. ></el-table-column>
  151. <el-table-column
  152. prop="examName"
  153. label="考试"
  154. min-width="160"
  155. ></el-table-column> -->
  156. <el-table-column
  157. prop="printPlanName"
  158. label="印刷计划"
  159. min-width="200"
  160. ></el-table-column>
  161. <el-table-column
  162. prop="courseNameCode"
  163. label="课程(代码)"
  164. min-width="200"
  165. >
  166. </el-table-column>
  167. <el-table-column
  168. prop="paperNumber"
  169. label="试卷编号"
  170. min-width="160"
  171. ></el-table-column>
  172. <el-table-column prop="examDate" label="考试日期" width="100">
  173. </el-table-column>
  174. <el-table-column prop="examTime" label="考试时间" width="100">
  175. </el-table-column>
  176. <el-table-column prop="packageCode" label="卷袋号" min-width="160">
  177. </el-table-column>
  178. <el-table-column prop="examPlace" label="考点" min-width="100">
  179. </el-table-column>
  180. <el-table-column prop="examRoom" label="考场" min-width="100">
  181. </el-table-column>
  182. <el-table-column prop="totalSubjects" label="科次" width="60">
  183. </el-table-column>
  184. <el-table-column
  185. class-name="action-column"
  186. label="操作"
  187. width="100"
  188. fixed="right"
  189. >
  190. <template slot-scope="scope">
  191. <el-button
  192. v-if="checkPrivilege('link', 'preview')"
  193. class="btn-primary"
  194. type="text"
  195. @click="toPreview(scope.row)"
  196. >预览</el-button
  197. >
  198. <el-button
  199. v-if="checkPrivilege('link', 'delete')"
  200. class="btn-danger"
  201. type="text"
  202. @click="toDelete(scope.row)"
  203. >删除</el-button
  204. >
  205. </template>
  206. </el-table-column>
  207. </el-table>
  208. <div class="box-justify">
  209. <div>
  210. <span class="mr-2"
  211. >科次总计:<i class="color-primary">{{
  212. totalData.totalSubjects
  213. }}</i>
  214. 科次</span
  215. >
  216. <span
  217. >卷袋数量总计:<i class="color-primary">{{
  218. totalData.packageCount
  219. }}</i>
  220. 个</span
  221. >
  222. </div>
  223. <el-pagination
  224. background
  225. layout="total, sizes, prev, pager, next, jumper"
  226. :pager-count="5"
  227. :current-page="current"
  228. :total="total"
  229. :page-size="size"
  230. @current-change="toPage"
  231. @size-change="pageSizeChange"
  232. >
  233. </el-pagination>
  234. </div>
  235. </div>
  236. <!-- PreviewBusinessDetail -->
  237. <preview-business-detail
  238. ref="PreviewBusinessDetail"
  239. :instance="curRow"
  240. ></preview-business-detail>
  241. <!-- ImportFile -->
  242. <import-file
  243. v-if="checkPrivilege('button', 'import')"
  244. ref="ImportFile"
  245. title="导入考务数据"
  246. :upload-url="uploadUrl"
  247. :upload-data="uploadData"
  248. :format="['xls', 'xlsx']"
  249. :auto-upload="false"
  250. :before-submit-handle="submitImport"
  251. @upload-success="uploadSuccess"
  252. >
  253. <el-form
  254. ref="modalFormComp"
  255. :model="modalForm"
  256. :rules="rules"
  257. label-width="90px"
  258. >
  259. <el-form-item label="模板下载:">
  260. <el-button type="text" :loading="loading" @click="toDownloadTemplate">
  261. <span class="cont-link">
  262. {{ dfilename }}
  263. </span>
  264. </el-button>
  265. </el-form-item>
  266. <el-form-item prop="printPlanId" label="印刷计划:">
  267. <el-select
  268. v-model="modalForm.printPlanId"
  269. placeholder="请选择"
  270. filterable
  271. :disabled="loading"
  272. style="width: 100%"
  273. >
  274. <el-option
  275. v-for="item in plans"
  276. :key="item.id"
  277. :value="item.id"
  278. :label="item.name"
  279. >
  280. </el-option>
  281. </el-select>
  282. </el-form-item>
  283. </el-form>
  284. </import-file>
  285. <!-- data-task-dialog -->
  286. <data-task-dialog
  287. v-if="
  288. checkPrivilege('button', 'import') || checkPrivilege('button', 'export')
  289. "
  290. ref="DataTaskDialog"
  291. :task-type="taskType"
  292. ></data-task-dialog>
  293. </div>
  294. </template>
  295. <script>
  296. import {
  297. businessDataListPage,
  298. businessTotalData,
  299. businessTemplateDownload,
  300. businessDataExport,
  301. printPlanQuery,
  302. deleteBusinessData,
  303. } from "../api";
  304. import PreviewBusinessDetail from "../components/PreviewBusinessDetail.vue";
  305. import ImportFile from "../../../components/ImportFile.vue";
  306. import { parseTimeRangeDateAndTime } from "@/plugins/utils";
  307. import { downloadByApi } from "@/plugins/download";
  308. import pickerOptions from "@/constants/datePickerOptions";
  309. export default {
  310. name: "business-data-export",
  311. components: { PreviewBusinessDetail, ImportFile },
  312. data() {
  313. return {
  314. filter: {
  315. semesterId: "",
  316. examId: "",
  317. printPlanIdList: "",
  318. courseId: "",
  319. paperNumber: "",
  320. examPlace: "",
  321. examRoom: "",
  322. packageCode: "",
  323. startDate: "",
  324. endDate: "",
  325. },
  326. current: 1,
  327. size: this.GLOBAL.pageSize,
  328. total: 0,
  329. dataList: [],
  330. curRow: {},
  331. totalData: {},
  332. loading: false,
  333. // date-picker
  334. createTime: [],
  335. pickerOptions,
  336. // import
  337. plans: [],
  338. modalForm: { type: "FILE", printPlanId: "" },
  339. rules: {
  340. printPlanId: [
  341. {
  342. required: true,
  343. message: "请选择印刷计划",
  344. trigger: "change",
  345. },
  346. ],
  347. },
  348. taskType: "",
  349. uploadUrl: "/api/admin/exam/print/data_import",
  350. dfilename: "考务数据模板.xlsx",
  351. uploadData: {},
  352. };
  353. },
  354. mounted() {
  355. // this.search();
  356. this.getPlans();
  357. },
  358. methods: {
  359. async getList() {
  360. if (!this.checkPrivilege("list", "list")) return;
  361. const datas = {
  362. ...this.filter,
  363. pageNumber: this.current,
  364. pageSize: this.size,
  365. };
  366. if (this.createTime) {
  367. datas.startDate = this.createTime[0];
  368. datas.endDate = this.createTime[1];
  369. }
  370. const data = await businessDataListPage(datas);
  371. this.dataList = data.records.map((item) => {
  372. const { date, time } = parseTimeRangeDateAndTime(
  373. item.examStartTime,
  374. item.examEndTime
  375. );
  376. item.examDate = date || "--";
  377. item.examTime = time || "--";
  378. return item;
  379. });
  380. this.total = data.total;
  381. },
  382. async getTotalData() {
  383. const datas = {
  384. ...this.filter,
  385. };
  386. if (this.createTime) {
  387. datas.startDate = this.createTime[0];
  388. datas.endDate = this.createTime[1];
  389. }
  390. this.totalData = await businessTotalData(datas);
  391. },
  392. toPage(page) {
  393. this.current = page;
  394. this.getList();
  395. },
  396. search() {
  397. this.toPage(1);
  398. this.getTotalData();
  399. },
  400. printPlanChange() {
  401. this.filter.examRoom = "";
  402. this.filter.examPlace = "";
  403. },
  404. async toExport() {
  405. // 异步导出
  406. if (this.loading) return;
  407. this.loading = true;
  408. const datas = {
  409. ...this.filter,
  410. };
  411. if (this.createTime) {
  412. datas.startDate = this.createTime[0];
  413. datas.endDate = this.createTime[1];
  414. }
  415. const res = await businessDataExport(datas).catch(() => {});
  416. this.loading = false;
  417. if (res) {
  418. this.$message.success("导出任务已提交!");
  419. } else {
  420. this.$message.error("导出任务提交失败,请重新尝试!");
  421. }
  422. },
  423. async toDownloadTemplate() {
  424. if (this.loading) return;
  425. this.loading = true;
  426. const res = await downloadByApi(() => {
  427. return businessTemplateDownload();
  428. }, `考务数据模板.xlsx`).catch((e) => {
  429. this.$message.error(e || "下载失败,请重新尝试!");
  430. });
  431. this.loading = false;
  432. if (!res) return;
  433. this.$message.success("下载成功!");
  434. },
  435. toPreview(row) {
  436. this.curRow = { ...row };
  437. this.$refs.PreviewBusinessDetail.open();
  438. },
  439. async toDelete(row) {
  440. const result = await this.$confirm(`确定要删除吗?`, "提示", {
  441. type: "warning",
  442. }).catch(() => {});
  443. if (result !== "confirm") return;
  444. await deleteBusinessData(row.id);
  445. this.$message.success("操作成功!");
  446. this.deletePageLastItem();
  447. },
  448. // import
  449. async getPlans() {
  450. const res = await printPlanQuery();
  451. this.plans = res.filter((item) => ["NEW", "READY"].includes(item.status));
  452. },
  453. toImport() {
  454. this.$refs.ImportFile.open();
  455. },
  456. toDataTask(taskType) {
  457. this.taskType = taskType;
  458. this.$refs.DataTaskDialog.open();
  459. },
  460. async submitImport() {
  461. this.uploadData = { ...this.modalForm };
  462. return this.$refs.modalFormComp.validate();
  463. },
  464. validError(errorData) {
  465. this.$message.error(errorData.message);
  466. },
  467. uploadSuccess() {
  468. this.$message.success("文件上传成功,后台正在导入!");
  469. this.getList();
  470. },
  471. },
  472. };
  473. </script>