增加手机号短信验证查询逻辑
This commit is contained in:
@@ -13,13 +13,10 @@
|
||||
<el-form-item v-if="queryMode === 'certificate'" label="证书编号">
|
||||
<el-input v-model.trim="form.certificateNo" placeholder="例如 PX2026-DBY-K7M9Q2R-83" />
|
||||
</el-form-item>
|
||||
<el-form-item v-else label="手机号">
|
||||
<el-input v-model.trim="form.phone" placeholder="请输入证书对应手机号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名">
|
||||
<el-form-item v-if="queryMode === 'certificate'" label="姓名">
|
||||
<el-input v-model.trim="form.name" placeholder="请输入证书对应姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图形验证码">
|
||||
<el-form-item v-if="queryMode === 'certificate'" label="图形验证码">
|
||||
<div class="captcha-row">
|
||||
<el-input v-model.trim="form.captcha" placeholder="请输入验证码" />
|
||||
<button class="captcha-button" type="button" @click="loadCaptcha">
|
||||
@@ -28,6 +25,31 @@
|
||||
</button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="queryMode === 'sms'" label="手机号">
|
||||
<el-input v-model.trim="form.phone" placeholder="请输入证书对应手机号" />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="queryMode === 'sms'" label="图形验证码">
|
||||
<div class="captcha-row">
|
||||
<el-input v-model.trim="form.smsCaptcha" placeholder="请输入验证码" />
|
||||
<button class="captcha-button" type="button" @click="loadSmsCaptcha">
|
||||
<img v-if="smsCaptchaImage" :src="smsCaptchaImage" alt="验证码" />
|
||||
<span v-else>刷新</span>
|
||||
</button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="queryMode === 'sms'" label="短信验证码">
|
||||
<div class="sms-row">
|
||||
<el-input v-model.trim="form.smsCode" placeholder="请输入短信验证码" />
|
||||
<el-button
|
||||
type="primary"
|
||||
:disabled="smsCooldown > 0 || !form.phone"
|
||||
@click="sendSmsCode"
|
||||
:loading="sendingSms"
|
||||
>
|
||||
{{ smsCooldown > 0 ? `${smsCooldown}秒后重试` : '获取验证码' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-button type="primary" class="submit" :loading="loading" @click="submitQuery">查询</el-button>
|
||||
</el-form>
|
||||
|
||||
@@ -111,7 +133,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref, watch } from "vue";
|
||||
import { onMounted, onUnmounted, reactive, ref, watch } from "vue";
|
||||
|
||||
import { http, type Captcha, type PublicCertificate } from "../api";
|
||||
|
||||
@@ -121,13 +143,15 @@ interface SearchResponse {
|
||||
|
||||
const queryOptions = [
|
||||
{ label: "证书编号查询", value: "certificate" },
|
||||
{ label: "手机号查询", value: "phone" },
|
||||
{ label: "短信验证码查询", value: "sms" },
|
||||
];
|
||||
|
||||
const queryMode = ref<"certificate" | "phone">("certificate");
|
||||
const form = reactive({ certificateNo: "", phone: "", name: "", captcha: "" });
|
||||
const queryMode = ref<"certificate" | "sms">("certificate");
|
||||
const form = reactive({ certificateNo: "", phone: "", name: "", captcha: "", smsCaptcha: "", smsCode: "" });
|
||||
const captchaId = ref("");
|
||||
const captchaImage = ref("");
|
||||
const smsCaptchaId = ref("");
|
||||
const smsCaptchaImage = ref("");
|
||||
const loading = ref(false);
|
||||
const message = ref("");
|
||||
const messageType = ref<"success" | "warning" | "error">("warning");
|
||||
@@ -135,6 +159,10 @@ const results = ref<PublicCertificate[]>([]);
|
||||
const previewVisible = ref(false);
|
||||
const current = ref<PublicCertificate | null>(null);
|
||||
const previewPdfUrl = ref("");
|
||||
const smsId = ref("");
|
||||
const sendingSms = ref(false);
|
||||
const smsCooldown = ref(0);
|
||||
let smsTimer: number | null = null;
|
||||
|
||||
function statusText(status: string) {
|
||||
return status === "valid" ? "有效" : "已作废";
|
||||
@@ -147,6 +175,9 @@ function courseText(item: PublicCertificate) {
|
||||
watch(queryMode, () => {
|
||||
message.value = "";
|
||||
results.value = [];
|
||||
if (queryMode.value === "sms") {
|
||||
loadSmsCaptcha();
|
||||
}
|
||||
});
|
||||
|
||||
async function loadCaptcha() {
|
||||
@@ -156,18 +187,86 @@ async function loadCaptcha() {
|
||||
form.captcha = "";
|
||||
}
|
||||
|
||||
async function loadSmsCaptcha() {
|
||||
const { data } = await http.get<Captcha>("/public/captcha");
|
||||
smsCaptchaId.value = data.captcha_id;
|
||||
smsCaptchaImage.value = data.image;
|
||||
form.smsCaptcha = "";
|
||||
}
|
||||
|
||||
async function sendSmsCode() {
|
||||
if (!form.phone) {
|
||||
message.value = "请先输入手机号";
|
||||
messageType.value = "warning";
|
||||
return;
|
||||
}
|
||||
|
||||
sendingSms.value = true;
|
||||
message.value = "";
|
||||
|
||||
try {
|
||||
const { data } = await http.post<{ sms_id: string; message: string }>("/public/sms/send", {
|
||||
phone: form.phone,
|
||||
captcha_id: smsCaptchaId.value,
|
||||
captcha_code: form.smsCaptcha,
|
||||
});
|
||||
smsId.value = data.sms_id;
|
||||
message.value = data.message;
|
||||
messageType.value = "success";
|
||||
|
||||
// 开始倒计时
|
||||
smsCooldown.value = 60;
|
||||
if (smsTimer) clearInterval(smsTimer);
|
||||
smsTimer = window.setInterval(() => {
|
||||
smsCooldown.value--;
|
||||
if (smsCooldown.value <= 0) {
|
||||
if (smsTimer) clearInterval(smsTimer);
|
||||
smsTimer = null;
|
||||
}
|
||||
}, 1000);
|
||||
} catch (error: any) {
|
||||
message.value = error?.response?.data?.detail || "发送失败,请稍后再试";
|
||||
messageType.value = "error";
|
||||
await loadSmsCaptcha();
|
||||
} finally {
|
||||
sendingSms.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function submitQuery() {
|
||||
loading.value = true;
|
||||
message.value = "";
|
||||
results.value = [];
|
||||
|
||||
try {
|
||||
const { data } = await http.post<SearchResponse>("/public/certificates/search", {
|
||||
certificate_no: queryMode.value === "certificate" ? form.certificateNo : null,
|
||||
phone: queryMode.value === "phone" ? form.phone : null,
|
||||
name: form.name,
|
||||
captcha_id: captchaId.value,
|
||||
captcha_code: form.captcha,
|
||||
});
|
||||
let data: SearchResponse;
|
||||
|
||||
if (queryMode.value === "certificate") {
|
||||
// 证书编号查询
|
||||
const response = await http.post<SearchResponse>("/public/certificates/search", {
|
||||
certificate_no: form.certificateNo,
|
||||
phone: null,
|
||||
name: form.name,
|
||||
captcha_id: captchaId.value,
|
||||
captcha_code: form.captcha,
|
||||
});
|
||||
data = response.data;
|
||||
} else {
|
||||
// 短信验证码查询
|
||||
if (!smsId.value) {
|
||||
message.value = "请先获取短信验证码";
|
||||
messageType.value = "warning";
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await http.post<SearchResponse>("/public/certificates/search-by-sms", {
|
||||
phone: form.phone,
|
||||
sms_id: smsId.value,
|
||||
sms_code: form.smsCode,
|
||||
});
|
||||
data = response.data;
|
||||
}
|
||||
|
||||
results.value = data.items;
|
||||
const hasVoided = data.items.some((item) => item.status !== "valid");
|
||||
message.value = hasVoided ? "已查询到证书,其中包含作废证书,请核对状态。" : "已查询到匹配证书。";
|
||||
@@ -175,7 +274,9 @@ async function submitQuery() {
|
||||
} catch (error: any) {
|
||||
message.value = error?.response?.data?.detail || "查询失败,请稍后再试";
|
||||
messageType.value = "error";
|
||||
await loadCaptcha();
|
||||
if (queryMode.value === "certificate") {
|
||||
await loadCaptcha();
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
@@ -208,6 +309,14 @@ function downloadPdf(item: PublicCertificate) {
|
||||
}
|
||||
|
||||
onMounted(loadCaptcha);
|
||||
|
||||
// 清理定时器
|
||||
onUnmounted(() => {
|
||||
if (smsTimer) {
|
||||
clearInterval(smsTimer);
|
||||
smsTimer = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -258,6 +367,13 @@ h1 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sms-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 120px;
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.captcha-button {
|
||||
height: 34px;
|
||||
padding: 0;
|
||||
|
||||
Reference in New Issue
Block a user