SignUpBaseInfo.vue 12 KB

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