ow
This commit is contained in:
1 parent
28dd3ffebd
commit
1b7ee59d23
14 files changed
+538
-4
No files matched your search
@@ -3,5 +3,13 @@ import { SecurityUserEntity } from "./securityUserEntity";
|
||||
export class SecurityUserDisplayData extends SecurityUserEntity
|
||||
{
|
||||
public OrgUserPassword: string = "";
|
||||
public IsCanAmend?: Date= null!;
|
||||
public Nation: string = "";
|
||||
public Address: string = "";
|
||||
public IdNumber: string = "";
|
||||
public Issuer: string = "";
|
||||
public Validity: string = "";
|
||||
public IdCardFilename: string = "";
|
||||
public IdCardUrl: string = "";
|
||||
|
||||
}
|
||||
@@ -28,6 +28,10 @@
|
||||
"loginAgent": "Agent Login",
|
||||
"changePassword": "Change Password",
|
||||
"changeLocalName": "Change Nickname",
|
||||
"verifiedLocalName": "Verified Nickname",
|
||||
"identityVerification": "Identity Verification",
|
||||
"verified": "Verified",
|
||||
"verifiedNoRename": "Verified users cannot change nickname",
|
||||
"logout": "Log Out",
|
||||
"logoutConfirmTitle": "Log Out",
|
||||
"logoutConfirmContent": "Are you sure you want to log out?",
|
||||
@@ -88,6 +92,19 @@
|
||||
"nameTooShort": "User name must be at least 2 characters",
|
||||
"success": "Updated, please log in again"
|
||||
},
|
||||
"IdentityVerificationPage": {
|
||||
"title": "Identity Verification",
|
||||
"intro": "After uploading your ID card, the system recognizes it and writes all information into the remark; the nickname becomes the name on the ID and the account is marked verified (applies to normal users only)",
|
||||
"uploadBut": "Upload & Verify",
|
||||
"uploadingTip": "Recognizing…",
|
||||
"savingTip": "Submitting…",
|
||||
"success": "Identity verified",
|
||||
"failed": "Recognition or submission failed",
|
||||
"noResult": "Nothing recognized, please try a clearer photo",
|
||||
"previewTitle": "Recognized Info (will be saved to remark)",
|
||||
"reloginTip": "Verification takes effect immediately; on another device or after clearing cache the server is the source of truth",
|
||||
"verifiedDone": "You have already completed identity verification"
|
||||
},
|
||||
"ThemePage": {
|
||||
"title": "My Theme",
|
||||
"themeTitle": "Theme Color",
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
"loginAgent": "代理登录",
|
||||
"changePassword": "修改密码",
|
||||
"changeLocalName": "修改昵称",
|
||||
"verifiedLocalName": "认证昵称",
|
||||
"identityVerification": "身份验证",
|
||||
"verified": "已认证",
|
||||
"verifiedNoRename": "已认证用户不能修改昵称",
|
||||
"logout": "退出登录",
|
||||
"logoutConfirmTitle": "退出登录",
|
||||
"logoutConfirmContent": "确定要退出当前账号吗?",
|
||||
@@ -88,6 +92,19 @@
|
||||
"nameTooShort": "用户名称不能少于两个字",
|
||||
"success": "修改成功,请重新登录"
|
||||
},
|
||||
"IdentityVerificationPage": {
|
||||
"title": "身份验证",
|
||||
"intro": "上传身份证后,系统自动识别并将全部信息写入备注,昵称为身份证姓名,账号置为已认证(仅普通用户生效)",
|
||||
"uploadBut": "上传并认证",
|
||||
"uploadingTip": "识别中…",
|
||||
"savingTip": "提交中…",
|
||||
"success": "身份验证成功",
|
||||
"failed": "识别或提交失败",
|
||||
"noResult": "未识别到信息,请换一张更清晰的照片",
|
||||
"previewTitle": "识别结果(将写入备注)",
|
||||
"reloginTip": "认证结果已即时生效;换设备或清除缓存后以服务端为准",
|
||||
"verifiedDone": "您已完成身份认证,无需重复认证"
|
||||
},
|
||||
"ThemePage": {
|
||||
"title": "我的主题",
|
||||
"themeTitle": "主题颜色",
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
{
|
||||
"path": "pages/login/change-local-name"
|
||||
},
|
||||
// 身份验证(/identity-verification):从「我的」跳入,上传身份证→后端 OCR→识别信息写入 UserRemark 并置认证态
|
||||
{
|
||||
"path": "pages/login/identity-verification"
|
||||
},
|
||||
// 错误页:H5 短地址由 CLEAN_PATH_OVERRIDES 指定为 /error/page40x,与旧 WebVue 地址一致
|
||||
{
|
||||
"path": "pages/error/page401"
|
||||
|
||||
@@ -33,6 +33,11 @@ async function doLogout(): Promise<void> {
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
// 已认证用户昵称锁定为身份证姓名,禁止再改(冷启动直达本页时的兜底)
|
||||
if (loginProfileStore.userType === "N") {
|
||||
uni.showToast({ title: t("MinePage.verifiedNoRename"), icon: "none" });
|
||||
return;
|
||||
}
|
||||
const name = localName.value.trim();
|
||||
if (!name) {
|
||||
uni.showToast({ title: t("ChangeLocalNamePage.nameRequired"), icon: "none" });
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 身份验证页:从「我的」跳入(短地址 /identity-verification)。
|
||||
* 流程:chooseImage 单图 → 复用同源后端 DmsFile/UploadIdCardFile(后端落盘 idcard 目录 +
|
||||
* server-to-server 调同 docker 的 OCR,返回带识别结果的 FamilyPersonDisplayData,避免浏览器跨域)→
|
||||
* 把「全部识别信息」格式化写入 UserRemark,昵称取身份证姓名,再调 SecurityUser/UpdateSecurityUserIdCard
|
||||
* 落库并把 UserType 置为 NORMAL_USERS(已认证)。
|
||||
* 与 family-person 的身份证不同:那边把无列信息并入「简介」;这里 UserRemark 是真实列,整体覆盖为识别信息。
|
||||
* 注意:后端 UpdateSecurityUserIdCard 对「可查看全部用户」(管理员)会直接 return 不更新——普通用户自助认证场景。
|
||||
*/
|
||||
import { useLocale } from "uview-pro";
|
||||
import { computed, ref } from "vue";
|
||||
import { buildChunkFileName, uploadFile } from "@/common/http.interceptor";
|
||||
import { useAuthGuard, useThemeGradient, useThemeTokens } from "@/composables";
|
||||
import { SecurityUserDisplayData } from "@/data/auto/securityUserDisplayData";
|
||||
import { pageUrl } from "@/router/routes";
|
||||
import securityUserService from "@/service/security/securityUserService";
|
||||
import { useLoginProfileStore } from "@/stores";
|
||||
|
||||
const { t } = useLocale();
|
||||
useAuthGuard();
|
||||
|
||||
const loginProfileStore = useLoginProfileStore();
|
||||
|
||||
/** 后端 UpdateSecurityUserIdCard 会把 UserType 置为 NORMAL_USERS("N")代表已认证;此处与后端口径保持一致 */
|
||||
const NORMAL_USERS = "N";
|
||||
|
||||
const imageUrl = ref("");
|
||||
const remark = ref("");
|
||||
const recognizedName = ref("");
|
||||
const uploading = ref(false);
|
||||
const saving = ref(false);
|
||||
|
||||
const busy = computed(() => uploading.value || saving.value);
|
||||
const buttonText = computed(() => {
|
||||
if (uploading.value) {
|
||||
return t("IdentityVerificationPage.uploadingTip");
|
||||
}
|
||||
if (saving.value) {
|
||||
return t("IdentityVerificationPage.savingTip");
|
||||
}
|
||||
return t("IdentityVerificationPage.uploadBut");
|
||||
});
|
||||
|
||||
/** 已认证(UserType=NORMAL_USERS):禁止重复认证,仅展示认证状态 */
|
||||
const isVerified = computed(() => loginProfileStore.userType === NORMAL_USERS);
|
||||
|
||||
/** 返回:有历史则回退,冷启动直达时兜底切回「我的」tab */
|
||||
function onBack(): void {
|
||||
if (getCurrentPages().length > 1) {
|
||||
uni.navigateBack();
|
||||
}
|
||||
else {
|
||||
uni.switchTab({ url: pageUrl("mineTab") });
|
||||
}
|
||||
}
|
||||
|
||||
/* 主题渐变底 + 主题色变量(与「我的」页同一接线口径) */
|
||||
const { themeBackground } = useThemeGradient();
|
||||
const { primary, accentGradient, accentSoft, accentShadow } = useThemeTokens();
|
||||
const themeVars = computed(() => ({
|
||||
"--fg-primary": primary.value,
|
||||
"--fg-gradient": accentGradient.value,
|
||||
"--fg-soft": accentSoft.value,
|
||||
"--fg-shadow": accentShadow.value,
|
||||
}));
|
||||
|
||||
/** 出生日期归一为 yyyy-MM-dd(兼容 yyyyMMdd 与带分隔符/时间戳);不足 8 位数字则原样返回 */
|
||||
function formatBirth(raw: string): string {
|
||||
const digits = String(raw ?? "").replace(/\D/g, "");
|
||||
if (digits.length < 8) {
|
||||
return String(raw ?? "").trim();
|
||||
}
|
||||
return `${digits.slice(0, 4)}-${digits.slice(4, 6)}-${digits.slice(6, 8)}`;
|
||||
}
|
||||
|
||||
/** 取后端识别结果字段:兼容 PascalCase(服务端默认)与 camelCase(前端缓存转键) */
|
||||
function pick(info: any, pascal: string, camel: string): string {
|
||||
return String(info?.[pascal] ?? info?.[camel] ?? "").trim();
|
||||
}
|
||||
|
||||
/** 把全部识别信息拼成 UserRemark 文本(有值才成行,逐行「标签: 值」);返回拼接文本与身份证姓名 */
|
||||
function buildRemark(info: any): { text: string; name: string } {
|
||||
const name = pick(info, "CommonName", "commonName");
|
||||
const rows: string[] = [];
|
||||
const push = (label: string, val: string): void => {
|
||||
if (val) {
|
||||
rows.push(`${label}: ${val}`);
|
||||
}
|
||||
};
|
||||
push(t("FamilyPersonPage.commonName"), name);
|
||||
push(t("FamilyPersonPage.gender"), pick(info, "Gender", "gender"));
|
||||
push(t("FamilyPersonPage.birthDate"), formatBirth(pick(info, "BirthDate", "birthDate")));
|
||||
push(t("FamilyPersonPage.nation"), pick(info, "Nation", "nation"));
|
||||
push(t("FamilyPersonPage.address"), pick(info, "Address", "address"));
|
||||
push(t("FamilyPersonPage.idNumber"), pick(info, "IdNumber", "idNumber"));
|
||||
push(t("FamilyPersonPage.issuer"), pick(info, "Issuer", "issuer"));
|
||||
push(t("FamilyPersonPage.validity"), pick(info, "Validity", "validity"));
|
||||
return { text: rows.join("\n"), name };
|
||||
}
|
||||
|
||||
/** 上传身份证:单图 → 后端 OCR → 拼 UserRemark(整体覆盖)→ UpdateSecurityUserIdCard 落库并置认证态 */
|
||||
function onUploadIdCard(): void {
|
||||
if (uploading.value || saving.value || isVerified.value) {
|
||||
return;
|
||||
}
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: async (res: any) => {
|
||||
const filePath = String(res?.tempFilePaths?.[0] ?? "");
|
||||
const fileName = String(res?.tempFiles?.[0]?.name || `idcard-${Date.now()}.jpg`);
|
||||
if (!filePath) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
uploading.value = true;
|
||||
const physicalName = buildChunkFileName(fileName);
|
||||
imageUrl.value = filePath;
|
||||
const result = await uploadFile({
|
||||
url: "/DmsFile/UploadIdCardFile",
|
||||
filePath,
|
||||
name: fileName,
|
||||
fileName: physicalName,
|
||||
header: { FilePath: "idcard" },
|
||||
formData: { side: "auto" },
|
||||
});
|
||||
const info = result?.Data ?? result?.data ?? result;
|
||||
const { text, name } = buildRemark(info);
|
||||
if (!text) {
|
||||
uni.showToast({ title: t("IdentityVerificationPage.noResult"), icon: "none" });
|
||||
return;
|
||||
}
|
||||
remark.value = text;
|
||||
recognizedName.value = name;
|
||||
await save();
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
uni.showToast({ title: t("IdentityVerificationPage.failed"), icon: "none" });
|
||||
}
|
||||
finally {
|
||||
uploading.value = false;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/** 提交认证:昵称取身份证姓名(识别不到则沿用当前昵称),UserRemark 整体覆盖为识别信息 */
|
||||
async function save(): Promise<void> {
|
||||
try {
|
||||
saving.value = true;
|
||||
const payload = new SecurityUserDisplayData();
|
||||
payload.UserLocalName = recognizedName.value || loginProfileStore.userLocalName || "";
|
||||
payload.UserRemark = remark.value;
|
||||
await securityUserService.UpdateSecurityUserIdCard(payload);
|
||||
// 后端已将 UserType 置为 NORMAL_USERS、昵称改为身份证姓名;
|
||||
// 登录快照是登录时的旧值,这里同步本地态,返回「我的」即可立即显示「已认证」
|
||||
loginProfileStore.loginProfile.UserType = NORMAL_USERS;
|
||||
if (payload.UserLocalName) {
|
||||
loginProfileStore.loginProfile.UserLocalName = payload.UserLocalName;
|
||||
}
|
||||
uni.showToast({ title: t("IdentityVerificationPage.success"), icon: "none" });
|
||||
// 成功后短延时返回「我的」,让 toast 露出
|
||||
setTimeout(() => uni.navigateBack(), 800);
|
||||
}
|
||||
finally {
|
||||
saving.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<app-page :hide-nav="true">
|
||||
<view class="idv-page" :style="[{ background: themeBackground }, themeVars]">
|
||||
<hero-navbar :title="t('IdentityVerificationPage.title')" @back="onBack" />
|
||||
<view class="idv-body">
|
||||
<!-- 已认证:仅展示状态,隐藏上传入口,禁止重复认证 -->
|
||||
<view v-if="isVerified" class="idv-card idv-card--verified">
|
||||
<u-icon name="checkmark-circle-fill" size="80" color="#52c41a" />
|
||||
<text class="idv-verified-text">
|
||||
{{ t("IdentityVerificationPage.verifiedDone") }}
|
||||
</text>
|
||||
</view>
|
||||
<template v-else>
|
||||
<!-- 说明卡 -->
|
||||
<view class="idv-card">
|
||||
<text class="idv-title">
|
||||
{{ t("IdentityVerificationPage.title") }}
|
||||
</text>
|
||||
<text class="idv-intro">
|
||||
{{ t("IdentityVerificationPage.intro") }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 上传 + 预览卡 -->
|
||||
<view class="idv-card">
|
||||
<view class="idv-thumb">
|
||||
<image v-if="imageUrl" class="idv-thumb__img" :src="imageUrl" mode="aspectFill" />
|
||||
<view v-else class="idv-thumb__empty">
|
||||
<u-icon name="camera" size="44" color="#c4c8cf" />
|
||||
<text class="idv-thumb__empty-text">
|
||||
{{ t("IdentityVerificationPage.uploadBut") }}
|
||||
</text>
|
||||
</view>
|
||||
<view v-if="uploading" class="idv-thumb__mask">
|
||||
<text class="idv-thumb__mask-text">
|
||||
{{ t("IdentityVerificationPage.uploadingTip") }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<u-button type="primary" shape="circle" :loading="busy" :disabled="busy" :text="buttonText"
|
||||
@click="onUploadIdCard" />
|
||||
</view>
|
||||
|
||||
<!-- 识别结果预览(保存后可见) -->
|
||||
<view v-if="remark" class="idv-card">
|
||||
<text class="idv-subtitle">
|
||||
{{ t("IdentityVerificationPage.previewTitle") }}
|
||||
</text>
|
||||
<text class="idv-remark">
|
||||
{{ remark }}
|
||||
</text>
|
||||
<text class="idv-tip">
|
||||
{{ t("IdentityVerificationPage.reloginTip") }}
|
||||
</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</app-page>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.idv-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.idv-body {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
padding: 0 24rpx 24rpx;
|
||||
}
|
||||
|
||||
.idv-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
padding: 32rpx;
|
||||
border-radius: 24rpx;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 4rpx 16rpx rgba(31, 35, 41, 0.06);
|
||||
}
|
||||
|
||||
.idv-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.idv-subtitle {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.idv-intro {
|
||||
font-size: 24rpx;
|
||||
line-height: 1.6;
|
||||
color: #9aa0a6;
|
||||
}
|
||||
|
||||
.idv-thumb {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
overflow: hidden;
|
||||
border: 2rpx dashed #d6d9de;
|
||||
border-radius: 16rpx;
|
||||
background-color: #f5f6f8;
|
||||
}
|
||||
|
||||
.idv-thumb__img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.idv-thumb__empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.idv-thumb__empty-text {
|
||||
font-size: 26rpx;
|
||||
color: #9aa0a6;
|
||||
}
|
||||
|
||||
.idv-thumb__mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.idv-thumb__mask-text {
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.idv-remark {
|
||||
font-size: 26rpx;
|
||||
line-height: 1.7;
|
||||
color: #1f2329;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.idv-tip {
|
||||
font-size: 22rpx;
|
||||
color: #9aa0a6;
|
||||
}
|
||||
|
||||
/* 已认证态卡:图标 + 文案居中,绿字与「我的」徒章同色系 */
|
||||
.idv-card--verified {
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
padding: 64rpx 32rpx;
|
||||
}
|
||||
|
||||
.idv-verified-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #52c41a;
|
||||
}
|
||||
</style>
|
||||
@@ -28,6 +28,9 @@ const loginProfileStore = useLoginProfileStore();
|
||||
const { can } = usePermission();
|
||||
const canSeeLoginAgent = computed(() => can("none", "SecurityUser", "LoginAgent"));
|
||||
|
||||
/* 「已认证」判定:与后端 UpdateSecurityUserIdCard 口径一致——UserType=NORMAL_USERS("N") 即视为已认证(身份验证成功后本地快照同步) */
|
||||
const isVerified = computed(() => loginProfileStore.userType === "N");
|
||||
|
||||
/* 统一风格:主题渐变底 + 主题色变量(与 family-person-enquiry / 族谱首页同一接线口径) */
|
||||
const { themeBackground } = useThemeGradient();
|
||||
const { primary, accentGradient, accentSoft, accentShadow } = useThemeTokens();
|
||||
@@ -63,11 +66,22 @@ function goChangePassword(): void {
|
||||
uni.navigateTo({ url: pageUrl("changePassword") });
|
||||
}
|
||||
|
||||
/** 进入「修改昵称」页(/change-local-name):改用户名,成功后按旧系统约定退出重登刷新快照 */
|
||||
/** 进入「修改昵称」页(/change-local-name):改用户名,成功后按旧系统约定退出重登刷新快照;已认证用户昵称锁定为身份证姓名,单击无效(改由右侧直接展示昵称) */
|
||||
function goChangeLocalName(): void {
|
||||
if (isVerified.value) {
|
||||
return;
|
||||
}
|
||||
uni.navigateTo({ url: pageUrl("changeLocalName") });
|
||||
}
|
||||
|
||||
/** 进入「身份验证」页(/identity-verification):上传身份证 OCR 后把信息写入备注并置认证态;已认证后不再重复认证,单击无效 */
|
||||
function goIdentityVerification(): void {
|
||||
if (isVerified.value) {
|
||||
return;
|
||||
}
|
||||
uni.navigateTo({ url: pageUrl("identityVerification") });
|
||||
}
|
||||
|
||||
/** 退出登录:确认后调后端 Logout、清本地档案,回登录页 */
|
||||
async function handleLogout(): Promise<void> {
|
||||
const confirmed = await new Promise<boolean>((resolve) => {
|
||||
@@ -156,15 +170,32 @@ async function handleLogout(): Promise<void> {
|
||||
<u-icon name="arrow-right" size="32" color="#9aa0a6" />
|
||||
</view>
|
||||
|
||||
<!-- 修改昵称:改用户名,成功后退出重登刷新快照(/change-local-name) -->
|
||||
<!-- 修改昵称:改用户名(/change-local-name);已认证则锁定、改名为「认证昵称」并直接展示昵称 -->
|
||||
<view class="mine-cell" @tap="goChangeLocalName">
|
||||
<view class="mine-cell__icon">
|
||||
<u-icon name="edit-pen-fill" size="30" color="#ffffff" />
|
||||
</view>
|
||||
<text class="mine-cell__title">
|
||||
{{ t("MinePage.changeLocalName") }}
|
||||
{{ isVerified ? t("MinePage.verifiedLocalName") : t("MinePage.changeLocalName") }}
|
||||
</text>
|
||||
<u-icon name="arrow-right" size="32" color="#9aa0a6" />
|
||||
<text v-if="isVerified" class="mine-cell__value">
|
||||
{{ loginProfileStore.userLocalName }}
|
||||
</text>
|
||||
<u-icon v-else name="arrow-right" size="32" color="#9aa0a6" />
|
||||
</view>
|
||||
|
||||
<!-- 身份验证:上传身份证 OCR 后写入备注并置认证态(/identity-verification);已认证则右侧换为徽标 -->
|
||||
<view class="mine-cell" @tap="goIdentityVerification">
|
||||
<view class="mine-cell__icon">
|
||||
<u-icon name="checkmark-circle-fill" size="30" color="#ffffff" />
|
||||
</view>
|
||||
<text class="mine-cell__title">
|
||||
{{ t("MinePage.identityVerification") }}
|
||||
</text>
|
||||
<text v-if="isVerified" class="mine-cell__tag">
|
||||
{{ t("MinePage.verified") }}
|
||||
</text>
|
||||
<u-icon v-else name="arrow-right" size="32" color="#9aa0a6" />
|
||||
</view>
|
||||
|
||||
<!-- 退出登录:确认后清会话回登录页 -->
|
||||
@@ -272,6 +303,26 @@ async function handleLogout(): Promise<void> {
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
/* 已认证徽标:替换右箭头,绿色描边胶囊,与主题橙入口区分状态语义 */
|
||||
.mine-cell__tag {
|
||||
padding: 6rpx 20rpx;
|
||||
border: 2rpx solid #52c41a;
|
||||
border-radius: 999rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
/* 已认证锁定的展示值(如昵称):右对齐灰字省略,替代不可点的箭头 */
|
||||
.mine-cell__value {
|
||||
max-width: 60%;
|
||||
overflow: hidden;
|
||||
font-size: 28rpx;
|
||||
color: #8f959e;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 退出登录:降权为描边行,标题居中、危险色,与普通入口区分 */
|
||||
.mine-cell--logout {
|
||||
justify-content: center;
|
||||
|
||||
@@ -19,6 +19,8 @@ export const PAGE_PATHS = {
|
||||
changePassword: "pages/login/change-password",
|
||||
// 修改昵称(短地址 /change-local-name):需登录,从「我的」页跳入,成功后按旧系统约定退出重登刷新快照
|
||||
changeLocalName: "pages/login/change-local-name",
|
||||
// 身份验证(短地址 /identity-verification):从「我的」跳入,上传身份证 OCR 后写入 UserRemark 并置认证态
|
||||
identityVerification: "pages/login/identity-verification",
|
||||
dashboard: "pages/dashboard/dashboard",
|
||||
error401: "pages/error/page401",
|
||||
error403: "pages/error/page403",
|
||||
|
||||
@@ -5,6 +5,7 @@ import { request,download } from "@/utils/request";
|
||||
import type { SecurityUserSearchCriteria } from "@/data/auto/securityUserSearchCriteria";
|
||||
import type { SecurityUserResultData } from "@/data/auto/securityUserResultData";
|
||||
import type { SecurityFunctionResultData } from "@/data/auto/securityFunctionResultData";
|
||||
import type { SecurityUserDisplayData } from "@/data/auto/securityUserDisplayData";
|
||||
|
||||
class SecurityUserService{
|
||||
|
||||
@@ -117,6 +118,16 @@ class SecurityUserService{
|
||||
)
|
||||
};
|
||||
|
||||
async UpdateSecurityUserIdCard(data: SecurityUserDisplayData) {
|
||||
return request<any>(
|
||||
{
|
||||
url: "/SecurityUser/UpdateSecurityUserIdCard",
|
||||
method: "post",
|
||||
data,
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const securityUserService= new SecurityUserService();
|
||||
|
||||
Reference in new issue
Block a user