123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- <template>
- <div class="one-click-bind">
- <div class="bind-header">
- <span
- >根据《中华人民共和国网络安全法》要求,<br />
- 为避免非正常使用标讯信息,需完成手机号绑定</span
- >
- </div>
- <div class="bind-form">
- <van-field
- v-model.trim="info.phone"
- label="手机号"
- type="tel"
- maxlength="11"
- placeholder="请输入手机号码"
- :error-message="errorMessage.phone"
- @blur="checkPhoneRegPass"
- ></van-field>
- <van-field
- v-show="picCode.show"
- v-model.trim="info.picCode"
- label=""
- maxlength="6"
- placeholder="图形验证码"
- :error-message="errorMessage.picCode"
- >
- <template #button>
- <div class="pic-code" @click="refreshCaptcha">
- <img :src="imgBase64Complete" v-if="picCode.imgBase64" />
- <van-loading size="24" v-else></van-loading>
- </div>
- </template>
- </van-field>
- <van-field
- v-model.trim="info.code"
- label="验证码"
- maxlength="6"
- placeholder="请输入验证码"
- :error-message="errorMessage.code"
- >
- <template #button>
- <van-button
- class="send-code"
- :class="{ active: info.phone }"
- size="small"
- :disabled="sendCodeButtonDisabled"
- @click="sendVerifyCode"
- >{{ sendCodeButtonText }}</van-button
- >
- </template>
- </van-field>
- </div>
- <div class="bind-footer">
- <div class="j-button-group">
- <button
- class="j-button-confirm"
- @click="onSubmit"
- :disabled="confirmButtonDisabled"
- >
- 立即绑定
- </button>
- </div>
- <div class="fast-login-container">
- <button
- class="fast-login-text fast-login-open-link highlight-text"
- @click="getPhoneBind"
- >
- 本机号码一键绑定
- </button>
- </div>
- <div class="tip-text" v-if="showBottomTip">
- 根据《中华人民共和国网络安全法》要求,为避免非正常使用标讯信息,需完成手机号绑定,
- 保障账户安全和信息的正当使用。
- </div>
- </div>
- </div>
- </template>
- <script>
- import { Field, Button, Loading } from 'vant'
- import { getPhoneCaptcha, setPhoneBind } from '@/api/modules/'
- import fastBind from '@/utils/mixins/modules/fast-bind'
- export default {
- name: 'OneClickBinding',
- mixins: [fastBind],
- components: {
- [Field.name]: Field,
- [Button.name]: Button,
- [Loading.name]: Loading
- },
- data() {
- return {
- info: {
- phone: '',
- picCode: '',
- code: ''
- },
- errorMessage: {
- phone: '',
- picCode: '',
- code: ''
- },
- sendCodeButton: {
- timerId: 0,
- timeStartDefault: 60,
- defaultValue: '发送验证码',
- count: 0
- },
- picCode: {
- show: false,
- imgBase64: '',
- cacheShow: false,
- cacheImgBase64: ''
- },
- conf: {
- phoneReg: /^1[3-9]\d{9}$/
- },
- showBottomTip: false
- }
- },
- computed: {
- confirmButtonDisabled() {
- let hasEmpty = false
- if (this.picCode.show) {
- hasEmpty = !this.info.phone || !this.info.code || !this.info.picCode
- } else {
- hasEmpty = !this.info.phone || !this.info.code
- }
- const pass = this.conf.phoneReg.test(this.info.phone)
- return hasEmpty || !pass
- },
- sendCodeButtonText() {
- const dText = this.sendCodeButton.defaultValue
- return this.sendCodeButton.count <= 0
- ? dText
- : `重新发送(${this.sendCodeButton.count}s)`
- },
- sendCodeButtonDisabled() {
- return this.sendCodeButton.count > 0
- },
- imgBase64Complete() {
- return 'data:image/png;base64,' + this.picCode.imgBase64
- }
- },
- methods: {
- showToast(message) {
- this.$toast({
- duration: 1500,
- forbidClick: true,
- message: message
- })
- },
- showLoading() {
- return this.$toast.loading({
- duration: 0,
- forbidClick: true,
- message: 'loading...'
- })
- },
- async getImgCaptcha(needCache) {
- if (this.picCode.cacheImgBase64) {
- this.picCode.show = this.picCode.cacheShow
- this.picCode.imgBase64 = this.picCode.cacheImgBase64
- this.picCode.cacheImgBase64 = ''
- return
- }
- const { error_code: code, error_msg: msg, data } = await getPhoneCaptcha()
- if (code === 0 && data) {
- // 是否缓存图片
- if (needCache == 'cache') {
- // 将下一张图片的状态缓存
- this.picCode.cacheShow = data.needVerify
- this.picCode.cacheImgBase64 = data.imageData
- } else {
- this.picCode.show = data.needVerify
- this.picCode.imgBase64 = data.imageData
- }
- } else {
- this.showToast(msg)
- }
- },
- refreshCaptcha() {
- this.picCode.imgBase64 = ''
- this.getImgCaptcha()
- },
- checkPhoneRegPass() {
- let pass = this.conf.phoneReg.test(this.info.phone)
- if (this.info.phone) {
- if (pass) {
- this.errorMessage.phone = ''
- } else {
- this.errorMessage.phone = '手机号格式不正确'
- }
- } else {
- this.errorMessage.phone = ''
- }
- return pass
- },
- startSendCodeTimer(t) {
- this.sendCodeButton.count = t || this.sendCodeButton.timeStartDefault
- this.sendCodeButton.timerId = setInterval(() => {
- this.sendCodeButton.count--
- if (this.sendCodeButton.count <= 0) {
- // 倒计时结束
- clearInterval(this.sendCodeButton.timerId)
- // 倒计时结束,刷新验证码
- if (this.picCode.cacheImgBase64) {
- this.picCode.show = this.picCode.cacheShow
- this.picCode.imgBase64 = this.picCode.cacheImgBase64
- this.picCode.cacheImgBase64 = ''
- } else {
- this.refreshCaptcha()
- }
- }
- }, 1000)
- },
- // 发送验证码
- async sendVerifyCode() {
- const pass = this.checkPhoneRegPass()
- if (!pass) return
- const loading = this.showLoading()
- const params = {
- phone: this.info.phone,
- code: this.info.picCode,
- step: 1
- }
- const {
- error_code: code,
- error_msg: msg,
- data
- } = await setPhoneBind(params, 'bind')
- loading.clear()
- if (code === 0 && data?.state === 1) {
- this.startSendCodeTimer()
- this.showToast('验证码发送成功')
- this.getImgCaptcha('cache')
- } else {
- this.showToast(msg || '验证码发送失败')
- this.refreshCaptcha()
- }
- },
- bindPhoneSuccess(state) {
- console.log(state, '组件内接收参数')
- if (state === 1) {
- let newQuery = JSON.parse(JSON.stringify(this.$route.query))
- if (newQuery && newQuery.wxpush) {
- delete newQuery.wxpush
- }
- this.$router.replace({ query: newQuery })
- }
- },
- async onSubmit() {
- const pass = this.checkPhoneRegPass()
- if (!pass) return
- const loading = this.showLoading()
- const params = {
- phone: this.info.phone,
- code: this.info.code,
- step: 2
- }
- const {
- error_code: code,
- error_msg: msg,
- data
- } = await setPhoneBind(params, 'bind')
- loading.clear()
- if (code === 0 && data) {
- this.bindPhoneSuccess(data.state)
- } else {
- this.$toast(msg)
- }
- }
- }
- }
- </script>
- <style lang="scss">
- @import '@/assets/style/modules/fast-login.scss';
- </style>
- <style lang="scss" scoped>
- .one-click-bind {
- margin: 12px;
- border: 2px solid $color_main;
- border-radius: 12px;
- background: #fff;
- .bind-header {
- padding: 16px 8px 12px;
- font-size: 14px;
- line-height: 20px;
- color: #171826;
- text-align: center;
- }
- .bind-form {
- padding: 0 8px;
- .send-code {
- padding: 0;
- height: unset;
- color: #c0c4cc;
- font-size: 14px;
- line-height: 20px;
- border: none;
- &.active {
- color: $color_main;
- }
- }
- ::v-deep {
- .van-cell {
- align-items: center;
- padding: 16px;
- }
- .van-field__label {
- width: 75px;
- margin-right: 8px;
- font-size: 15px;
- line-height: 22px;
- color: #5f5e64;
- }
- .van-field__control {
- font-size: 16px;
- }
- .van-field__button {
- display: flex;
- }
- }
- }
- .fast-login-container {
- text-align: center;
- }
- .fast-login-text {
- padding-bottom: 20px;
- font-size: 16px;
- line-height: 26px;
- background-color: transparent;
- }
- }
- </style>
|