add ali captcha
This commit is contained in:
@@ -461,6 +461,7 @@ import { useDialogStore } from "@/stores/dialogStore";
|
||||
import { useEnv } from "@/composables/useEnv";
|
||||
import { showConfirmDialog, showToast, DatePicker } from "vant";
|
||||
import { useInquireForm } from "@/composables/useInquireForm";
|
||||
import { useAliyunCaptcha } from "@/composables/useAliyunCaptcha";
|
||||
|
||||
import Payment from "@/components/Payment.vue";
|
||||
import BindPhoneDialog from "@/components/BindPhoneDialog.vue";
|
||||
@@ -557,6 +558,7 @@ const featureData = computed(() => props.featureData || {});
|
||||
|
||||
// 使用通用查询表单 composable(根据 feature 自动决定字段)
|
||||
const { formData, isPhoneNumberValid, isIdCardValid, isHasInput, buildRequestPayload } = useInquireForm(feature);
|
||||
const { runWithCaptcha } = useAliyunCaptcha();
|
||||
|
||||
const userTypeOptions = [
|
||||
{ text: "ETC开户人", value: "1" },
|
||||
@@ -998,69 +1000,77 @@ function handleSubmit() {
|
||||
if (!userStore.mobile) {
|
||||
pendingPayment.value = true;
|
||||
dialogStore.openBindPhone();
|
||||
} else {
|
||||
} else if (isHasInput("verificationCode")) {
|
||||
submitRequest();
|
||||
} else {
|
||||
// 无短信验证码时,查询前先过滑块
|
||||
runWithCaptcha(
|
||||
(captchaVerifyParam) => doQueryPost(captchaVerifyParam),
|
||||
(res) => {
|
||||
if (res?.code === 200 && res?.data) handleQueryResult(res);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function submitRequest() {
|
||||
// 根据当前 feature 与字段配置组装请求体
|
||||
function handleQueryResult(res) {
|
||||
queryId.value = res.data.id;
|
||||
if (props.type === "promotion") {
|
||||
localStorage.setItem("token", res.data.accessToken);
|
||||
localStorage.setItem("refreshAfter", res.data.refreshAfter);
|
||||
localStorage.setItem("accessExpire", res.data.accessExpire);
|
||||
}
|
||||
showPayment.value = true;
|
||||
emit("submit-success", res.data);
|
||||
}
|
||||
|
||||
function doQueryPost(captchaVerifyParam) {
|
||||
const req = buildRequestPayload();
|
||||
const reqStr = JSON.stringify(req);
|
||||
const encodeData = aesEncrypt(reqStr, "ff83609b2b24fc73196aac3d3dfb874f");
|
||||
|
||||
let apiUrl = '';
|
||||
let requestData = { data: encodeData };
|
||||
|
||||
if (props.type === 'promotion') {
|
||||
let apiUrl = "";
|
||||
const requestData = { data: encodeData };
|
||||
if (captchaVerifyParam) requestData.captchaVerifyParam = captchaVerifyParam;
|
||||
if (props.type === "promotion") {
|
||||
apiUrl = `/query/service_agent/${props.feature}`;
|
||||
requestData.agent_identifier = props.linkIdentifier;
|
||||
} else {
|
||||
apiUrl = `/query/service/${props.feature}`;
|
||||
}
|
||||
return useApiFetch(apiUrl).post(requestData).json();
|
||||
}
|
||||
|
||||
const { data, error } = await useApiFetch(apiUrl)
|
||||
.post(requestData)
|
||||
.json();
|
||||
|
||||
if (data.value.code === 200) {
|
||||
queryId.value = data.value.data.id;
|
||||
|
||||
// 推广查询需要保存token
|
||||
if (props.type === 'promotion') {
|
||||
localStorage.setItem("token", data.value.data.accessToken);
|
||||
localStorage.setItem("refreshAfter", data.value.data.refreshAfter);
|
||||
localStorage.setItem("accessExpire", data.value.data.accessExpire);
|
||||
}
|
||||
|
||||
showPayment.value = true;
|
||||
emit('submit-success', data.value.data);
|
||||
async function submitRequest() {
|
||||
const { data, error } = await doQueryPost();
|
||||
if (data.value?.code === 200 && data.value?.data) {
|
||||
handleQueryResult(data.value);
|
||||
}
|
||||
}
|
||||
|
||||
async function sendVerificationCode() {
|
||||
function sendVerificationCode() {
|
||||
if (isCountingDown.value || !isPhoneNumberValid.value) return;
|
||||
if (!isPhoneNumberValid.value) {
|
||||
showToast({ message: "请输入有效的手机号" });
|
||||
return;
|
||||
}
|
||||
|
||||
const { data, error } = await useApiFetch("/auth/sendSms")
|
||||
.post({ mobile: formData.mobile, actionType: "query" })
|
||||
.json();
|
||||
|
||||
if (!error.value && data.value.code === 200) {
|
||||
showToast({ message: "验证码发送成功", type: "success" });
|
||||
startCountdown();
|
||||
nextTick(() => {
|
||||
const verificationCodeInput = document.getElementById('verificationCode');
|
||||
if (verificationCodeInput) {
|
||||
verificationCodeInput.focus();
|
||||
runWithCaptcha(
|
||||
(captchaVerifyParam) =>
|
||||
useApiFetch("/auth/sendSms")
|
||||
.post({ mobile: formData.mobile, actionType: "query", captchaVerifyParam })
|
||||
.json(),
|
||||
(res) => {
|
||||
if (res?.code === 200) {
|
||||
showToast({ message: "验证码发送成功", type: "success" });
|
||||
startCountdown();
|
||||
nextTick(() => {
|
||||
const el = document.getElementById("verificationCode");
|
||||
if (el) el.focus();
|
||||
});
|
||||
} else {
|
||||
showToast({ message: res?.msg || "验证码发送失败,请重试" });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showToast({ message: "验证码发送失败,请重试" });
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let timer = null;
|
||||
|
||||
@@ -3,10 +3,12 @@ import { ref, computed, nextTick } from 'vue'
|
||||
import { showToast } from 'vant'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import { useUserStore } from '@/stores/userStore'
|
||||
import { useAliyunCaptcha } from '@/composables/useAliyunCaptcha'
|
||||
|
||||
const emit = defineEmits(['login-success'])
|
||||
const dialogStore = useDialogStore()
|
||||
const userStore = useUserStore()
|
||||
const { runWithCaptcha } = useAliyunCaptcha()
|
||||
|
||||
const phoneNumber = ref('')
|
||||
const verificationCode = ref('')
|
||||
@@ -35,31 +37,30 @@ const canLogin = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
async function sendVerificationCode() {
|
||||
function sendVerificationCode() {
|
||||
if (isCountingDown.value || !isPhoneNumberValid.value) return
|
||||
if (!isPhoneNumberValid.value) {
|
||||
showToast({ message: "请输入有效的手机号" });
|
||||
return
|
||||
}
|
||||
const { data, error } = await useApiFetch('auth/sendSms')
|
||||
.post({ mobile: phoneNumber.value, actionType: 'login' })
|
||||
.json()
|
||||
|
||||
if (data.value && !error.value) {
|
||||
if (data.value.code === 200) {
|
||||
showToast({ message: "获取成功" });
|
||||
startCountdown()
|
||||
// 聚焦到验证码输入框
|
||||
nextTick(() => {
|
||||
const verificationCodeInput = document.getElementById('verificationCode');
|
||||
if (verificationCodeInput) {
|
||||
verificationCodeInput.focus();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showToast(data.value.msg)
|
||||
runWithCaptcha(
|
||||
(captchaVerifyParam) =>
|
||||
useApiFetch('auth/sendSms')
|
||||
.post({ mobile: phoneNumber.value, actionType: 'login', captchaVerifyParam })
|
||||
.json(),
|
||||
(res) => {
|
||||
if (res?.code === 200) {
|
||||
showToast({ message: "获取成功" });
|
||||
startCountdown();
|
||||
nextTick(() => {
|
||||
const el = document.getElementById('verificationCode');
|
||||
if (el) el.focus();
|
||||
});
|
||||
} else {
|
||||
showToast(res?.msg || "获取失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function startCountdown() {
|
||||
@@ -95,31 +96,17 @@ async function handleLogin() {
|
||||
showToast({ message: "请先同意用户协议" });
|
||||
return
|
||||
}
|
||||
// 直接执行登录逻辑
|
||||
await performLogin()
|
||||
}
|
||||
|
||||
// 执行实际的登录逻辑
|
||||
async function performLogin() {
|
||||
const { data, error } = await useApiFetch('/user/mobileCodeLogin')
|
||||
.post({ mobile: phoneNumber.value, code: verificationCode.value })
|
||||
.json()
|
||||
|
||||
if (data.value && !error.value) {
|
||||
if (data.value.code === 200) {
|
||||
localStorage.setItem('token', data.value.data.accessToken)
|
||||
localStorage.setItem('refreshAfter', data.value.data.refreshAfter)
|
||||
localStorage.setItem('accessExpire', data.value.data.accessExpire)
|
||||
|
||||
// 更新用户信息
|
||||
await userStore.fetchUserInfo()
|
||||
|
||||
showToast({ message: "登录成功" });
|
||||
closeDialog();
|
||||
emit('login-success');
|
||||
} else {
|
||||
showToast(data.value.msg);
|
||||
}
|
||||
.json();
|
||||
if (data.value && !error.value && data.value.code === 200 && data.value.data) {
|
||||
localStorage.setItem('token', data.value.data.accessToken);
|
||||
localStorage.setItem('refreshAfter', data.value.data.refreshAfter);
|
||||
localStorage.setItem('accessExpire', data.value.data.accessExpire);
|
||||
await userStore.fetchUserInfo();
|
||||
showToast({ message: "登录成功" });
|
||||
closeDialog();
|
||||
emit('login-success');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user