SignUpBaseInfo.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <template>
  2. <div class="signupBaseInfo">
  3. <m-header />
  4. <m-step :number="2" />
  5. <!-- <van-form ref="form" :show-error="false" validate-first @submit="onSubmit" @failed="onFailed"> -->
  6. <div class="title">基本信息</div>
  7. <van-field v-model="form.idCardNo" readonly required name="idCardNo" label="身份证号" placeholder="请输入身份证号" >
  8. <template #button>
  9. <!-- <span class="codeText">上传</span> -->
  10. <!-- <van-uploader :before-read="beforeRead2"
  11. :after-read="afterReadOCR"
  12. accept="image/*"
  13. :max-count="1">
  14. <span class="codeText">上传</span>
  15. </van-uploader> -->
  16. <div class="cropper">
  17. <span>上传</span>
  18. <h5-cropper
  19. @getFile="getFile"
  20. :option="option"
  21. ></h5-cropper>
  22. </div>
  23. </template>
  24. </van-field>
  25. <!-- <div class="cardTips">如有括号,请用英文括号()</div> -->
  26. <van-field readonly required v-model="form.realName" name="realName" label="姓名" placeholder="请输入姓名" />
  27. <van-field name="radio" required label="性别">
  28. <template #input>
  29. <van-radio-group v-model="form.gender" direction="horizontal">
  30. <van-radio disabled checked-color="var(--main-color)" :name="1">男</van-radio>
  31. <van-radio disabled checked-color="var(--main-color)" :name="0">女</van-radio>
  32. </van-radio-group>
  33. </template>
  34. </van-field>
  35. <van-field readonly required name="birthdate" v-model="form.birthdate" label="生日" placeholder="请选择" />
  36. <van-field readonly required name="nation" v-model="form.nation" label="民族" placeholder="请选择" />
  37. <div class="title">证件照上传</div>
  38. <div class="upload-img">
  39. <van-uploader v-model="certificatePhoto" :before-read="beforeRead"
  40. :before-delete="beforeDelete"
  41. :after-read="afterRead"
  42. accept="image/*"
  43. :max-count="1">
  44. <div class="upload-container">
  45. <i class="icon-upload-add"></i>
  46. <p>点击上传</p>
  47. </div>
  48. </van-uploader>
  49. <p class="upload-tips">须使用免冠证件照,纯底色<br/>(纯白、纯蓝或纯红)<br/>(图像预览可能会异常)</p>
  50. </div>
  51. <m-button class="step-btn" @click="onSubmit" text="下一步" />
  52. <!-- </van-form> -->
  53. </div>
  54. </template>
  55. <script>
  56. import MHeader from '@/components/MHeader'
  57. import MStep from '@/components/MStep'
  58. import MButton from '@/components/MButton'
  59. import setLoading from '@/utils/loading'
  60. import H5Cropper from 'vue-cropper-h5'
  61. import { getStudent, ocr, uploadFile, updateStudentInfo, getExamIngOrder, closeOrder } from './SignUpApi'
  62. import dayjs from 'dayjs'
  63. export default {
  64. name: 'signupBaseInfo',
  65. components: { MHeader, MStep, MButton, H5Cropper },
  66. data () {
  67. const examId = localStorage.getItem('examId')
  68. return {
  69. examId: examId,
  70. certificatePhoto: [],
  71. form: {
  72. idCardNo: null,
  73. realName: null,
  74. gender: 1,
  75. birthdate: null,
  76. nation: null,
  77. certificatePhoto: null
  78. },
  79. fileList: [],
  80. option: {
  81. canScale: true,
  82. fixedNumber: [3, 2],
  83. img: '',
  84. size: 1,
  85. info: true,
  86. full: false,
  87. canMove: true,
  88. fixedBox: false,
  89. original: false,
  90. canMoveBox: true,
  91. autoCrop: true,
  92. centerBox: false,
  93. high: true
  94. }, //配置
  95. }
  96. },
  97. mounted() {
  98. localStorage.removeItem("examRegistrationParams")
  99. // 插入token
  100. // let params = this.$route.query
  101. // if(params.Authorization) {
  102. // localStorage.setItem('Authorization', decodeURI(params.Authorization))
  103. // localStorage.setItem('userInfo', decodeURI(params.Authorization))
  104. // }
  105. this.__init()
  106. },
  107. methods: {
  108. async getFile(file) {
  109. setLoading(true)
  110. try {
  111. let formData = new FormData()
  112. formData.append('file', file)
  113. formData.append('idCardSide', "front")
  114. let res = await ocr(formData)
  115. let result = res.data
  116. setLoading(false)
  117. if(result.code == 200) {
  118. this.idCardParse(result.data)
  119. } else {
  120. this.$toast(result.msg)
  121. return false
  122. }
  123. } catch (err) {
  124. return false
  125. }
  126. },
  127. async __init() {
  128. setLoading(true)
  129. try {
  130. const res = await getStudent()
  131. if(res.data.code == 200) {
  132. const tempData = res.data.data
  133. this.form = {
  134. idCardNo: tempData.idCardNo,
  135. realName: tempData.realName == tempData.phone ? null : tempData.realName,
  136. gender: tempData.gender,
  137. birthdate: tempData.birthdate ? dayjs(tempData.birthdate).format('YYYY-MM-DD') : null,
  138. nation: tempData.nation,
  139. certificatePhoto: tempData.certificatePhoto
  140. }
  141. if(tempData.certificatePhoto) { // 判断是否在头像
  142. this.certificatePhoto = [{url: tempData.certificatePhoto}]
  143. }
  144. }
  145. const order = await getExamIngOrder({ examinationBasicId: this.examId })
  146. const resultOrder = order.data
  147. if(resultOrder.code == 200 && resultOrder.data) {
  148. this.$dialog.confirm({
  149. title: '提示',
  150. message: "您当前有待支付订单",
  151. confirmButtonColor: '#269a93',
  152. cancelButtonText: '取消订单',
  153. confirmButtonText: '去支付'
  154. }).then(() => {
  155. this.$router.push({
  156. path: '/signUpPayment',
  157. query: {
  158. orderNo: resultOrder.data.orderNo,
  159. examRegistrationId: resultOrder.data.examRegistrationId
  160. }
  161. })
  162. }).catch(() => {
  163. const orderNo = resultOrder.data.orderNo
  164. this.$dialog.close()
  165. if(!orderNo) {
  166. return
  167. }
  168. this.onCloseOrder(orderNo)
  169. })
  170. }
  171. } catch(err) {
  172. //
  173. }
  174. setLoading(false)
  175. },
  176. async onCloseOrder(orderNo) {
  177. setLoading(true)
  178. await closeOrder({ orderNo: orderNo })
  179. setLoading(false)
  180. },
  181. async onSubmit() {
  182. if(!this.onCheckFields()) {
  183. return
  184. }
  185. setLoading(true)
  186. try {
  187. let res = await updateStudentInfo(this.form)
  188. setLoading(false)
  189. let result = res.data
  190. if(result.code == 200) {
  191. // localStorage.setItem("studentName", this.form.realName)
  192. this.$router.push({
  193. path: '/signUpLevel'
  194. })
  195. } else {
  196. this.$toast(result.msg)
  197. }
  198. } catch(err) {
  199. //
  200. }
  201. // this.$router.push({
  202. // path: '/signUpLevel'
  203. // })
  204. },
  205. onCheckFields() { // 校验字段
  206. let form = this.form
  207. if(!form.idCardNo || !form.realName || !form.birthdate || !form.nation) {
  208. this.$toast('请上传身份证正面进行扫描')
  209. return false
  210. } else if(!form.certificatePhoto) {
  211. this.$toast('请上传证件照片')
  212. return false
  213. }
  214. return true
  215. },
  216. // beforeRead2(file) {
  217. // const isLt2M = file.size / 1024 / 1024 < 4
  218. // if (!isLt2M) {
  219. // this.$toast('上传证书大小不能超过 4MB')
  220. // return false
  221. // }
  222. // return true
  223. // },
  224. beforeRead(file) {
  225. const isLt2M = file.size / 1024 / 1024 < 2
  226. if (!isLt2M) {
  227. this.$toast('上传图片大小不能超过 2MB')
  228. return false
  229. }
  230. return true
  231. },
  232. beforeDelete() {
  233. this.form.certificatePhoto = '' // 上传图片地址为空
  234. return true
  235. },
  236. async afterRead(file) { // 上传头像
  237. // setLoading(true)
  238. try {
  239. file.status = 'uploading'
  240. file.message = '上传中...'
  241. let formData = new FormData()
  242. formData.append('file', file.file)
  243. let res = await uploadFile(formData)
  244. let result = res.data
  245. // setLoading(false)
  246. if(result.code == 200) {
  247. file.status = 'done'
  248. this.form.certificatePhoto = result.data.url
  249. } else {
  250. file.status = 'failed'
  251. file.message = '上传失败'
  252. this.$toast(result.msg)
  253. return false
  254. }
  255. } catch (err) {
  256. return false
  257. }
  258. },
  259. // async afterReadOCR(file) { // 上传身份证照片识别
  260. // setLoading(true)
  261. // try {
  262. // let formData = new FormData()
  263. // formData.append('file', file.file)
  264. // formData.append('idCardSide', "front")
  265. // let res = await ocr(formData)
  266. // let result = res.data
  267. // setLoading(false)
  268. // if(result.code == 200) {
  269. // this.idCardParse(result.data)
  270. // } else {
  271. // this.$toast(result.msg)
  272. // return false
  273. // }
  274. // } catch (err) {
  275. // return false
  276. // }
  277. // },
  278. idCardParse(data) {
  279. // 身份证信息解析
  280. let wordsResult = data.words_result
  281. let errorText
  282. switch (data.image_status) {
  283. case "normal":
  284. this.form = {
  285. idCardNo: wordsResult["公民身份号码"].words,
  286. realName: wordsResult["姓名"].words,
  287. gender: wordsResult["性别"].words == '男' ? 1 : 0,
  288. birthdate: dayjs(wordsResult["出生"].words).format('YYYY-MM-DD'),
  289. nation: wordsResult["民族"].words,
  290. certificatePhoto: this.form.certificatePhoto
  291. }
  292. break;
  293. case "reversed_side":
  294. errorText = "身份证正反面颠倒"
  295. break;
  296. case "non_idcard":
  297. errorText = "上传的图片中不包含身份证"
  298. break;
  299. case "blurred":
  300. errorText = "身份证模糊"
  301. break;
  302. case "other_type_card":
  303. errorText = "身份证关键字段反光或过曝"
  304. break;
  305. case "over_dark":
  306. errorText = "身份证欠曝(亮度过低)"
  307. break;
  308. default:
  309. errorText = "上传身份证有误"
  310. break;
  311. }
  312. errorText && this.$toast(errorText)
  313. }
  314. },
  315. destroyed() {
  316. this.$toast.clear()
  317. this.$dialog.close()
  318. }
  319. }
  320. </script>
  321. <style lang="less" scoped>
  322. .cropper {
  323. width: 60px;
  324. /* 切记position: relative一定要有 */
  325. position: relative;
  326. overflow: hidden;
  327. text-align: center;
  328. span {
  329. position: absolute;
  330. width: 100%;
  331. height: 100%;
  332. left: 0;
  333. top: 0;
  334. color: var(--main-color);
  335. }
  336. .upbtn {
  337. height: 24px;
  338. }
  339. }
  340. .img {
  341. position: absolute;
  342. width: 100%;
  343. height: 100%;
  344. left: 0;
  345. top: 0;
  346. }
  347. .signupBaseInfo {
  348. height: 100vh;
  349. overflow-y: auto;
  350. overflow-x: hidden;
  351. background-color: var(--main-bg-color);
  352. .title {
  353. font-size: .16rem;
  354. color: var(--font-second-color);
  355. padding: .12rem .16rem;
  356. }
  357. /deep/.van-cell {
  358. padding: .13rem .16rem;
  359. }
  360. /deep/.van-field__label {
  361. font-size: .17rem;
  362. color: var(--font-main-color);
  363. width: 1rem;
  364. }
  365. /deep/.van-field__body {
  366. font-size: .16rem
  367. }
  368. .codeText {
  369. font-size: .16rem;
  370. color: var(--main-color);
  371. }
  372. }
  373. .upload-img {
  374. background: #ffffff;
  375. text-align: center;
  376. padding: .3rem 0 .2rem;
  377. .van-uploader__wrapper {
  378. &:active {
  379. .icon-upload-add {
  380. display: inline-block;
  381. width: .55rem;
  382. height: .55rem;
  383. background: url('../../assets/images/level/icon_upload_add_active.png') no-repeat center;
  384. background-size: contain;
  385. }
  386. // p {
  387. // }
  388. }
  389. }
  390. .upload-container {
  391. width: 1rem;
  392. height: 1.4rem;
  393. background: url('../../assets/images/level/uploadBg.png') no-repeat center;
  394. background-size: contain;
  395. display: flex;
  396. flex-direction: column;
  397. justify-content: center;
  398. align-items: center;
  399. }
  400. .upload-tips {
  401. padding-top: .18rem;
  402. font-size: .14rem;
  403. color: var(--font-second-color);
  404. }
  405. .icon-upload-add {
  406. display: inline-block;
  407. width: .55rem;
  408. height: .55rem;
  409. background: url('../../assets/images/level/icon_upload_add.png') no-repeat center;
  410. background-size: contain;
  411. }
  412. p {
  413. margin-top: -.04rem;
  414. font-size: .16rem;
  415. color: var(--main-color);
  416. }
  417. }
  418. /deep/.van-uploader__preview {
  419. margin: 0;
  420. }
  421. /deep/.van-uploader__preview-image {
  422. width: 1rem;
  423. height: 1.4rem;
  424. }
  425. .cardTips {
  426. font-size: .14rem;
  427. color: #2DC7AA;
  428. padding-left: 1.28rem;
  429. padding-top: .03rem;
  430. padding-bottom: .15rem;
  431. }
  432. /deep/.van-radio__icon--disabled .van-icon {
  433. background-color: #F5F5F5;
  434. }
  435. /deep/.van-radio__icon--disabled.van-radio__icon--checked .van-icon {
  436. background-color: var(--main-color);
  437. border-color: var(--main-color);
  438. color: #ffffff;
  439. }
  440. </style>