|
|
@@ -1,86 +1,72 @@
|
|
|
<template>
|
|
|
- <view class="profile-page">
|
|
|
- <uni-forms ref="formRef" :model="formModel" :rules="rules" validate-trigger="submit">
|
|
|
+ <FlexCol :padding="30">
|
|
|
+ <Form
|
|
|
+ ref="formRef"
|
|
|
+ :model="formModel"
|
|
|
+ :rules="rules"
|
|
|
+ validateTrigger="submit"
|
|
|
+ :labelWidth="140"
|
|
|
+ >
|
|
|
<!-- 头像 -->
|
|
|
<view class="avatar-section">
|
|
|
<view class="avatar-container" @click="handleAvatarClick">
|
|
|
<image
|
|
|
- :src="formModel.avatar || '/static/images/default-avatar.png'"
|
|
|
+ :src="formModel.avatar || DefaultAvatar"
|
|
|
class="avatar-image"
|
|
|
mode="aspectFill"
|
|
|
></image>
|
|
|
- <view class="avatar-edit-mask">
|
|
|
- <uni-icons type="camera" size="24" color="#ffffff"></uni-icons>
|
|
|
- </view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 昵称 -->
|
|
|
- <uni-forms-item name="nickname" label="昵称" required>
|
|
|
- <uni-easyinput
|
|
|
- v-model="formModel.nickname"
|
|
|
- placeholder="请输入昵称"
|
|
|
- maxlength="20"
|
|
|
- />
|
|
|
- </uni-forms-item>
|
|
|
+ <Field name="nickname" label="昵称" placeholder="请输入昵称" required />
|
|
|
+ <Field name="bio" multiline label="个人简介" placeholder="输入个人简介" :inputStyle="{width: '240px'}" />
|
|
|
+ </Form>
|
|
|
|
|
|
- <!-- 个人简介 -->
|
|
|
- <uni-forms-item name="bio" label="个人简介">
|
|
|
- <uni-easyinput
|
|
|
- v-model="formModel.bio"
|
|
|
- type="textarea"
|
|
|
- placeholder="介绍一下自己吧"
|
|
|
- maxlength="100"
|
|
|
- :height="100"
|
|
|
- show-word-limit
|
|
|
- />
|
|
|
- </uni-forms-item>
|
|
|
+ <Height :height="40" />
|
|
|
|
|
|
- <!-- 提交按钮 -->
|
|
|
- <u-button type="primary" :loading="loading" @click="submitForm" >
|
|
|
- 保存修改
|
|
|
- </u-button>
|
|
|
- <view class="mt-3" />
|
|
|
- <u-button type="primary" :plain="true" @click="navTo('/pages/user/update/password')">
|
|
|
- 修改密码
|
|
|
- </u-button>
|
|
|
- </uni-forms>
|
|
|
- </view>
|
|
|
+ <Button type="primary" :loading="loading" @click="submitForm" >
|
|
|
+ 保存修改
|
|
|
+ </Button>
|
|
|
+ <Height :height="20" />
|
|
|
+ <Button type="primary" :plain="true" @click="navTo('/pages/user/update/password')">
|
|
|
+ 修改密码
|
|
|
+ </Button>
|
|
|
+ </FlexCol>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
import { ref, onMounted } from 'vue';
|
|
|
-import userApi from '@/api/auth/UserApi';
|
|
|
-import CommonContent from '@/api/CommonContent';
|
|
|
import { useAuthStore } from '@/store/auth';
|
|
|
import { navTo } from '@imengyu/imengyu-utils/dist/uniapp/PageAction';
|
|
|
+import UserApi from '@/api/auth/UserApi';
|
|
|
+import DefaultAvatar from '/static/images/home/UserHead.png';
|
|
|
+import CommonContent from '@/api/CommonContent';
|
|
|
+import Form from '@/components/form/Form.vue';
|
|
|
+import Field from '@/components/form/Field.vue';
|
|
|
+import FlexCol from '@/components/layout/FlexCol.vue';
|
|
|
+import Button from '@/components/basic/Button.vue';
|
|
|
+import Height from '@/components/layout/space/Height.vue';
|
|
|
+import type { Rules } from 'async-validator';
|
|
|
|
|
|
const authStore = useAuthStore();
|
|
|
const formRef = ref<any>(null);
|
|
|
const loading = ref(false);
|
|
|
const uploading = ref(false);
|
|
|
|
|
|
-// 表单数据
|
|
|
const formModel = ref({
|
|
|
avatar: '',
|
|
|
nickname: '',
|
|
|
bio: '',
|
|
|
});
|
|
|
-
|
|
|
-// 表单验证规则
|
|
|
-const rules = {
|
|
|
- nickname: {
|
|
|
- rules: [
|
|
|
- { required: true, errorMessage: '请输入昵称' },
|
|
|
- { minLength: 2, errorMessage: '昵称长度至少2个字符' },
|
|
|
- { maxLength: 20, errorMessage: '昵称长度最多20个字符' }
|
|
|
- ]
|
|
|
- },
|
|
|
- bio: {
|
|
|
- rules: [
|
|
|
- { maxLength: 100, errorMessage: '个人简介最多100个字符' }
|
|
|
- ]
|
|
|
- }
|
|
|
+const rules : Rules = {
|
|
|
+ nickname: [
|
|
|
+ { required: true, message: '请输入昵称' },
|
|
|
+ { min: 2, message: '昵称长度至少2个字符' },
|
|
|
+ { max: 20, message: '昵称长度最多20个字符' }
|
|
|
+ ],
|
|
|
+ bio: [
|
|
|
+ { max: 100, message: '个人简介最多100个字符' }
|
|
|
+ ],
|
|
|
};
|
|
|
|
|
|
// 处理头像点击事件
|
|
|
@@ -114,22 +100,17 @@ const handleAvatarClick = async () => {
|
|
|
uploading.value = false;
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
// 更新头像到服务器
|
|
|
const updateAvatar = async (avatarUrl: string) => {
|
|
|
try {
|
|
|
- // 调用修改头像API
|
|
|
- await userApi.updateSystemUserInfo({
|
|
|
+ await UserApi.updateSystemUserInfo({
|
|
|
avatar: avatarUrl
|
|
|
});
|
|
|
-
|
|
|
- // 更新表单数据和store
|
|
|
formModel.value.avatar = avatarUrl;
|
|
|
if (authStore.userInfo) {
|
|
|
authStore.userInfo.avatar = avatarUrl;
|
|
|
+ authStore.saveLoginState();
|
|
|
}
|
|
|
-
|
|
|
- // 显示成功提示
|
|
|
uni.showToast({
|
|
|
title: '头像更新成功',
|
|
|
icon: 'success',
|
|
|
@@ -141,8 +122,8 @@ const updateAvatar = async (avatarUrl: string) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-// 页面加载时获取用户信息
|
|
|
onMounted(() => {
|
|
|
+ console.log(authStore.userInfo);
|
|
|
if (authStore.userInfo) {
|
|
|
formModel.value.avatar = authStore.userInfo.avatar || '';
|
|
|
formModel.value.nickname = authStore.userInfo.nickname || '';
|
|
|
@@ -152,40 +133,34 @@ onMounted(() => {
|
|
|
|
|
|
// 提交表单
|
|
|
const submitForm = async () => {
|
|
|
- // 表单验证
|
|
|
- const valid = await formRef.value?.validate();
|
|
|
- if (!valid) return;
|
|
|
+ try {
|
|
|
+ await formRef.value?.validate();
|
|
|
+ } catch {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
loading.value = true;
|
|
|
|
|
|
try {
|
|
|
- // 调用修改个人信息API
|
|
|
- await userApi.updateSystemUserInfo({
|
|
|
+ await UserApi.updateSystemUserInfo({
|
|
|
nickname: formModel.value.nickname,
|
|
|
bio: formModel.value.bio
|
|
|
});
|
|
|
-
|
|
|
- // 更新store中的用户信息
|
|
|
if (authStore.userInfo) {
|
|
|
authStore.userInfo.nickname = formModel.value.nickname;
|
|
|
authStore.userInfo.avatar = formModel.value.avatar;
|
|
|
authStore.userInfo.intro = formModel.value.bio;
|
|
|
}
|
|
|
-
|
|
|
- // 显示成功提示
|
|
|
uni.showToast({
|
|
|
title: '个人信息更新成功',
|
|
|
icon: 'success',
|
|
|
duration: 2000
|
|
|
});
|
|
|
-
|
|
|
- // 成功后返回上一页
|
|
|
setTimeout(() => {
|
|
|
uni.navigateBack();
|
|
|
}, 2000);
|
|
|
|
|
|
} catch (error: any) {
|
|
|
- // 显示错误提示
|
|
|
uni.showToast({
|
|
|
title: error?.message || '更新失败,请稍后重试',
|
|
|
icon: 'none',
|
|
|
@@ -198,12 +173,6 @@ const submitForm = async () => {
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-.profile-page {
|
|
|
- min-height: 100vh;
|
|
|
- background-color: #f5f5f5;
|
|
|
- padding: 16px;
|
|
|
-}
|
|
|
-
|
|
|
.avatar-section {
|
|
|
text-align: center;
|
|
|
}
|
|
|
@@ -229,26 +198,6 @@ const submitForm = async () => {
|
|
|
border: 2px solid #e0e0e0;
|
|
|
background-color: #f5f5f5;
|
|
|
}
|
|
|
-
|
|
|
-.avatar-edit-mask {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- border-radius: 50%;
|
|
|
- background-color: rgba(0, 0, 0, 0.3);
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- opacity: 0;
|
|
|
- transition: opacity 0.3s ease;
|
|
|
-}
|
|
|
-
|
|
|
-.avatar-container:hover .avatar-edit-mask {
|
|
|
- opacity: 1;
|
|
|
-}
|
|
|
-
|
|
|
.avatar-hint {
|
|
|
font-size: 12px;
|
|
|
color: #007aff;
|
|
|
@@ -268,46 +217,13 @@ const submitForm = async () => {
|
|
|
align-items: center;
|
|
|
z-index: 9999;
|
|
|
}
|
|
|
-
|
|
|
.uploading-content {
|
|
|
background-color: #ffffff;
|
|
|
padding: 20px;
|
|
|
border-radius: 8px;
|
|
|
text-align: center;
|
|
|
}
|
|
|
-
|
|
|
.uploading-content uni-loading {
|
|
|
margin-bottom: 10px;
|
|
|
}
|
|
|
-
|
|
|
-uni-forms {
|
|
|
- background-color: #ffffff;
|
|
|
- border-radius: 8px;
|
|
|
- padding: 16px;
|
|
|
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
|
-}
|
|
|
-
|
|
|
-uni-forms-item {
|
|
|
- margin-bottom: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-uni-forms-item:last-child {
|
|
|
- margin-bottom: 0;
|
|
|
-}
|
|
|
-
|
|
|
-uni-easyinput {
|
|
|
- border-bottom: 1px solid #f0f0f0;
|
|
|
- padding: 8px 0;
|
|
|
-}
|
|
|
-
|
|
|
-uni-easyinput:focus {
|
|
|
- border-bottom-color: #007aff;
|
|
|
-}
|
|
|
-
|
|
|
-.submit-btn {
|
|
|
- margin-top: 32px;
|
|
|
- border-radius: 8px;
|
|
|
- height: 44px;
|
|
|
- font-size: 16px;
|
|
|
-}
|
|
|
</style>
|