2
0

fix:修改个人信息界面以及接口

This commit is contained in:
zhongzm
2024-12-13 19:14:29 +08:00
parent bf911bac96
commit 7cf6249fd8
5 changed files with 129 additions and 35 deletions

View File

@@ -50,9 +50,16 @@ export function doDeleteLogout() {
/** Get user info */ /** Get user info */
export function doGetUserInfo() { export function doGetUserInfo() {
return request<Api.Auth.UserInfo>({ url: '/u/user/getInfo' }); return request<Api.Auth.UserInfo>({ url: '/u/user/getInfo',method:'get' });
}
/** change user info */
export function doChangeUserInfo(body: Api.Auth.ChangeInfoBody){
return request({
url:'/u/user/profile',
method:'put',
data:body
});
} }
/** /**
* Refresh token * Refresh token
* *

View File

@@ -106,7 +106,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
return isSuccess; return isSuccess;
} }
//查询用户信息
async function refreshUserInfo() { async function refreshUserInfo() {
const { data: info, error } = await doGetUserInfo(); const { data: info, error } = await doGetUserInfo();
if (!error) { if (!error) {
@@ -115,6 +115,16 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
} }
return false; return false;
} }
/**修改用户信息**/
async function updateUserProfile(info: Api.Auth.ChangeInfoBody) {
try {
await doChangeUserInfo(info);
return true;
} catch (error) {
console.error('Failed to update user profile:', error);
return false;
}
}
/** /**
* 检查用户信息是否已存在 * 检查用户信息是否已存在
@@ -141,7 +151,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
endLoading(); endLoading();
return !error; return !error;
} }
//二维码
async function captcha(email: string) { async function captcha(email: string) {
if (!email) { if (!email) {
return null; return null;
@@ -161,6 +171,7 @@ export const useAuthStore = defineStore(SetupStoreId.Auth, () => {
refreshUserInfo, refreshUserInfo,
register, register,
captcha, captcha,
checkUserRepeat checkUserRepeat,
updateUserProfile
}; };
}); });

19
src/typings/api.d.ts vendored
View File

@@ -104,6 +104,7 @@ declare namespace Api {
delFlag: string; delFlag: string;
loginIp: string; loginIp: string;
loginDate: string; loginDate: string;
birthDate:string;
dept: Department.Dept; dept: Department.Dept;
roles: Role[]; roles: Role[];
roleId: string; roleId: string;
@@ -143,11 +144,11 @@ declare namespace Api {
password: string; password: string;
authType:string; authType:string;
email: string; email: string;
fullName: string; fullName?: string;
age: number; age: number;
address: string; address?: string;
sex: string; sex?: string;
phonenumber: string; phonenumber?: string;
} }
interface EmailCaptcha{ interface EmailCaptcha{
email:string; email:string;
@@ -158,6 +159,16 @@ declare namespace Api {
phonenumber?:string; phonenumber?:string;
authType: string; authType: string;
} }
interface ChangeInfoBody{
userId:number;
userName: string;
nickName?: string|undefined;
email: string;
phonenumber?: string|undefined;
sex?: string|undefined;
birthDate?:string|undefined;
age?:number;
}
} }
/** /**

View File

@@ -53,6 +53,7 @@ declare global {
const doAddDict: typeof import('../service/api/dict')['doAddDict'] const doAddDict: typeof import('../service/api/dict')['doAddDict']
const doAddMenu: typeof import('../service/api/menu')['doAddMenu'] const doAddMenu: typeof import('../service/api/menu')['doAddMenu']
const doAddPost: typeof import('../service/api/post')['doAddPost'] const doAddPost: typeof import('../service/api/post')['doAddPost']
const doChangeUserInfo: typeof import('../service/api/auth')['doChangeUserInfo']
const doCheckUserRepeat: typeof import('../service/api/auth')['doCheckUserRepeat'] const doCheckUserRepeat: typeof import('../service/api/auth')['doCheckUserRepeat']
const doDeleteDept: typeof import('../service/api/dept')['doDeleteDept'] const doDeleteDept: typeof import('../service/api/dept')['doDeleteDept']
const doDeleteDict: typeof import('../service/api/dict')['doDeleteDict'] const doDeleteDict: typeof import('../service/api/dict')['doDeleteDict']

View File

@@ -34,11 +34,16 @@ const { t } = useI18n();
const rules = computed<{ [k: string]: RuleObject | RuleObject[] }>(() => { const rules = computed<{ [k: string]: RuleObject | RuleObject[] }>(() => {
const validateUsername = async (_rule: RuleObject, value: string) => { const validateUsername = async (_rule: RuleObject, value: string) => {
const currentUsername = authStore.userInfo?.user?.userName;
if (value === currentUsername) {
return Promise.resolve();
}
if (value && (value.length < 4 || value.length > 20)) { if (value && (value.length < 4 || value.length > 20)) {
return Promise.reject(t('page.login.register.usernameLengthLimit')); return Promise.reject(t('page.login.register.usernameLengthLimit'));
} }
const currentUsername = authStore.userInfo?.user?.userName;
if (value && value !== currentUsername) { if (value) {
const { exists } = await authStore.checkUserRepeat({ username: value, authType: 'u' }); const { exists } = await authStore.checkUserRepeat({ username: value, authType: 'u' });
if (exists) { if (exists) {
return Promise.reject(t('page.login.register.usernameExists')); return Promise.reject(t('page.login.register.usernameExists'));
@@ -50,8 +55,10 @@ const rules = computed<{ [k: string]: RuleObject | RuleObject[] }>(() => {
const validatePhone = async (_rule: RuleObject, value: string) => { const validatePhone = async (_rule: RuleObject, value: string) => {
if (!value) return Promise.resolve(); if (!value) return Promise.resolve();
const phonePattern = /^1[3-9]\d{9}$/; const phonePattern = /^\+?([0-9]{1,3})?[-\s]?\d{6,15}$/;
if (!phonePattern.test(value)) {
const cleanPhone = value.replace(/[-\s]/g, '');
if (!phonePattern.test(cleanPhone)) {
return Promise.reject(t('page.login.register.phoneInvalid')); return Promise.reject(t('page.login.register.phoneInvalid'));
} }
@@ -66,6 +73,11 @@ const rules = computed<{ [k: string]: RuleObject | RuleObject[] }>(() => {
}; };
const validateEmail = async (_rule: RuleObject, value: string) => { const validateEmail = async (_rule: RuleObject, value: string) => {
const currentEmail = authStore.userInfo?.user?.email;
if (value === currentEmail) {
return Promise.resolve();
}
if (!value) { if (!value) {
return Promise.reject(t('page.login.register.emailRequired')); return Promise.reject(t('page.login.register.emailRequired'));
} }
@@ -75,12 +87,9 @@ const rules = computed<{ [k: string]: RuleObject | RuleObject[] }>(() => {
return Promise.reject(t('page.login.register.emailInvalid')); return Promise.reject(t('page.login.register.emailInvalid'));
} }
const currentEmail = authStore.userInfo?.user?.email; const { exists } = await authStore.checkUserRepeat({ email: value, authType: 'u' });
if (value !== currentEmail) { if (exists) {
const { exists } = await authStore.checkUserRepeat({ email: value, authType: 'u' }); return Promise.reject(t('page.login.register.emailExists'));
if (exists) {
return Promise.reject(t('page.login.register.emailExists'));
}
} }
return Promise.resolve(); return Promise.resolve();
}; };
@@ -97,12 +106,22 @@ const rules = computed<{ [k: string]: RuleObject | RuleObject[] }>(() => {
], ],
phonenumber: [{ validator: validatePhone, trigger: 'blur' }], phonenumber: [{ validator: validatePhone, trigger: 'blur' }],
birthdate: [ birthdate: [
{ required: true, message: t('page.login.register.birthDateRequired') },
{ {
validator: (_rule: RuleObject, value: string) => { validator: (_rule: RuleObject, value: string) => {
if (value && dayjs(value).isAfter(dayjs())) { if (!value) return Promise.resolve();
const selectedDate = dayjs(value);
const today = dayjs();
const minDate = today.subtract(120, 'year');
if (selectedDate.isAfter(today)) {
return Promise.reject(t('page.login.register.birthDateInvalid')); return Promise.reject(t('page.login.register.birthDateInvalid'));
} }
if (selectedDate.isBefore(minDate)) {
return Promise.reject(t('page.login.register.birthDateTooEarly'));
}
return Promise.resolve(); return Promise.resolve();
} }
} }
@@ -112,23 +131,27 @@ const rules = computed<{ [k: string]: RuleObject | RuleObject[] }>(() => {
onMounted(async () => { onMounted(async () => {
try { try {
// 先刷新获取最新的用户信息
await authStore.refreshUserInfo();
const userInfo = authStore.userInfo?.user; const userInfo = authStore.userInfo?.user;
if (!userInfo) { if (!userInfo) {
message.error(t('page.profile.getUserInfoFailed')); message.error(t('page.profile.getUserInfoFailed'));
return; return;
} }
// 将获取到的用户信息填充到表单中
formState.value = { formState.value = {
username: userInfo.userName ?? '', username: userInfo.userName ?? '',
fullname: userInfo.nickName ?? '', fullname: userInfo.nickName ?? '',
birthdate: '', birthdate: userInfo.birthDate ?? '', // 添加出生日期
email: userInfo.email ?? '', email: userInfo.email ?? '',
phonenumber: userInfo.phonenumber ?? '', phonenumber: userInfo.phonenumber ?? '',
sex: userInfo.sex ?? '0' sex: userInfo.sex ?? '0'
}; };
} catch (error) { } catch (error) {
console.error('Failed to get user info:', error); console.error('Failed to get user info:', error);
message.error(t('page.profile.updateFailed')); message.error(t('page.profile.getUserInfoFailed'));
} }
}); });
@@ -137,20 +160,55 @@ const handleSubmit = async () => {
await formRef.value?.validate(); await formRef.value?.validate();
loading.value = true; loading.value = true;
// 构建更新数据,只包含后端接受的字段 const userId = authStore.userInfo?.user?.userId;
// const updateData = { if (!userId) {
// userName: formState.value.username, message.error(t('page.profile.getUserInfoFailed'));
// nickName: formState.value.fullname, return;
// email: formState.value.email, }
// phonenumber: formState.value.phonenumber,
// sex: formState.value.sex,
// age: formState.value.birthdate ? dayjs().diff(dayjs(formState.value.birthdate), 'year') : undefined
// };
// 这里需要调用后端 API 更新用户信息 // 构建基础更新数据
// await authStore.updateUserProfile(updateData); const updateData: Api.Auth.ChangeInfoBody = {
userId,
userName: formState.value.username,
email: formState.value.email
};
message.success(t('page.profile.updateSuccess')); // 只在有值时添加可选字段
if (formState.value.fullname) {
updateData.nickName = formState.value.fullname;
}
if (formState.value.phonenumber) {
updateData.phonenumber = formState.value.phonenumber;
}
if (formState.value.sex) {
updateData.sex = formState.value.sex;
}
if (formState.value.birthdate) {
updateData.birthDate = formState.value.birthdate;
updateData.age = dayjs().diff(dayjs(formState.value.birthdate), 'year');
}
// 调用更新接口
const success = await authStore.updateUserProfile(updateData);
if (success) {
await authStore.refreshUserInfo();
// 更新表单数据以显示最新信息
const userInfo = authStore.userInfo?.user;
if (userInfo) {
formState.value = {
username: userInfo.userName ?? '',
fullname: userInfo.nickName ?? '',
birthdate: userInfo.birthDate ?? '',
email: userInfo.email ?? '',
phonenumber: userInfo.phonenumber ?? '',
sex: userInfo.sex ?? '0'
};
}
message.success(t('page.profile.updateSuccess'));
} else {
message.error(t('page.profile.updateFailed'));
}
} catch (error) { } catch (error) {
console.error('表单验证失败:', error); console.error('表单验证失败:', error);
message.error(t('page.profile.updateFailed')); message.error(t('page.profile.updateFailed'));
@@ -201,6 +259,12 @@ const handleBack = () => {
style="width: 100%" style="width: 100%"
:format="'YYYY-MM-DD'" :format="'YYYY-MM-DD'"
:placeholder="t('page.login.register.birthDatePlaceholder')" :placeholder="t('page.login.register.birthDatePlaceholder')"
:disabled-date="(current) => {
const today = dayjs();
const minDate = today.subtract(120, 'year');
return current && (current.isAfter(today) || current.isBefore(minDate));
}"
:show-today="false"
/> />
</a-form-item> </a-form-item>