feat(personal-item): 个人事项

This commit is contained in:
caozehui
2026-05-19 10:59:07 +08:00
parent acd41555f9
commit 7d578ab271
28 changed files with 3743 additions and 105 deletions

View File

@@ -1,14 +1,13 @@
<script setup lang="ts">
import { computed, onActivated, onMounted, ref } from 'vue';
import { userGenderRecord } from '@/constants/business';
import { fetchGetMyProfileDetail, fetchUpdateMyProfile } from '@/service/api';
import { buildFileProxyUrl, uploadFile } from '@/service/api/file';
import { fetchGetMyProfileDetail, fetchUpdateMyAvatar } from '@/service/api';
import { useAuthStore } from '@/store/modules/auth';
import { useAppStore } from '@/store/modules/app';
import { $t } from '@/locales';
import ProfileInfoDialog from './modules/profile-info-dialog.vue';
import ProfilePasswordDialog from './modules/profile-password-dialog.vue';
import { buildProfileUpdatePayload, formatProfileDateTime, resolveProfileRoleLabels } from './modules/profile-model';
import { formatProfileDateTime, resolveProfileRoleLabels } from './modules/profile-model';
defineOptions({ name: 'MyProfile' });
@@ -22,6 +21,8 @@ const profileInfoVisible = ref(false);
const passwordVisible = ref(false);
const avatarInputRef = ref<HTMLInputElement | null>(null);
const MAX_AVATAR_SIZE = 5 * 1024 * 1024;
const descriptionColumns = computed(() => (appStore.isMobile ? 1 : 2));
const displayName = computed(() => profile.value?.nickname?.trim() || profile.value?.username || '--');
const displayUsername = computed(() => profile.value?.username?.trim() || '--');
@@ -41,6 +42,7 @@ const genderText = computed(() => {
return $t(userGenderRecord[value]);
});
const roleLabels = computed(() => {
const roles = profile.value?.roles ?? [];
@@ -57,16 +59,6 @@ function getAvatarText() {
return name === '--' ? 'CN' : name.slice(0, 1).toUpperCase();
}
function getEditableProfileValues(current: Api.Auth.MyProfileDetail): Api.Auth.UpdateMyProfileParams {
return {
nickname: current.nickname ?? '',
email: current.email ?? '',
mobile: current.mobile ?? '',
sex: current.sex ?? 1,
avatar: current.avatar ?? ''
};
}
async function loadProfile() {
const userId = authStore.userInfo.userId;
@@ -75,9 +67,7 @@ async function loadProfile() {
return;
}
const { data, error } = await fetchGetMyProfileDetail({
userId
});
const { data, error } = await fetchGetMyProfileDetail({ userId });
if (!error) {
profile.value = data;
@@ -115,21 +105,14 @@ async function handleAvatarChange(event: Event) {
return;
}
avatarSubmitting.value = true;
const uploadResult = await uploadFile(file, 'avatar');
if (uploadResult.error) {
avatarSubmitting.value = false;
if (file.size > MAX_AVATAR_SIZE) {
window.$message?.error('头像图片大小不能超过 5MB');
return;
}
const avatar = buildFileProxyUrl(uploadResult.data.configId, uploadResult.data.path);
const payload = buildProfileUpdatePayload({
...getEditableProfileValues(profile.value),
avatar
});
const updateResult = await fetchUpdateMyProfile(payload);
avatarSubmitting.value = true;
const updateResult = await fetchUpdateMyAvatar(file);
avatarSubmitting.value = false;
@@ -212,7 +195,7 @@ onActivated(() => {
<ElDescriptions :column="descriptionColumns" border>
<ElDescriptionsItem label="用户名">{{ displayUsername }}</ElDescriptionsItem>
<ElDescriptionsItem label="称">{{ displayName }}</ElDescriptionsItem>
<ElDescriptionsItem label="称">{{ displayName }}</ElDescriptionsItem>
<ElDescriptionsItem label="手机号">{{ mobileText }}</ElDescriptionsItem>
<ElDescriptionsItem label="邮箱">{{ emailText }}</ElDescriptionsItem>
<ElDescriptionsItem label="性别">{{ genderText }}</ElDescriptionsItem>