fix:修改个人信息界面以及接口
This commit is contained in:
@@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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
19
src/typings/api.d.ts
vendored
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
1
src/typings/auto-imports.d.ts
vendored
1
src/typings/auto-imports.d.ts
vendored
@@ -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']
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user