newRegister.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. <template>
  2. <div id="newRegister">
  3. <div style="margin-bottom: 12px">
  4. <span style="font-size: 14px">第一步:</span>
  5. <el-select
  6. :style="marSty"
  7. :size="size"
  8. filterable
  9. v-model="formData.applyId"
  10. placeholder="请选择考试计划(必填)"
  11. >
  12. <el-option
  13. v-for="item in examList"
  14. :key="item.applyId"
  15. :label="item.applyName"
  16. :value="item.applyId"
  17. >
  18. </el-option>
  19. </el-select>
  20. <el-select
  21. :style="marSty"
  22. :size="size"
  23. filterable
  24. v-model="formData.applySiteAddress"
  25. placeholder="请选择考试地点(必填)"
  26. >
  27. <el-option
  28. v-for="item in applySiteAddress"
  29. :key="item.siteId"
  30. :label="item.siteAddress"
  31. :value="item.siteAddress"
  32. >
  33. </el-option>
  34. </el-select>
  35. <el-button :size="size" type="info" @click="advanced">选择学员</el-button>
  36. <el-input
  37. v-if="formData.idCards"
  38. type="textarea"
  39. :size="size"
  40. readonly
  41. :rows="1"
  42. style="width: 180px; vertical-align: top; margin: 0px 10px"
  43. placeholder="请点击选择学员按钮上传学员名单"
  44. v-model="formData.idCards"
  45. >
  46. </el-input>
  47. <el-button :size="size" type="warning" @click="downModel"
  48. >下载模板</el-button
  49. >
  50. </div>
  51. <div style="margin-bottom: 12px">
  52. <span style="font-size: 14px">第二步:</span>
  53. <label
  54. for="mobles4"
  55. class="el-button el-button--success el-button--mini"
  56. style="margin-right: 10px"
  57. >批量导入</label
  58. ><input
  59. style="display: none"
  60. type="file"
  61. id="mobles4"
  62. ref="input4"
  63. @change="importMobleadd"
  64. />
  65. </div>
  66. <div>
  67. <el-badge
  68. :hidden="!tableDataSuccess.length"
  69. :value="tableDataSuccess.length"
  70. class="item"
  71. >
  72. <el-button
  73. :size="size"
  74. :type="active === 1 ? 'primary' : ''"
  75. @click="active = 1"
  76. >成功导入</el-button
  77. >
  78. </el-badge>
  79. <el-badge
  80. :hidden="!tableDataError.length"
  81. :value="tableDataError.length"
  82. class="item"
  83. >
  84. <el-button
  85. :size="size"
  86. :type="active === 2 ? 'primary' : ''"
  87. @click="active = 2"
  88. >失败导入</el-button
  89. >
  90. </el-badge>
  91. </div>
  92. <div v-show="active === 1" class="exportBox">
  93. <h4 class="h4Sty">
  94. 成功导入<strong style="color: red">{{ tableDataSuccess.length }}</strong
  95. >人
  96. </h4>
  97. <el-table
  98. max-height="600"
  99. :data="tableDataSuccess"
  100. style="width: 100%"
  101. border
  102. :header-cell-style="{
  103. 'background-color': '#eee',
  104. color: '#333',
  105. fontSize: '14px',
  106. }"
  107. >
  108. <af-table-column
  109. v-for="(item, index) in computedForm(tableSet, 1)"
  110. :key="index"
  111. :prop="item.prop"
  112. :label="item.label"
  113. :width="item.width"
  114. align="center"
  115. >
  116. <template slot-scope="scope">
  117. <div v-if="item.scope === 'time'">
  118. <div>{{ scope.row[item.prop1] }}</div>
  119. <div>{{ scope.row[item.prop2] }} {{ scope.row[item.prop3] }}</div>
  120. </div>
  121. <div v-else-if="item.scope === 'StudentType'">
  122. {{
  123. scope.row[item.prop] == 1
  124. ? "非补考学员"
  125. : scope.row[item.prop] == 2
  126. ? "补考学员"
  127. : ""
  128. }}
  129. </div>
  130. <span v-else>{{ scope.row[item.prop] }}</span>
  131. </template>
  132. </af-table-column>
  133. </el-table>
  134. </div>
  135. <div v-show="active === 2" class="exportBox">
  136. <h4 class="h4Sty">
  137. 失败导入<strong style="color: red">{{ tableDataError.length }}</strong
  138. >人
  139. <el-button
  140. v-if="tableDataError.length"
  141. style="margin-left: 10px"
  142. :size="size"
  143. type="success"
  144. @click="dowmErrorData"
  145. >下载失败数据</el-button
  146. >
  147. </h4>
  148. <el-table
  149. max-height="600"
  150. :data="tableDataError"
  151. style="width: 100%"
  152. border
  153. :header-cell-style="{
  154. 'background-color': '#eee',
  155. color: '#333',
  156. fontSize: '14px',
  157. }"
  158. >
  159. <af-table-column
  160. v-for="(item, index) in computedForm(tableSet, 2)"
  161. :key="index"
  162. :prop="item.prop"
  163. :label="item.label"
  164. :width="item.width"
  165. align="center"
  166. >
  167. <template slot-scope="scope">
  168. <span v-if="item.scope === 'time'">
  169. {{ changeDatas(scope.row[item.prop]) }}
  170. </span>
  171. <div v-else-if="item.scope === 'StudentType'">
  172. {{
  173. scope.row[item.prop] == 1
  174. ? "非补考学员"
  175. : scope.row[item.prop] == 2
  176. ? "补考学员"
  177. : ""
  178. }}
  179. </div>
  180. <span v-else>{{ scope.row[item.prop] }}</span>
  181. </template>
  182. </af-table-column>
  183. </el-table>
  184. </div>
  185. <el-dialog
  186. :visible.sync="dialogPLS"
  187. width="660px"
  188. :show-close="false"
  189. :close-on-click-modal="false"
  190. >
  191. <div slot="title" class="hearders">
  192. <div class="leftTitle">高级输入</div>
  193. <div class="rightBoxs">
  194. <img
  195. src="@/assets/images/Close@2x.png"
  196. alt=""
  197. @click="dialogPLS = false"
  198. />
  199. </div>
  200. </div>
  201. <el-row :gutter="20">
  202. <el-col :span="12"
  203. ><h4>请输入学员的身份证号码,换行隔开,每行一个</h4>
  204. <el-input
  205. type="textarea"
  206. :rows="10"
  207. placeholder="请输入身份证"
  208. v-model="idcordList"
  209. >
  210. </el-input>
  211. </el-col>
  212. <el-col :span="12">
  213. <h4>快捷导入</h4>
  214. <el-link type="primary" @click="getDowm">下载模板</el-link>
  215. <label
  216. for="mobles3"
  217. class="el-button el-button--primary"
  218. style="margin-left: 14px; padding: 10px 20px"
  219. >上传学员名单</label
  220. ><input
  221. style="display: none"
  222. type="file"
  223. id="mobles3"
  224. ref="input1"
  225. @change="importMobleadds"
  226. />
  227. </el-col>
  228. </el-row>
  229. <span slot="footer" class="dialog-footer">
  230. <el-button @click="dialogPLS = false">取消</el-button>
  231. <el-button type="primary" @click="submitChecksPals">确定</el-button>
  232. </span>
  233. </el-dialog>
  234. </div>
  235. </template>
  236. <script>
  237. import * as baseUrls from "@/utils/request.js";
  238. import { mapGetters } from "vuex";
  239. export default {
  240. data() {
  241. return {
  242. dialogPLS: false,
  243. active: 1,
  244. marSty: { marginRight: "10px" },
  245. size: "mini",
  246. formData: {
  247. applyId: "",
  248. applySiteAddress: "",
  249. idCards: "",
  250. },
  251. idcordList: "",
  252. tableDataSuccess: [],
  253. tableDataError: [],
  254. tableSet: [
  255. {
  256. label: "学员姓名",
  257. prop: "userName",
  258. },
  259. {
  260. label: "学员身份证",
  261. prop: "idCard",
  262. },
  263. {
  264. label: "学员报名类型",
  265. prop: "studentTypeName",
  266. scope: "StudentType",
  267. },
  268. {
  269. label: "考试标题",
  270. prop: "applyName",
  271. },
  272. {
  273. label: "考试地点",
  274. prop: "applySiteAddress",
  275. },
  276. {
  277. label: "考试日期",
  278. prop: "applySiteExamTime",
  279. // scope: "time",
  280. },
  281. {
  282. label: "考试时间段",
  283. prop: "applySiteTime",
  284. },
  285. {
  286. label: "商品编码",
  287. prop: "code",
  288. },
  289. {
  290. label: "商品标题",
  291. prop: "goodsName",
  292. },
  293. {
  294. label: "预约登记",
  295. prop: "subscribeStatus",
  296. },
  297. {
  298. label: "考试登记",
  299. prop: "examStatus",
  300. },
  301. {
  302. label: "考试成绩",
  303. prop: "performance",
  304. },
  305. {
  306. label: "考试结果",
  307. prop: "result",
  308. },
  309. {
  310. label: "证书编号",
  311. prop: "certificateCode",
  312. },
  313. {
  314. label: "出错原因",
  315. prop: "cause",
  316. hidden: true,
  317. width: "260px",
  318. },
  319. ],
  320. };
  321. },
  322. computed: {
  323. ...mapGetters(["examList", "applySiteAddress"]),
  324. computedForm: function () {
  325. return function (tabs, int) {
  326. if (int === 1) {
  327. const ayst = tabs.filter((item) => {
  328. return !item.hidden;
  329. });
  330. return ayst;
  331. } else {
  332. return tabs;
  333. }
  334. };
  335. },
  336. },
  337. methods: {
  338. /**
  339. * 转换时间格式
  340. */
  341. changeDatas(time) {
  342. if (time) {
  343. var datas = this.$methodsTools.onlyForma(
  344. new Date(time).getTime() / 1000,
  345. false
  346. );
  347. return datas;
  348. } else {
  349. return "";
  350. }
  351. },
  352. importMobleadd(e) {
  353. var file = e.target.files[0];
  354. let formData = new FormData();
  355. formData.append("file", file);
  356. this.$api
  357. .editsystemimportUpdateData(formData)
  358. .then((res) => {
  359. this.tableDataSuccess = res.data.successList;
  360. this.tableDataError = res.data.errorList;
  361. this.$message.info("导入操作执行成功");
  362. })
  363. .finally(() => {
  364. e.target.value = "";
  365. });
  366. },
  367. advanced() {
  368. this.dialogPLS = true;
  369. this.idcordList = this.formData.idCards;
  370. },
  371. submitChecksPals() {
  372. this.formData.idCards = this.idcordList;
  373. this.dialogPLS = false;
  374. },
  375. /**
  376. * 窗口下载模板
  377. */
  378. getDowm() {
  379. let url = baseUrls.BASE_IMG_URL + "/oss/images/file/20220214.xls";
  380. let link = document.createElement("a");
  381. let fileName = "导入模板" + ".xlsx";
  382. document.body.appendChild(link);
  383. link.href = url;
  384. link.dowmload = fileName;
  385. link.click();
  386. link.remove();
  387. },
  388. /**
  389. * 导入
  390. */
  391. importMobleadds(e) {
  392. var self = this;
  393. var file = e.target.files[0];
  394. let formData = new FormData();
  395. formData.append("file", file);
  396. this.$api
  397. .inquiresystemsubscribeimportIdsDataFilter(formData)
  398. .then((res) => {
  399. if (!res.data.length) {
  400. this.$message.warning("未检测到上传学员数据,请检查上传文件");
  401. return;
  402. }
  403. let idList = res.data.map((item) => {
  404. return item.idCard.toString();
  405. });
  406. if (this.idcordList) {
  407. var arr = this.idcordList.split("\n");
  408. var arrs = arr.concat(idList);
  409. var newArr = arrs.filter(function (value, index, self) {
  410. return self.indexOf(value) === index;
  411. });
  412. this.idcordList = newArr.join("\n");
  413. } else {
  414. var newArr = idList.filter(function (value, index, self) {
  415. return self.indexOf(value) === index;
  416. });
  417. this.idcordList = newArr.join("\n");
  418. }
  419. this.$message.success("上传成功");
  420. })
  421. .finally(() => {
  422. e.target.value = "";
  423. });
  424. },
  425. /**下载模板 */
  426. downModel() {
  427. if (!this.formData.applyId) {
  428. this.$message.warning("请选择考试计划");
  429. return;
  430. }
  431. if (!this.formData.applySiteAddress) {
  432. this.$message.warning("请选择考试地点");
  433. return;
  434. }
  435. var data = JSON.parse(JSON.stringify(this.formData));
  436. if (this.formData.idCards) {
  437. data.idCards = this.formData.idCards.split("\n");
  438. } else {
  439. this.$message.warning("请选择学员");
  440. return;
  441. }
  442. const indexs = this.examList.findIndex((item) => {
  443. return item.applyId == data.applyId;
  444. });
  445. data.applyName = this.examList[indexs].applyName;
  446. this.$api.inquiresystemsubscribeexportRegister(data).then((res) => {
  447. let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
  448. let link = document.createElement("a");
  449. let fileName = "导入模板" + ".xlsx";
  450. document.body.appendChild(link);
  451. link.href = url;
  452. link.dowmload = fileName;
  453. link.click();
  454. link.remove();
  455. });
  456. },
  457. /**
  458. * 下载错误数据
  459. */
  460. dowmErrorData() {
  461. this.$api
  462. .inquiresystemsubscribeexportexportErrorUpdate(this.tableDataError)
  463. .then((res) => {
  464. let url = baseUrls.baseURL + "common/download?fileName=" + res.msg;
  465. let link = document.createElement("a");
  466. let fileName = "导入模板" + ".xlsx";
  467. document.body.appendChild(link);
  468. link.href = url;
  469. link.dowmload = fileName;
  470. link.click();
  471. link.remove();
  472. });
  473. },
  474. },
  475. };
  476. </script>
  477. <style lang="less" scoped>
  478. .h4Sty {
  479. margin: 6px;
  480. font-size: 14px;
  481. }
  482. .exportBox {
  483. border: 1px solid #999;
  484. padding: 10px;
  485. margin-top: 10px;
  486. border-radius: 4px;
  487. }
  488. /deep/.el-button {
  489. border-radius: 8px;
  490. }
  491. /deep/.el-dialog {
  492. border-radius: 8px;
  493. .el-dialog__header {
  494. padding: 0;
  495. .hearders {
  496. height: 40px;
  497. display: flex;
  498. align-items: center;
  499. justify-content: space-between;
  500. padding: 0px 18px 0px 20px;
  501. border-bottom: 1px solid #e2e2e2;
  502. .leftTitle {
  503. font-size: 14px;
  504. font-weight: bold;
  505. color: #2f4378;
  506. }
  507. .rightBoxs {
  508. display: flex;
  509. align-items: center;
  510. img {
  511. width: 14px;
  512. height: 14px;
  513. margin-left: 13px;
  514. cursor: pointer;
  515. }
  516. }
  517. }
  518. }
  519. .el-dialog__footer {
  520. padding: 0;
  521. .dialog-footer {
  522. padding: 0px 40px;
  523. height: 70px;
  524. border-top: 1px solid #e2e2e2;
  525. display: flex;
  526. align-items: center;
  527. justify-content: flex-end;
  528. }
  529. }
  530. }
  531. .imgBox {
  532. width: 100%;
  533. // height: 210px;
  534. border: 1px solid #e2e2e2;
  535. border-radius: 8px;
  536. padding: 8px 8px 3px;
  537. display: flex;
  538. flex-direction: column;
  539. align-items: center;
  540. .imgLabel {
  541. flex: 1;
  542. width: 100%;
  543. border: 1px dotted #e2e2e2;
  544. color: #999;
  545. font-size: 14px;
  546. cursor: pointer;
  547. border-radius: 8px;
  548. .msPhoto {
  549. display: flex;
  550. justify-content: center;
  551. align-items: center;
  552. max-width: 100%;
  553. max-height: 270px;
  554. img {
  555. max-width: 100%;
  556. max-height: 270px;
  557. }
  558. }
  559. .imgbbx {
  560. display: flex;
  561. flex-direction: column;
  562. align-items: center;
  563. justify-content: center;
  564. width: 100%;
  565. height: 100%;
  566. i {
  567. font-weight: bold;
  568. margin: 14px 0;
  569. font-size: 24px;
  570. }
  571. }
  572. }
  573. p {
  574. margin: 5px 0px;
  575. }
  576. }
  577. .item {
  578. margin-top: 10px;
  579. margin-right: 20px;
  580. }
  581. </style>