| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- <!-- src/views/captcha/CaptchaPage.vue -->
- <template>
- <div class="captcha-page">
- <div class="container">
- <!-- 表单区域 -->
- <div class="form-group">
- <label for="phone">手机号</label>
- <input
- v-model="form.phone"
- type="tel"
- id="phone"
- placeholder="请输入手机号"
- maxlength="11"
- />
- </div>
-
- <!-- 验证码显示区域 -->
- <div id="captcha-container" class="captcha-container"></div>
-
- <div class="form-group">
- <label for="smsCode">短信验证码</label>
- <div class="sms-input-group">
- <input
- v-model="form.smsCode"
- type="text"
- id="smsCode"
- placeholder="请输入短信验证码"
- maxlength="6"
- />
- <button
- class="get-sms-btn"
- :disabled="smsCountdown > 0 || !isPhoneValid"
- @click="getSmsCode"
- >
- {{ smsCountdown > 0 ? `${smsCountdown}s后重试` : '获取验证码' }}
- </button>
- </div>
- </div>
-
- <button
- class="submit-btn"
- :disabled="!isFormValid || isSubmitting"
- @click="handleSubmit"
- >
- {{ isSubmitting ? '提交中...' : '绑定手机号' }}
- </button>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, computed, onMounted, onUnmounted } from 'vue'
- import { tijiao } from '@/api/login.js' // 直接使用你的API
- import { toast } from '@/utils/common'
- // 表单数据
- const form = ref({
- phone: '',
- smsCode: ''
- })
- // 状态管理
- const captchaVerifyParam = ref(null)
- const isSubmitting = ref(false)
- const smsCountdown = ref(0)
- let countdownTimer = null
- // 计算属性
- const isPhoneValid = computed(() => {
- const phone = form.value.phone
- return /^1[3-9]\d{9}$/.test(phone)
- })
- const isFormValid = computed(() => {
- return isPhoneValid.value &&
- form.value.smsCode.length === 6 &&
- captchaVerifyParam.value
- })
- // 生命周期
- onMounted(() => {
- loadAliyunCaptcha()
- })
- onUnmounted(() => {
- if (countdownTimer) {
- clearInterval(countdownTimer)
- }
- })
- // 加载阿里云验证码
- function loadAliyunCaptcha() {
- // 动态加载阿里云验证码脚本
- const script = document.createElement('script')
- script.src = 'https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js'
- script.onload = () => {
- initCaptcha()
- }
- script.onerror = () => {
- toast('验证码加载失败,请重试')
- }
- document.head.appendChild(script)
- }
- // 初始化验证码
- function initCaptcha() {
- window.AliyunCaptchaConfig = {
- region: 'cn',
- prefix: 'm9a704',
- }
- try {
- window.initAliyunCaptcha({
- SceneId: '1xp14eyl',
- mode: "embed",
- element: "#captcha-container",
- success: (param) => {
- captchaVerifyParam.value = param
- console.log('验证码验证成功:', param)
- },
- fail: (err) => {
- toast('验证失败,请重试')
- console.error('验证码验证失败:', err)
- },
- slideStyle: {
- width: 320,
- height: 40
- },
- language: 'cn',
- timeout: 5000,
- })
- } catch (error) {
- console.error('初始化验证码失败:', error)
- toast('验证码初始化失败')
- }
- }
- // 获取短信验证码
- async function getSmsCode() {
- if (!isPhoneValid.value) {
- toast('请输入正确的手机号')
- return
- }
- try {
- // 这里调用你的短信接口
- const response = await tijiao({
- phone: form.value.phone,
- captchaVerifyParam: captchaVerifyParam.value,
- type: 'sms'
- })
-
- if (response.code === 0) {
- toast('验证码已发送')
- startSmsCountdown()
- } else {
- toast(response.msg || '发送失败')
- }
- } catch (error) {
- console.error('获取短信验证码失败:', error)
- toast('发送失败,请重试')
- }
- }
- // 开始短信倒计时
- function startSmsCountdown() {
- smsCountdown.value = 60
- countdownTimer = setInterval(() => {
- smsCountdown.value--
- if (smsCountdown.value <= 0) {
- clearInterval(countdownTimer)
- countdownTimer = null
- }
- }, 1000)
- }
- // 提交表单
- async function handleSubmit() {
- if (!isFormValid.value || isSubmitting.value) return
- isSubmitting.value = true
- try {
- const params = {
- phone: form.value.phone,
- smsCode: form.value.smsCode,
- captchaVerifyParam: captchaVerifyParam.value
- }
- // 直接使用你项目中的API
- const response = await tijiao(params)
-
- if (response.code === 0) {
- toast('绑定成功')
-
- // 通知uniapp页面
- if (window.uni && uni.postMessage) {
- uni.postMessage({
- data: {
- status: 'success',
- phone: form.value.phone,
- captchaResult: captchaVerifyParam.value,
- userInfo: response.data // 如果有用户信息
- }
- })
- }
-
- // 延迟返回,确保消息传递
- setTimeout(() => {
- if (window.uni && uni.navigateBack) {
- uni.navigateBack()
- }
- }, 1000)
- } else {
- toast(response.msg || '绑定失败')
- }
- } catch (error) {
- console.error('绑定失败:', error)
- toast('绑定失败,请重试')
- } finally {
- isSubmitting.value = false
- }
- }
- </script>
- <style scoped>
- .captcha-page {
- height: 100vh;
- display: flex;
- align-items: center;
- justify-content: center;
- background: #f5f5f5;
- }
- .container {
- width: 90%;
- max-width: 400px;
- background: white;
- padding: 30px;
- border-radius: 10px;
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
- }
- .form-group {
- margin-bottom: 20px;
- }
- .form-group label {
- display: block;
- margin-bottom: 8px;
- font-weight: bold;
- color: #333;
- }
- .form-group input {
- width: 100%;
- padding: 10px;
- border: 1px solid #ddd;
- border-radius: 5px;
- box-sizing: border-box;
- }
- .sms-input-group {
- display: flex;
- gap: 10px;
- }
- .sms-input-group input {
- flex: 1;
- }
- .get-sms-btn {
- padding: 10px 15px;
- background: #007aff;
- color: white;
- border: none;
- border-radius: 5px;
- cursor: pointer;
- white-space: nowrap;
- }
- .get-sms-btn:disabled {
- background: #ccc;
- cursor: not-allowed;
- }
- .captcha-container {
- margin: 20px 0;
- min-height: 100px;
- }
- .submit-btn {
- width: 100%;
- padding: 12px;
- background: #07c160;
- color: white;
- border: none;
- border-radius: 5px;
- font-size: 16px;
- cursor: pointer;
- }
- .submit-btn:disabled {
- background: #ccc;
- cursor: not-allowed;
- }
- .submit-btn:hover:not(:disabled) {
- background: #06ae56;
- }
- </style>
|