PhoneValidationSecondStep.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. <template>
  2. <div class="validation">
  3. <div class="container">
  4. <div class="content">
  5. <div class="content-top">
  6. <h3>验证手机</h3>
  7. <div class="step">
  8. <img src="/images/all/step02.png" alt=""/>
  9. <div class="step-item"><span class="active">账号验证</span><span class="active">新手机号码</span><span>设置完成</span></div>
  10. </div>
  11. </div>
  12. <div class="content-bottom">
  13. <div>
  14. <el-form :model="valid2" :rules="rules2" ref="valid2" label-width="100px" class="demo-ruleForm">
  15. <el-form-item prop="mobile">
  16. <el-input v-model="valid2.mobile" placeholder="新手机号码"></el-input>
  17. </el-form-item>
  18. <el-form-item prop="code">
  19. <el-input type="text" v-model="valid2.code"
  20. v-bind:class="{ active: this.secondStepCodeErrorChecked }"
  21. auto-complete="off"
  22. class="msg"
  23. placeholder="短信验证码"></el-input>
  24. <el-button type="primary" class="code"
  25. v-show="showSecondStepCode"
  26. @click="getSecondCheckCode"
  27. :disabled="getCodeBtnIsDisabled">获取验证码</el-button>
  28. <el-button type="primary" v-show="!showSecondStepCode" class="code code-send">已发送({{second_step_time}}s)</el-button>
  29. <span v-show="secondStepCodeErrorChecked" class="tip codeError-tip">{{secondCodeErrorMsg}}</span>
  30. </el-form-item>
  31. <el-form-item>
  32. <a class="btn finish"
  33. :disabled="!mobileSecondChecked || !secondCodeChecked"
  34. @click="setNewMobile">确认</a>
  35. </el-form-item>
  36. </el-form>
  37. </div>
  38. </div>
  39. </div>
  40. <loading v-show="isShowLoading"/>
  41. </div>
  42. </div>
  43. </template>
  44. <script>
  45. import Loading from '~components/common/loading/Loading.vue'
  46. export default {
  47. name: 'validation',
  48. components: {
  49. Loading
  50. },
  51. data () {
  52. // 第二步验证手机
  53. var validateSecondMobile = (rule, value, callback) => {
  54. if (value === '') {
  55. callback(new Error('请填写正确的手机号'))
  56. this.getCodeBtnIsDisabled = true
  57. this.mobileSecondChecked = false
  58. } else {
  59. if (this.valid2.mobile !== '') {
  60. var reg = /^1[0-9]{10}$/
  61. if (!reg.test(value)) {
  62. callback(new Error('请填写正确的手机号'))
  63. this.getCodeBtnIsDisabled = true
  64. this.mobileSecondChecked = false
  65. } else {
  66. this.getCodeBtnIsDisabled = false
  67. this.mobileSecondChecked = true
  68. }
  69. }
  70. callback()
  71. }
  72. }
  73. var validateSecondCode = (rule, value, callback) => {
  74. if (value === '') {
  75. callback(new Error('请填写正确的验证码'))
  76. this.secondStepCodeErrorChecked = false
  77. this.secondCodeChecked = false
  78. } else {
  79. if (this.valid2.code !== '') {
  80. if (this.valid2.mobile === '') {
  81. callback(new Error('请先填写正确的手机号'))
  82. } else {
  83. if (this.secondToken) {
  84. let param = new FormData()
  85. param.append('mobile', this.valid2.mobile)
  86. param.append('code', this.valid2.code)
  87. param.append('token', this.secondToken)
  88. let config = {
  89. headers: {'Content-Type': 'multipart/form-data'}
  90. }
  91. this.$http.post(`/update/user/checkCode/mobile`, param, config)
  92. .then(response => {
  93. if (response.data.success) {
  94. this.secondCodeChecked = true
  95. this.secondStepCodeErrorChecked = false
  96. } else {
  97. this.secondStepCodeErrorChecked = true
  98. this.secondCodeChecked = false
  99. return Promise.reject(response.data)
  100. }
  101. }).catch(err => {
  102. this.secondCodeErrorMsg = err.errMsg
  103. })
  104. } else {
  105. callback(new Error('请先获取验证码'))
  106. this.codeChecked = false
  107. this.codeErrorChecked = false
  108. }
  109. }
  110. }
  111. callback()
  112. }
  113. }
  114. return {
  115. isShowLoading: false,
  116. second_step_time: 0,
  117. codeErrorChecked: false,
  118. secondStepCodeErrorChecked: false,
  119. secondCodeChecked: false,
  120. secondCodeErrorMsg: '',
  121. mobileSecondChecked: false,
  122. getCodeBtnIsDisabled: true,
  123. showSecondStepCode: true,
  124. valid2: {
  125. mobile: '',
  126. code: ''
  127. },
  128. rules2: {
  129. mobile: [
  130. {validator: validateSecondMobile, trigger: 'blur'}
  131. ],
  132. code: [
  133. {validator: validateSecondCode, trigger: 'blur'}
  134. ]
  135. }
  136. }
  137. },
  138. computed: {
  139. firstStepToken () {
  140. return this.$store.state.login.token.data
  141. }
  142. },
  143. mounted () {
  144. // 获取邮箱token
  145. this.$nextTick(() => {
  146. this.getEmailLinkToken()
  147. })
  148. },
  149. methods: {
  150. // 获取第二步手机验证码
  151. getSecondCheckCode () {
  152. this.isShowLoading = true
  153. console.log(this.isShowLoading)
  154. this.$http.get(`/update/user/setMobile`, {params: {mobile: this.valid2.mobile, token: this.firstStepToken}})
  155. .then(response => {
  156. this.isShowLoading = false
  157. if (response.data.success) {
  158. this.secondToken = response.data.content.token
  159. if (this.secondToken !== '') {
  160. this.$message({
  161. message: '验证码已经发送到您的手机,请注意查收',
  162. type: 'success'
  163. })
  164. this.showSecondStepCode = false
  165. this.second_step_time = 60
  166. var secondStepTime = setInterval(() => {
  167. this.second_step_time--
  168. if (this.second_step_time <= 0) {
  169. this.showSecondStepCode = true
  170. clearInterval(secondStepTime)
  171. }
  172. }, 1000)
  173. }
  174. } else {
  175. return Promise.reject(response.data)
  176. }
  177. }).catch(err => {
  178. this.isShowLoading = false
  179. this.$message.error(err.errMsg)
  180. })
  181. },
  182. // 设置新手机号
  183. setNewMobile () {
  184. if (this.mobileSecondChecked && this.secondCodeChecked) {
  185. this.isShowLoading = true
  186. let param = new FormData()
  187. param.append('mobile', this.valid2.mobile)
  188. param.append('code', this.valid2.code)
  189. param.append('token', this.secondToken)
  190. let config = {
  191. headers: {'Content-Type': 'multipart/form-data'}
  192. }
  193. this.$http.post(`/update/user/setMobile`, param, config)
  194. .then(response => {
  195. this.isShowLoading = false
  196. if (response.data.success) {
  197. this.$router.push({ path: '/validation/phoneValidationThirdStep' })
  198. } else {
  199. return Promise.reject(response.data)
  200. }
  201. }).catch(err => {
  202. this.$message.error(err.errMsg)
  203. this.isShowLoading = false
  204. this.secondStepCodeErrorChecked = true
  205. this.secondCodeChecked = false
  206. this.second_step_time = 0
  207. })
  208. }
  209. },
  210. // 获得邮箱token
  211. getEmailLinkToken () {
  212. var url = window.location.search
  213. var request = {}
  214. if (url.indexOf('?' !== -1)) {
  215. var str = url.substr(1)
  216. var strs = str.split('&')
  217. for (var i = 0; i < strs.length; i++) {
  218. request[strs[i].split('=')[0]] = decodeURI(strs[i].split('=')[1])
  219. }
  220. }
  221. this.Token = request['token'] || ''
  222. if (this.Token) {
  223. this.$store.commit('login/GET_TOKEN', this.Token)
  224. }
  225. }
  226. }
  227. }
  228. </script>
  229. <style lang="scss" scoped>
  230. .validation {
  231. margin: 0 auto;
  232. width: 100%;
  233. background: #eee;
  234. .container{
  235. padding-top: 50px;
  236. margin: 0 auto;
  237. width: 980px;
  238. text-align: center;
  239. .content{
  240. padding: 0 50px;
  241. margin: 50px auto 0;
  242. width: 100%;
  243. /*height: 540px;*/
  244. text-align: center;
  245. background: #fff;
  246. .content-top{
  247. height: 80px;
  248. line-height: 80px;
  249. h3{
  250. margin-bottom: 0;
  251. font-size: 24px;
  252. color: #000;
  253. border-bottom: 1px solid #dcdcdc;
  254. }
  255. .step{
  256. position: relative;
  257. margin-top: 10px;
  258. img{
  259. width: 315px;
  260. height: 46px;
  261. }
  262. .step-item{
  263. position: absolute;
  264. top: 45px;
  265. left: 265px;
  266. span{
  267. margin-right: 78px;
  268. font-size: 14px;
  269. color: #b4b4b4;
  270. }
  271. span.active {
  272. color: #0076ad;
  273. }
  274. }
  275. }
  276. }
  277. form {
  278. margin-top: 150px;
  279. padding-bottom: 44px;
  280. input{
  281. padding: 0 0 0 18px;
  282. width: 360px;
  283. height: 44px;
  284. line-height: 44px;
  285. font-size: 14px;
  286. color: #000;
  287. border-radius: 0;
  288. }
  289. input.answer {
  290. background: url("/images/all/more.png") no-repeat 325px center;
  291. cursor: pointer;
  292. }
  293. ul{
  294. display: none;
  295. position: absolute;
  296. top: 44px;
  297. left: 0;
  298. width: 360px;
  299. background: #fff;
  300. box-shadow: 0 0 5px rgba(0,0,0,.5);
  301. -moz-box-shadow: 0 0 5px rgba(0,0,0,.5);
  302. -o-box-shadow: 0 0 5px rgba(0,0,0,.5);
  303. -webkit-box-shadow: 0 0 5px rgba(0,0,0,.5);
  304. z-index: 10;
  305. li{
  306. padding-left: 18px;
  307. width: 100%;
  308. height: 30px;
  309. line-height: 30px;
  310. text-align: left;
  311. font-size: 14px;
  312. color: #000;
  313. cursor: pointer;
  314. &:hover{
  315. background: #0076ad;
  316. color: #fff;
  317. }
  318. }
  319. }
  320. span.tip{
  321. position: absolute;
  322. top: 0;
  323. right: -238px;
  324. font-size: 13px;
  325. color: #8c8c8c;
  326. a{
  327. font-size: 13px;
  328. color: #0076ad;
  329. }
  330. }
  331. span.tip.codeError-tip{
  332. position: absolute;
  333. top: 3px;
  334. left: 378px;
  335. width: 200px;
  336. text-align: left;
  337. color: #ff4949;
  338. font-size: 12px;
  339. }
  340. i{
  341. position: absolute;
  342. top: 13px;
  343. left: 20px;
  344. font-size: 20px;
  345. color: #a0a0a0;
  346. }
  347. .btn {
  348. margin: 34px 0 16px 0;
  349. width: 360px;
  350. height: 44px;
  351. line-height: 44px;
  352. font-size: 16px;
  353. color: #fff;
  354. background: #0076AD;
  355. border-radius: 3px;
  356. }
  357. }
  358. .content-bottom{
  359. margin: 155px auto 0;
  360. padding-bottom: 50px;
  361. width: 360px;
  362. div.warp{
  363. padding-bottom: 65px;
  364. }
  365. p{
  366. font-size: 24px;
  367. color: #323232;
  368. img{
  369. margin-right: 20px;
  370. width: 30px;
  371. height: 28px;
  372. }
  373. }
  374. p.pass{
  375. font-size: 24px;
  376. color: #e77405;
  377. img{
  378. height: 30px;
  379. }
  380. }
  381. p.passed {
  382. color: #2ab300;
  383. img{
  384. height: 30px;
  385. }
  386. }
  387. span{
  388. display: inline-block;
  389. font-size: 14px;
  390. color: #8b8b8b;
  391. }
  392. span.close-tip{
  393. margin: 15px 0 140px 0;
  394. }
  395. .close-btn{
  396. margin: 0 auto;
  397. width: 200px;
  398. height: 36px;
  399. line-height: 36px;
  400. font-size: 14px;
  401. text-align: center;
  402. color: #323232;
  403. border: 1px solid #d2d2d2;
  404. border-radius: 3px;
  405. cursor: pointer ;
  406. }
  407. span.use{
  408. display: inline-block;
  409. margin-bottom: 30px;
  410. width: 360px;
  411. font-size: 14px;
  412. color: #000;
  413. text-align: left;
  414. em{
  415. font-size: 14px;
  416. font-style: normal;
  417. color: #000;
  418. }
  419. }
  420. .form-group {
  421. margin: 0 auto 16px;
  422. position: relative;
  423. width: 360px;
  424. height: 44px;
  425. line-height: 44px;
  426. input{
  427. padding: 0 0 0 18px;
  428. width: 360px;
  429. height: 44px;
  430. line-height: 44px;
  431. font-size: 14px;
  432. color: #000;
  433. border-radius: 0;
  434. }
  435. input.msg{
  436. float: left;
  437. width: 210px;
  438. padding: 0 0 0 18px;
  439. height: 44px;
  440. line-height: 44px;
  441. font-size: 14px;
  442. color: #000;
  443. border-radius: 0;
  444. }
  445. span.msg{
  446. float: right;
  447. margin: 0;
  448. width: 130px;
  449. height: 44px;
  450. line-height: 44px;
  451. text-align: center ;
  452. font-size: 14px;
  453. color: #5a5a5a;
  454. background: #f4f4f4;
  455. border: 1px solid #dcdcdc;
  456. cursor: pointer;
  457. }
  458. span.msg.send{
  459. background: #d2d2d2;
  460. color: #fff;
  461. }
  462. }
  463. .btn {
  464. margin: 34px 0 10px 0;
  465. width: 360px;
  466. height: 44px;
  467. line-height: 44px;
  468. font-size: 16px;
  469. color: #fff;
  470. background: #0076AD;
  471. border-radius: 3px;
  472. }
  473. }
  474. .choose{
  475. margin: 155px auto 0;
  476. padding-bottom: 44px;
  477. div{
  478. padding: 0 15px;
  479. margin: 0 auto 16px;
  480. width: 360px;
  481. height: 60px;
  482. line-height: 60px;
  483. text-align: left;
  484. overflow: hidden;
  485. border: 1px solid #d2d2d2;
  486. cursor: pointer;
  487. &:hover,&.active{
  488. border-color: #0076ad;
  489. span{
  490. color: #0076ad;
  491. }
  492. i.second {
  493. color: #0076ad;
  494. }
  495. }
  496. img.first{
  497. float: left;
  498. margin: 24px 20px 0 0;
  499. font-size: 20px;
  500. color: #323232;
  501. }
  502. img.first.mob{
  503. margin: 22px 20px 0 5px;
  504. font-size: 28px;
  505. }
  506. i.second {
  507. float: right;
  508. margin: 20px 0 0 5px;
  509. font-size: 20px;
  510. color: #323232;
  511. }
  512. span{
  513. float: left;
  514. font-size: 14px;
  515. color: #323232;
  516. }
  517. }
  518. }
  519. a.return{
  520. position: absolute;
  521. left: 0;
  522. top: -15px;
  523. img{
  524. width: 34px !important;
  525. height: 34px !important;
  526. }
  527. }
  528. }
  529. }
  530. }
  531. </style>