bind.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <template>
  2. <div class="w-full h-full bg-page flex items-center justify-center">
  3. <div class="flex bg-white">
  4. <div class="bg-white w-[380px] p-[30px]">
  5. <div class="flex items-end mb-[30px] mt-[15px]">
  6. <div class="mr-[20px] text-base cursor-pointer leading-none font-bold">{{t('mobileBind')}}</div>
  7. </div>
  8. <el-form :model="formData" ref="formRef" :rules="formRules" :validate-on-rule-change="false">
  9. <div>
  10. <el-form-item prop="mobile">
  11. <el-input v-model="formData.mobile" :placeholder="t('mobilePlaceholder')" clearable>
  12. </el-input>
  13. </el-form-item>
  14. <el-form-item prop="mobile_code">
  15. <el-input v-model="formData.mobile_code" :placeholder="t('codePlaceholder')">
  16. <template #suffix>
  17. <sms-code :mobile="formData.mobile" type="login" v-model="formData.mobile_key" @click="sendSmsCode" ref="smsCodeRef"></sms-code>
  18. </template>
  19. </el-input>
  20. </el-form-item>
  21. </div>
  22. <el-form-item>
  23. <el-button type="primary" class="mt-[20px] w-full" size="large" @click="handleRegister" :loading="loading">{{ loading ? t('binding') : t('bind') }}</el-button>
  24. </el-form-item>
  25. </el-form>
  26. </div>
  27. </div>
  28. </div>
  29. </template>
  30. <script lang="ts" setup>
  31. import { ref, reactive, computed } from 'vue'
  32. import { bind } from '@/app/api/auth'
  33. import { bindMobile } from '@/app/api/member'
  34. import useMemberStore from '@/stores/member'
  35. import { FormInstance } from 'element-plus'
  36. import { useRouter } from 'vue-router'
  37. definePageMeta({
  38. layout: "container"
  39. });
  40. let router = useRouter()
  41. const memberStore = useMemberStore()
  42. const info = computed(() => memberStore.info)
  43. const loading = ref(false)
  44. const formData = reactive({
  45. mobile: '',
  46. mobile_code: '',
  47. mobile_key: '',
  48. openid: useCookie('openId').value
  49. })
  50. const formRules = computed(() => {
  51. return {
  52. 'mobile': [
  53. {
  54. type: 'string',
  55. required: true,
  56. message: t('mobilePlaceholder'),
  57. trigger: ['blur', 'change'],
  58. },
  59. {
  60. validator(rule: any, value: string, callback: any) {
  61. return test.mobile(value)
  62. },
  63. message: t('mobileError'),
  64. trigger: ['change', 'blur'],
  65. }
  66. ],
  67. 'mobile_code': {
  68. type: 'string',
  69. required: true,
  70. message: t('codePlaceholder'),
  71. trigger: ['blur', 'change']
  72. }
  73. }
  74. })
  75. const formRef = ref<FormInstance>()
  76. const handleRegister = async () => {
  77. await formRef.value?.validate(async (valid, fields) => {
  78. if (valid) {
  79. if (loading.value) return
  80. loading.value = true
  81. const request = info.value ? bindMobile : bind
  82. request(formData).then((res: responseResult) => {
  83. memberStore.setToken(res.data.token)
  84. router.push({ path: '/' })
  85. }).catch(() => {
  86. loading.value = false
  87. captcha.refresh()
  88. })
  89. }
  90. })
  91. }
  92. // 验证码
  93. const captcha = useCaptcha(formData)
  94. captcha.refresh()
  95. // 获取手机验证码
  96. const smsCodeRef = ref<AnyObject | null>(null)
  97. const sendSmsCode = async () => {
  98. await formRef.value?.validateField('mobile', async (valid, fields) => {
  99. if (valid) {
  100. smsCodeRef.value?.send()
  101. }
  102. })
  103. }
  104. </script>
  105. <style lang="scss" scoped>
  106. :deep(.el-form-item) {
  107. .el-input__wrapper {
  108. box-shadow: unset !important;
  109. border-radius: 0;
  110. border-bottom: 1px solid var(--el-input-border-color);
  111. padding: 8px 0;
  112. &.is-focus {
  113. border-bottom: 1px solid var(--el-input-focus-border-color);
  114. }
  115. }
  116. &.is-error {
  117. .el-input__wrapper {
  118. border-bottom: 1px solid var(--el-color-danger);
  119. }
  120. }
  121. }
  122. :deep(.el-form-item__error) {
  123. padding-top: 5px;
  124. }
  125. </style>