newRegister.vue 14 KB

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