Files
jiapuapp/pages/profile/security.vue
T

168 lines
4.7 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.
<template>
<view class="security-page">
<ModulePageBackground module="profile" />
<view class="page-header"
><PageHeader title="账号与安全" custom-back @back="backToProfile"
/></view>
<view class="page-content">
<view v-if="loading" class="state-card"
><AppLoading text="正在读取账号安全资料"
/></view>
<view v-else-if="securityProfileError" class="state-card">
<text>账号安全资料暂时无法读取</text><text>{{ securityProfileError }}</text>
<AppButton block label="重新读取" @click="loadProfile" />
</view>
<view v-else class="security-card">
<text class="security-card__title">账号安全概览</text>
<view class="security-field"
><text>绑定手机号</text><text>{{ maskedPhone }}</text></view
>
<view class="security-field"
><text>账号编号</text
><text>{{ profile.userNo || "未提供" }}</text></view
>
<text class="security-note"
>这里显示可查看的账号信息其他安全信息暂不支持查看</text
>
<AppButton block label="修改密码" @click="openPassword" />
<AppButton
type="secondary"
block
label="换绑手机号"
@click="openPhone"
/>
</view>
</view>
</view>
</template>
<script setup>
import { computed, reactive, ref } from "vue";
import { onShow, onUnload } from "@dcloudio/uni-app";
import AppButton from "@/components/AppButton.vue";
import AppLoading from "@/components/AppLoading.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
import {
createRequestController,
isRequestCancelled
} from "@/services/api/request-controller.js";
import { profileApi } from "@/services/api/profile-service.js";
import { getRequestErrorMessage } from "@/services/api/request-error-message.js";
import { openPage, returnTo } from "@/utils/navigation/gateway.js";
const profile = reactive({ phone: "", userNo: "" });
const loading = ref(false);
const securityProfileError = ref("");
const securityProfileRequestController = createRequestController();
let pageActive = true;
const maskedPhone = computed(() =>
/^\d{7,}$/.test(profile.phone)
? `${profile.phone.slice(0, 3)}****${profile.phone.slice(-4)}`
: "未提供",
);
const loadProfile = async () => {
if (loading.value) return;
loading.value = true;
securityProfileError.value = "";
try {
const profileResponse = await profileApi.getProfile({
requestController: securityProfileRequestController,
});
if (pageActive) Object.assign(profile, profileResponse);
} catch (error) {
if (pageActive && !isRequestCancelled(error))
securityProfileError.value = getRequestErrorMessage(error, "请稍后重试");
} finally {
if (pageActive) loading.value = false;
}
};
const backToProfile = () => returnTo("M01");
const openPassword = () => openPage("M04", {}, "M03");
const openPhone = () => openPage("M05", {}, "M03");
onShow(loadProfile);
onUnload(() => {
pageActive = false;
securityProfileRequestController.abort();
});
</script>
<style scoped lang="scss">
@import "../../styles/adaptive-frame-profiles.scss";
.security-page {
display: flex;
min-height: 100vh;
flex-direction: column;
background: $paper;
}
.page-header,
.page-content {
z-index: 1;
}
.page-content {
padding: 18rpx 24rpx 72rpx;
}
.state-card,
.security-card {
box-sizing: border-box;
min-height: 340rpx;
padding: 54rpx 42rpx 44rpx;
@include adaptive-profile-content;
}
.state-card {
text-align: center;
}
.state-card text,
.security-card text {
display: block;
}
.state-card text:first-child,
.security-card__title {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
margin-top: 28rpx;
}
.security-field {
display: flex;
min-height: 82rpx;
align-items: center;
justify-content: space-between;
gap: 20rpx;
border-bottom: 1rpx solid rgba(181, 137, 63, 0.3);
}
.security-field:first-of-type {
margin-top: 24rpx;
}
.security-field text:first-child {
color: $ink;
font-size: clamp(15px, 24rpx, 18px);
font-weight: 700;
}
.security-field text:last-child {
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
text-align: right;
overflow-wrap: anywhere;
}
.security-note {
margin-top: 22rpx;
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.6;
}
.security-card .app-button {
margin-top: 20rpx;
}
</style>