This commit is contained in:
2026-03-06 13:41:22 +08:00
commit f39c6a705f
394 changed files with 159599 additions and 0 deletions

View File

@ -0,0 +1,332 @@
<template>
<view class="mine-user-edit">
<view class="edit-content">
<view class="flex-row-between edit-cell">
<text class="title">头像</text>
<button class="flex-row-end user-avator" open-type="chooseAvatar" @chooseavatar="chooseavatar">
<image class="avator-icon" :src="userInfo.head_pic_url" />
<!-- <image class="arrow-icon" :src="`${imgPrefix}right-arrow.png`" /> -->
</button>
</view>
<view class="flex-row-between edit-cell">
<text class="title">昵称</text>
<input class="fs-24 app-fc-main SourceHanSansCN-Medium edit-input" type="nickname"
placeholder-class="fs-24 app-fc-normal SourceHanSansCN-Regular app-text-right"
:value="userInfo.nick_name" placeholder="点击输入昵称" @change="
(e) =>
onChange(e.detail.value && e.detail.value.trim(), 'nick_name')
" />
</view>
<form-cell title="出生年月" type="checkDate" placeholderText="选择出生日期" :value="userInfo.birthday"
:defaultDate="userInfo.birthday" @onChange="(value) => onChange(value, 'birthday')" />
<form-cell title="性别" type="custom" :showRightArrow="false" :noBorder="true">
<view class="flex-row-end edit-sex" slot="right">
<view class="flex-center fs-24 app-fc-main SourceHanSansCN-Medium sex-item"
:class="[userInfo.sex === 1 ? 'active man' : '']" @click="onChange(1, 'sex')">
<image class="sex-item-img"
:src="userInfo.sex === 1 ? `${imgPrefix}whiteMale.png` : `${imgPrefix}record-maleImg.png`">
</image>
</view>
<view class="flex-center fs-24 app-fc-main SourceHanSansCN-Medium sex-item"
:class="[userInfo.sex === 2 ? 'active women' : '']" @click="onChange(2, 'sex')">
<image class="sex-item-img"
:src="userInfo.sex === 2 ? `${imgPrefix}whiteFemale.png` : `${imgPrefix}record-femaleImg.png`">
</image>
</view>
</view>
</form-cell>
</view>
<view class="footer">
<view class="footerBtn" @click="onsubmit()">
保存
</view>
<view class="bottom-safe-area"></view>
</view>
</view>
</template>
<script>
import FormCell from "../../../components/FormCell.vue";
import {
updateUserInfo,
getUserInfo
} from "../../../api/user";
import appConfig from "../../../constants/app.config";
import {
imgPrefix
} from "@/utils/common";
import {
uploadImageToOSS_PUT
} from "@/utils/oss";
export default {
components: {
FormCell,
},
data() {
return {
userInfo: {
head_pic_url: "",
head_pic: "",
nick_name: "",
birthday: "",
sex: 0,
},
appConfig,
imgPrefix
};
},
onShow() {
// 直接从 store缓存中获取用户信息并映射到表单字段
const storeUserInfo = this.$store.state?.user?.userInfo || {};
if (storeUserInfo && Object.keys(storeUserInfo).length > 0) {
// 将 gender 转换为 sex: "male" -> 1, "female" -> 2, 其他 -> 0
let sex = 0;
if (storeUserInfo.gender === 'male') {
sex = 1;
} else if (storeUserInfo.gender === 'female') {
sex = 2;
} else if (storeUserInfo.sex) {
// 兼容旧的 sex 字段
sex = storeUserInfo.sex;
}
// 格式化生日:将 ISO 8601 格式 (2006-01-02T00:00:00+08:00) 转换为 YYYY-MM-DD 格式
let birthday = storeUserInfo.birthday || '';
if (birthday) {
// 如果是 ISO 8601 格式,提取日期部分
if (birthday.includes('T')) {
birthday = birthday.split('T')[0];
}
// 确保格式为 YYYY-MM-DD
const dateMatch = birthday.match(/^(\d{4})-(\d{2})-(\d{2})/);
if (!dateMatch) {
// 如果不是标准格式,尝试转换
const date = new Date(birthday);
if (!isNaN(date.getTime())) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
birthday = `${year}-${month}-${day}`;
}
}
}
this.userInfo = {
head_pic_url: storeUserInfo.avatar || storeUserInfo.head_pic_url || storeUserInfo.head_pic || '',
head_pic: storeUserInfo.avatar || storeUserInfo.head_pic || storeUserInfo.head_pic_url || '',
nick_name: storeUserInfo.nickname || storeUserInfo.nick_name || storeUserInfo.username || '',
birthday: birthday,
sex: sex,
};
}
},
methods: {
// 保存
onsubmit() {
const {
head_pic,
nick_name,
birthday,
sex
} = this.userInfo;
if (!head_pic || !nick_name) {
uni.showToast({
icon: "none",
title: "请将昵称和头像填写完整",
});
return;
}
// 将 sex 转换为 gender: 1 -> "male", 2 -> "female", 其他 -> "other"
let gender = "other";
if (sex === 1) {
gender = "male";
} else if (sex === 2) {
gender = "female";
}
uni.showLoading({
title: "处理中..."
});
// 构建请求参数
const params = {
username: nick_name,
gender: gender,
birthday: birthday,
};
// 如果头像地址不是 https 开头,才传给后端
if (head_pic && !head_pic.startsWith('https://')) {
params.avatar = head_pic;
}
updateUserInfo(params).then(() => {
uni.hideLoading();
uni.navigateBack();
}).catch((err) => {
uni.hideLoading();
console.error('更新用户信息失败:', err);
});
},
// 更新头像
async chooseavatar(e) {
const {
avatarUrl
} = e.detail;
uni.showLoading({
title: "上传中..."
});
try {
const { url, objectKey } = await uploadImageToOSS_PUT(avatarUrl);
console.log(url, objectKey, 'url, objectKey')
this.userInfo.head_pic_url = url; // 同时更新 head_pic_url因为模板使用的是这个字段
this.userInfo.head_pic = objectKey;
this.$forceUpdate();
uni.hideLoading();
} catch (error) {
console.error('头像上传失败:', error);
uni.hideLoading();
uni.showToast({
title: error?.message || "头像上传失败",
icon: "none"
});
}
},
onChange(value, key) {
this.userInfo[key] = value;
this.$forceUpdate();
},
},
};
</script>
<style lang="scss">
.mine-user-edit {
background-color: #ffecf3;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
.edit-content {
background-color: #fff;
border-radius: 16rpx;
padding: 0rpx 24rpx;
width: calc(100vw - 40rpx);
margin: 20rpx auto;
box-sizing: border-box;
.edit-cell {
border-bottom: 1rpx solid #ececec;
height: 110rpx;
width: 100%;
box-sizing: border-box;
.title {
color: #3D3D3D;
font-size: 24rpx;
.required {
color: #FF19A0;
}
}
.avator-icon {
width: 80rpx;
height: 80rpx;
border-radius: 80rpx;
background: gray;
}
.arrow-icon {
width: 11rpx;
height: 18rpx;
}
.edit-input {
height: 100%;
text-align: right;
flex: 1;
margin-left: 30rpx;
font-size: 24rpx;
}
}
.edit-sex {
width: 100%;
}
.sex-item {
width: 120rpx;
height: 64rpx;
background: #f9f7f9;
border-radius: 16rpx 16rpx 16rpx 16rpx;
margin-left: 50rpx;
&-img {
width: 28rpx;
height: 28rpx;
}
&.active {
color: #fff;
&.man {
background: #FF19A0;
}
&.women {
background: #FF19A0;
}
}
}
}
.user-avator {
margin: 0;
background: #fff;
border: 0;
padding: 0;
border-color: transparent;
padding-left: 100rpx;
&::after {
border: none;
}
}
.footer {
background-color: #fff;
border-radius: 32rpx 32rpx 0px 0px;
.footerBtn {
color: #fff;
background-color: #FF19A0;
width: calc(100% - 48rpx);
margin: auto;
margin-bottom: 24rpx;
margin-top: 12rpx;
border-radius: 100px;
text-align: center;
padding: 32rpx 0rpx;
}
.bottom-safe-area {
padding-bottom: constant(safe-area-inset-bottom);
/* 兼容 iOS < 11.2 */
padding-bottom: env(safe-area-inset-bottom);
/* 兼容 iOS >= 11.2 */
}
}
}
</style>