发布前校验是否实名认证

This commit is contained in:
yml
2026-05-23 00:01:03 +08:00
parent 94edda9710
commit efb3b94286
5 changed files with 62 additions and 5 deletions
+1
View File
@@ -38,6 +38,7 @@ apiClient.interceptors.response.use(
localStorage.removeItem('access_token') localStorage.removeItem('access_token')
localStorage.removeItem('refresh_token') localStorage.removeItem('refresh_token')
localStorage.removeItem('user_id') localStorage.removeItem('user_id')
localStorage.removeItem('realname_status')
if (!window.location.pathname.startsWith('/m/login') && !window.location.pathname.startsWith('/m/register')) { if (!window.location.pathname.startsWith('/m/login') && !window.location.pathname.startsWith('/m/register')) {
const redirect = encodeURIComponent(currentPath) const redirect = encodeURIComponent(currentPath)
+20 -2
View File
@@ -1,5 +1,6 @@
import { createRouter, createWebHistory } from "vue-router"; import { createRouter, createWebHistory } from "vue-router";
import { useSessionStore } from "@/stores/session";
import { isMobileHost, toMobilePath } from "./mobileHost"; import { isMobileHost, toMobilePath } from "./mobileHost";
const router = createRouter({ const router = createRouter({
@@ -65,7 +66,7 @@ const router = createRouter({
name: "mobile-seller-listing-create", name: "mobile-seller-listing-create",
component: () => component: () =>
import("@/views/mobile/MobileSellerListingCreateView.vue"), import("@/views/mobile/MobileSellerListingCreateView.vue"),
meta: { layout: "blank", requiresAuth: true }, meta: { layout: "blank", requiresAuth: true, requiresRealname: true },
}, },
{ {
path: "/", path: "/",
@@ -212,7 +213,7 @@ const router = createRouter({
], ],
}); });
router.beforeEach((to) => { router.beforeEach(async (to) => {
if (isMobileHost() && to.path !== toMobilePath(to.path)) { if (isMobileHost() && to.path !== toMobilePath(to.path)) {
return { path: toMobilePath(to.path), query: to.query, hash: to.hash }; return { path: toMobilePath(to.path), query: to.query, hash: to.hash };
} }
@@ -221,6 +222,23 @@ router.beforeEach((to) => {
return { path: "/m/login", query: { redirect: to.fullPath } }; return { path: "/m/login", query: { redirect: to.fullPath } };
} }
if (to.meta.requiresRealname) {
const session = useSessionStore();
if (session.realnameStatus !== "verified") {
try {
await session.loadMe();
} catch {
if (!localStorage.getItem("access_token")) {
return { path: "/m/login", query: { redirect: to.fullPath } };
}
}
}
if (session.realnameStatus !== "verified") {
return { path: "/m/realname", query: { redirect: to.fullPath } };
}
}
if ( if (
to.path === "/admin/login" && to.path === "/admin/login" &&
localStorage.getItem("admin_access_token") localStorage.getItem("admin_access_token")
+3 -1
View File
@@ -8,7 +8,7 @@ export const useSessionStore = defineStore('session', {
refreshToken: localStorage.getItem('refresh_token') || '', refreshToken: localStorage.getItem('refresh_token') || '',
userId: Number(localStorage.getItem('user_id') || 0), userId: Number(localStorage.getItem('user_id') || 0),
phone: '', phone: '',
realnameStatus: 'unknown', realnameStatus: localStorage.getItem('realname_status') || 'unknown',
}), }),
actions: { actions: {
async login(phone: string, code: string) { async login(phone: string, code: string) {
@@ -30,6 +30,7 @@ export const useSessionStore = defineStore('session', {
localStorage.removeItem('access_token') localStorage.removeItem('access_token')
localStorage.removeItem('refresh_token') localStorage.removeItem('refresh_token')
localStorage.removeItem('user_id') localStorage.removeItem('user_id')
localStorage.removeItem('realname_status')
}, },
applySession(user: AuthUser, accessToken: string, refreshToken: string) { applySession(user: AuthUser, accessToken: string, refreshToken: string) {
this.token = accessToken this.token = accessToken
@@ -45,6 +46,7 @@ export const useSessionStore = defineStore('session', {
localStorage.setItem('user_id', String(user.id)) localStorage.setItem('user_id', String(user.id))
this.phone = user.phone this.phone = user.phone
this.realnameStatus = user.realname_status this.realnameStatus = user.realname_status
localStorage.setItem('realname_status', user.realname_status)
}, },
}, },
}) })
@@ -44,7 +44,28 @@ async function handleCreateOrder() {
cancelButtonText: "取消", cancelButtonText: "取消",
showCancelButton: true, showCancelButton: true,
}).then(() => { }).then(() => {
router.push("/m/login"); router.push({ path: "/m/login", query: { redirect: route.fullPath } });
});
return;
}
if (session.realnameStatus !== "verified") {
try {
await session.loadMe();
} catch {
// 401 会由全局拦截器处理。
}
}
if (session.realnameStatus !== "verified") {
showDialog({
title: "请先实名认证",
message: "租号下单前需要完成实名认证。",
confirmButtonText: "去认证",
cancelButtonText: "取消",
showCancelButton: true,
}).then(() => {
router.push({ path: "/m/realname", query: { redirect: route.fullPath } });
}); });
return; return;
} }
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, reactive, ref } from "vue"; import { onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import { showToast, showDialog } from "vant"; import { showToast, showDialog } from "vant";
import { import {
getRealnameStatus, getRealnameStatus,
@@ -11,6 +11,7 @@ import { useSessionStore } from "@/stores/session";
const session = useSessionStore(); const session = useSessionStore();
const router = useRouter(); const router = useRouter();
const route = useRoute();
const loading = ref(false); const loading = ref(false);
const status = ref<RealnameStatus | null>(null); const status = ref<RealnameStatus | null>(null);
const form = reactive({ const form = reactive({
@@ -20,10 +21,22 @@ const form = reactive({
onMounted(loadStatus); onMounted(loadStatus);
function redirectAfterVerified() {
const redirect =
typeof route.query.redirect === "string" ? route.query.redirect : "";
if (redirect) {
router.replace(redirect);
}
}
async function loadStatus() { async function loadStatus() {
if (!session.token) return; if (!session.token) return;
try { try {
status.value = await getRealnameStatus(); status.value = await getRealnameStatus();
if (status.value.status === "verified") {
await session.loadMe();
redirectAfterVerified();
}
} catch { } catch {
status.value = null; status.value = null;
} }
@@ -46,6 +59,8 @@ async function handleSubmit() {
title: "认证成功", title: "认证成功",
message: "实名认证已通过", message: "实名认证已通过",
confirmButtonText: "好的", confirmButtonText: "好的",
}).then(() => {
redirectAfterVerified();
}); });
} catch (error: unknown) { } catch (error: unknown) {
const msg = const msg =