|
|
@@ -0,0 +1,261 @@
|
|
|
+<template>
|
|
|
+ <div class="l-flex--col">
|
|
|
+ <div class="l-flex--row c-line">
|
|
|
+ <div class="c-grid-form__label c-line__left u-color--black u-bold">
|
|
|
+ 绑定{{ config.label }}:
|
|
|
+ </div>
|
|
|
+ <div class="c-line__mid">
|
|
|
+ <el-input
|
|
|
+ v-model="cValue"
|
|
|
+ :maxlength="config.maxlength"
|
|
|
+ :placeholder="'请输入'+config.tipText"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="c-line__right has-left-padding">
|
|
|
+ <button
|
|
|
+ v-if="expanded === false"
|
|
|
+ class="o-button"
|
|
|
+ @click="expanded = true"
|
|
|
+ >
|
|
|
+ {{ initial?'更换':'绑定' }}{{ config.label }}
|
|
|
+ </button>
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="u-pointer u-color--blue"
|
|
|
+ @click="expanded = false"
|
|
|
+ >
|
|
|
+ 收起
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="expanded === true"
|
|
|
+ class="l-flex--row c-line"
|
|
|
+ >
|
|
|
+ <div class="c-line__left" />
|
|
|
+ <div class="c-line__mid l-flex--row">
|
|
|
+ <el-input
|
|
|
+ v-model="code"
|
|
|
+ class="c-code"
|
|
|
+ maxlength="6"
|
|
|
+ placeholder="验证码"
|
|
|
+ @keydown.enter="bind"
|
|
|
+ />
|
|
|
+ <el-button
|
|
|
+ class="o-button l-flex__fill c-btn"
|
|
|
+ :disabled="verification"
|
|
|
+ @click="sendCode"
|
|
|
+ >
|
|
|
+ {{ codeText }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div class="c-line__right" />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="expanded === true"
|
|
|
+ class="l-flex--row c-line"
|
|
|
+ >
|
|
|
+ <div class="c-line__left" />
|
|
|
+ <div class="c-line__mid l-flex--row">
|
|
|
+ <el-button
|
|
|
+ class="o-button l-flex__fill"
|
|
|
+ @click="bind"
|
|
|
+ >绑定</el-button>
|
|
|
+ </div>
|
|
|
+ <div class="c-line__right" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import {
|
|
|
+ validPhone, validEmail
|
|
|
+} from '@/utils/validate'
|
|
|
+import {
|
|
|
+ authcodeSend, authcodeCheck
|
|
|
+} from '@/api/user'
|
|
|
+const COUNTDOWN = 60
|
|
|
+const config = {
|
|
|
+ phone: {
|
|
|
+ label: '手机',
|
|
|
+ tipText: '手机号',
|
|
|
+ maxlength: 11,
|
|
|
+ valid: validPhone,
|
|
|
+ typeKey: 'phoneNum',
|
|
|
+ codeKey: 'phoneNumAuthCode',
|
|
|
+ checkKey: 'checkPhoneNum'
|
|
|
+ },
|
|
|
+ email: {
|
|
|
+ label: '邮箱',
|
|
|
+ maxlength: 50,
|
|
|
+ valid: validEmail,
|
|
|
+ tipText: '邮箱',
|
|
|
+ typeKey: 'email',
|
|
|
+ codeKey: 'emailAuthCode',
|
|
|
+ checkKey: 'checkEmail'
|
|
|
+ }
|
|
|
+}
|
|
|
+export default {
|
|
|
+ name: 'UserInfoItem',
|
|
|
+ props: {
|
|
|
+ type: {
|
|
|
+ type: String,
|
|
|
+ require: true,
|
|
|
+ default: 'phone'
|
|
|
+ },
|
|
|
+ value: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ initial: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ config: {},
|
|
|
+ code: null,
|
|
|
+ expanded: false,
|
|
|
+ verification: false,
|
|
|
+ countDown: COUNTDOWN
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ cValue: {
|
|
|
+ get () {
|
|
|
+ return this.value
|
|
|
+ },
|
|
|
+ set (v) {
|
|
|
+ this.$emit('input', v)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ codeText () {
|
|
|
+ return this.verification ? `${this.countDown} s` : '发送验证码'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ initial () {
|
|
|
+ this.reset()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created () {
|
|
|
+ this.config = config[this.type]
|
|
|
+ },
|
|
|
+ beforeDestroy () {
|
|
|
+ clearInterval(this.$timer)
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ reset () {
|
|
|
+ this.expanded = false
|
|
|
+ this.code = ''
|
|
|
+ this.verification = false
|
|
|
+ this.countDown = COUNTDOWN
|
|
|
+ clearInterval(this.$timer)
|
|
|
+ },
|
|
|
+ sendCode () {
|
|
|
+ if (this.verification) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!this.value) {
|
|
|
+ this.$message({
|
|
|
+ type: 'warning',
|
|
|
+ message: `${this.config.tipText}不能为空`
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!this.config.valid(this.value)) {
|
|
|
+ this.$message({
|
|
|
+ type: 'warning',
|
|
|
+ message: `${this.config.tipText}格式错误`
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ authcodeSend({
|
|
|
+ [this.config.typeKey]: this.value
|
|
|
+ })
|
|
|
+ .then(({ success, errMessage }) => {
|
|
|
+ if (success) {
|
|
|
+ this.$message({
|
|
|
+ type: 'success',
|
|
|
+ message: '验证码已发送...'
|
|
|
+ })
|
|
|
+ this.verification = true
|
|
|
+ this.countDown = COUNTDOWN
|
|
|
+ this.$timer = setInterval(() => {
|
|
|
+ this.countDown--
|
|
|
+ if (this.countDown <= 0) {
|
|
|
+ this.verification = false
|
|
|
+ this.countDown = COUNTDOWN
|
|
|
+ clearInterval(this.$timer)
|
|
|
+ }
|
|
|
+ }, 1000)
|
|
|
+ } else {
|
|
|
+ console.log(errMessage)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ console.log(err)
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ bind () {
|
|
|
+ if (!this.value) {
|
|
|
+ this.$message({
|
|
|
+ type: 'warning',
|
|
|
+ message: `${this.config.tipText}不能为空`
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!this.code) {
|
|
|
+ this.$message({
|
|
|
+ type: 'warning',
|
|
|
+ message: `验证码不能为空`
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ authcodeCheck({
|
|
|
+ [this.config.typeKey]: this.value,
|
|
|
+ [this.config.codeKey]: this.code
|
|
|
+ }).then(({ success, data }) => {
|
|
|
+ if (success) {
|
|
|
+ if (data[this.config.checkKey]) {
|
|
|
+ this.$emit('update', () => this.reset())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.$message({
|
|
|
+ type: 'error',
|
|
|
+ message: `验证码错误`
|
|
|
+ })
|
|
|
+ }).catch(err => {
|
|
|
+ console.log(err)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.c-line {
|
|
|
+ padding-bottom: $spacing;
|
|
|
+ width: 420px;
|
|
|
+ &__left {
|
|
|
+ flex: 0 0 80px;
|
|
|
+ }
|
|
|
+ &__mid {
|
|
|
+ flex: 1
|
|
|
+ }
|
|
|
+ &__right {
|
|
|
+ flex: 0 0 120px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.c-code {
|
|
|
+ flex: 0 0 100px;
|
|
|
+ margin-right: 20px;
|
|
|
+}
|
|
|
+::v-deep.el-button.is-disabled {
|
|
|
+ border: 1px solid $blue;
|
|
|
+ color: $blue;
|
|
|
+}
|
|
|
+</style>
|