Files
hfb_sys/frontend/src/views/mobile/MobileRealnameView.vue
T
2026-05-22 22:02:45 +08:00

250 lines
5.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { showToast, showDialog } from "vant";
import {
getRealnameStatus,
startRealname,
type RealnameStatus,
} from "@/api/realname";
import { useSessionStore } from "@/stores/session";
const session = useSessionStore();
const router = useRouter();
const loading = ref(false);
const status = ref<RealnameStatus | null>(null);
const form = reactive({
name: "",
idNo: "",
});
onMounted(loadStatus);
async function loadStatus() {
if (!session.token) return;
try {
status.value = await getRealnameStatus();
} catch {
status.value = null;
}
}
async function handleSubmit() {
if (!form.name.trim()) {
showToast({ message: "请输入真实姓名", icon: "warning-o" });
return;
}
if (!form.idNo.trim() || form.idNo.length < 15) {
showToast({ message: "请输入有效的证件号", icon: "warning-o" });
return;
}
loading.value = true;
try {
status.value = await startRealname(form.name, form.idNo);
await session.loadMe();
showDialog({
title: "认证成功",
message: "实名认证已通过",
confirmButtonText: "好的",
});
} catch (error: unknown) {
const msg =
typeof error === "object" && error && "response" in error
? (
error as {
response?: { data?: { message?: string } };
}
).response?.data?.message || "实名认证失败"
: "实名认证失败";
showToast({ message: msg, icon: "cross" });
} finally {
loading.value = false;
}
}
</script>
<template>
<main class="mobile-realname">
<header class="page-header">
<button class="back-btn" @click="router.back()">
<van-icon name="arrow-left" :size="20" />
</button>
<h1>实名认证</h1>
<span class="header-spacer"></span>
</header>
<!-- 未登录提示 -->
<van-empty
v-if="!session.token"
description="请先登录后再实名认证"
image="search"
/>
<template v-else>
<!-- 认证状态 -->
<section v-if="status" class="status-card">
<div class="status-row">
<span class="status-label">当前状态</span>
<van-tag
:type="status.status === 'verified' ? 'success' : 'warning'"
size="medium"
round
>
{{ status.status === "verified" ? "已认证" : status.status }}
</van-tag>
</div>
<p v-if="status.masked_name" class="status-detail">
姓名{{ status.masked_name }}
</p>
<p v-if="status.masked_id_no" class="status-detail">
证件号{{ status.masked_id_no }}
</p>
<p v-if="status.verified_at" class="status-detail">
通过时间{{ status.verified_at }}
</p>
</section>
<!-- 认证表单 -->
<section v-if="status?.status !== 'verified'" class="form-card">
<h2>提交认证</h2>
<p class="form-hint">
号主发布前必须完成实名认证提交合法姓名和身份证号即可认证
</p>
<van-field
v-model="form.name"
label="姓名"
placeholder="请输入真实姓名"
clearable
class="realname-field"
/>
<van-field
v-model="form.idNo"
label="身份证号"
placeholder="请输入18位身份证号"
maxlength="18"
clearable
class="realname-field"
/>
<van-button
type="primary"
block
round
:loading="loading"
class="submit-btn"
@click="handleSubmit"
>
提交认证
</van-button>
</section>
</template>
</main>
</template>
<style scoped>
.mobile-realname {
min-height: 100dvh;
background: #f5f7fa;
padding-bottom: 20px;
}
/* ========== 顶部导航 ========== */
.page-header {
position: sticky;
top: 0;
z-index: 10;
display: flex;
align-items: center;
height: 48px;
padding: 0 12px;
background: #fff;
border-bottom: 1px solid #eee;
}
.page-header h1 {
flex: 1;
margin: 0;
font-size: 17px;
font-weight: 700;
text-align: center;
}
.back-btn {
display: grid;
width: 36px;
height: 36px;
place-items: center;
border: none;
background: none;
color: #333;
cursor: pointer;
}
.header-spacer {
width: 36px;
}
/* ========== 认证状态 ========== */
.status-card {
margin: 16px 12px;
padding: 16px;
border-radius: 16px;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.status-row {
display: flex;
align-items: center;
justify-content: space-between;
}
.status-label {
font-size: 15px;
font-weight: 700;
color: #1a202c;
}
.status-detail {
margin: 8px 0 0;
font-size: 13px;
color: #666;
}
/* ========== 认证表单 ========== */
.form-card {
margin: 0 12px 16px;
padding: 18px 16px;
border-radius: 16px;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.form-card h2 {
margin: 0 0 6px;
font-size: 17px;
font-weight: 700;
}
.form-hint {
margin: 0 0 16px;
font-size: 13px;
color: #999;
line-height: 1.5;
}
.realname-field {
margin-bottom: 12px;
border-radius: 10px;
overflow: hidden;
}
.submit-btn {
margin-top: 8px;
background: #1477ff;
border-color: transparent;
font-weight: 800;
height: 44px;
font-size: 16px;
}
</style>