YingXingAI/pages/home/userSetting/index.vue

445 lines
11 KiB
Vue
Raw Normal View History

2025-07-09 15:37:12 +08:00
<template>
<view class="userSetting-container">
2025-07-09 15:37:12 +08:00
<view class="header">
<div class="header-left">
<u-icon
class="header-left-icon"
name="arrow-left"
@click="handleLeftClick"
></u-icon>
</div>
<text class="header-title">设置</text>
2025-07-09 15:37:12 +08:00
<div></div>
</view>
<view class="user-info-content">
<!-- 第一个卡片头像 -->
<view class="info-card">
<view class="info-item avatar-item">
<text class="item-label">头像</text>
<view class="item-content avatar-content">
<view>
<uni-file-picker
v-model="imageValue"
limit="1"
:del-icon="false"
disable-preview
:imageStyles="imageStyles"
file-mediatype="image"
style="font-size: 12rpx"
@select="onSelect"
><text></text>
</uni-file-picker>
</view>
2025-07-09 15:37:12 +08:00
</view>
</view>
</view>
<!-- 第二个卡片姓名和性别 -->
<view class="info-card">
<view class="info-item">
<text class="item-label">姓名</text>
<view class="item-content">
2025-07-10 14:46:13 +08:00
<input
class="item-input"
v-model="userInfo.name"
placeholder="请输入姓名"
placeholder-style="color: #CCCCCC;"
/>
2025-07-09 15:37:12 +08:00
</view>
</view>
<view class="info-item">
<text class="item-label">性别</text>
<view class="item-content" @click="openPicker('gender')">
2025-07-10 14:46:13 +08:00
<text class="placeholder-text" v-if="!userInfo.genderText"
2025-07-09 15:37:12 +08:00
>请选择性别</text
>
2025-07-10 14:46:13 +08:00
<text v-else>{{ userInfo.genderText }}</text>
2025-07-09 15:37:12 +08:00
<text class="arrow-icon">></text>
</view>
</view>
</view>
<!-- 第三个卡片归属地 -->
2025-07-09 15:37:12 +08:00
<view class="info-card">
<view class="info-item">
<text class="item-label">归属地</text>
<view class="item-content" @click="openPicker('region')">
<text class="placeholder-text" v-if="!userInfo.region"
>请选择归属地</text
>
<text v-else>{{ userInfo.region }}</text>
<text class="arrow-icon">></text>
</view>
</view>
</view>
</view>
<div class="user-info-footer">
<u-button class="user-info-footer-button save-button" @click="handleSave">
2025-07-09 15:37:12 +08:00
保存
</u-button>
<u-button
class="user-info-footer-button logout-button"
@click="handleLogout"
>
退出登录
</u-button>
2025-07-09 15:37:12 +08:00
</div>
2025-07-10 14:46:13 +08:00
<!-- 性别选择器 -->
<u-select
v-model="showGenderSelect"
mode="single-column"
:list="genderList"
@confirm="confirmGender"
></u-select>
<!-- 归属地选择器 -->
<u-select
2025-07-10 14:46:13 +08:00
v-model="showRegionSelect"
mode="single-column"
:list="regionList"
@confirm="confirmRegion"
></u-select>
<!-- 消息提示 -->
<u-toast ref="uToast" />
2025-07-09 15:37:12 +08:00
</view>
</template>
<script>
import chinaProvinces from "@/static/common/js/china-provinces.js";
2025-07-09 15:37:12 +08:00
export default {
components: {},
data() {
return {
baseUrl: "",
// imageValue: ['/static/common/images/avatar_default.jpg'],
imageUrl: "",
imageValue: [],
imageStyles: {
width: 52,
height: 52,
border: {
// style: "none",
radius: "50%",
},
},
2025-07-09 15:37:12 +08:00
userInfo: {
2025-07-10 14:46:13 +08:00
name: "",
2025-07-09 15:37:12 +08:00
gender: "",
region: "",
},
2025-07-10 14:46:13 +08:00
// 性别选择器
showGenderSelect: false,
genderList: [
{
label: "男",
value: 0,
2025-07-10 14:46:13 +08:00
},
{
label: "女",
value: 1,
2025-07-10 14:46:13 +08:00
},
],
// 归属地选择器
showRegionSelect: false,
regionList: chinaProvinces,
2025-07-09 15:37:12 +08:00
};
},
mounted() {},
onLoad() {
this.baseUrl = this.$u.http.config.baseUrl;
this.getUserInfo();
2025-07-09 15:37:12 +08:00
},
methods: {
handleLeftClick() {
uni.navigateBack();
},
// 获取上传状态
onSelect(data) {
// console.log(data, "data");
const file = (data && data.tempFiles && data.tempFiles[0]) || {};
const filePath =
file.path || file.url || (file.image && file.image.location);
if (!filePath) {
this.$u.toast("无法获取文件路径");
return;
}
// 上传到后端multipart/form-data
this.$u.api
.UploadSingleImage({
filePath,
name: "file", // 按后端约定的字段名
formData: {
// 可选:向后端传递文件类型等附加信息
// fileType: file.extname || "",
},
})
.then((res) => {
if (res.succeed) {
this.imageUrl = res.data.replace(/\\/g, "/") || "";
this.imageValue = [
{
url: this.baseUrl + "/" + this.imageUrl,
extname: file.extname || "",
name: "",
},
];
this.$u.toast("上传成功");
} else {
this.$u.toast(res.error || "上传失败");
}
});
// .catch((err) => {
// this.$u.toast("上传失败");
// });
2025-07-09 15:37:12 +08:00
},
2025-07-09 15:37:12 +08:00
openPicker(type) {
2025-07-10 14:46:13 +08:00
if (type === "gender") {
this.showGenderSelect = true;
return;
}
if (type === "region") {
this.showRegionSelect = true;
return;
2025-07-09 15:37:12 +08:00
}
},
2025-07-10 14:46:13 +08:00
// 确认性别
confirmGender(e) {
console.log("确认性别", e[0].value);
this.userInfo.gender = e[0].value;
this.userInfo.genderText = e[0].label;
this.showGenderSelect = false;
},
// 确认归属地
confirmRegion(e) {
console.log("确认归属地", e[0].value);
this.userInfo.region = e[0].value;
this.userInfo.regionText = e[0].label;
this.showRegionSelect = false;
},
// 获取用户信息
getUserInfo() {
this.$u.api.GetUserApi({ Id: this.vuex_user.Id }).then((res) => {
const data = res.data[0];
this.userInfo.name = data.name || "";
this.userInfo.gender = data.sex || "";
this.userInfo.region = data.Region || "";
if (data.headSculptureUrl) {
this.imageUrl = data.headSculptureUrl;
this.imageValue = [
{
url: data.headSculptureUrl,
extname: "png",
name: "",
},
];
} else {
this.imageUrl = "";
this.imageValue = [
{
url: "/static/common/images/avatar_default.jpg",
extname: "jpg",
name: "",
},
];
}
});
},
// 保存用户信息
handleSave() {
console.log(this.userInfo, "保存用户信息");
// 表单验证
if (!this.userInfo.name) {
return this.$u.toast("请输入姓名");
}
if (this.userInfo.gender !== 0 && this.userInfo.gender !== 1) {
return this.$u.toast("请选择性别");
}
if (!this.userInfo.region) {
return this.$u.toast("请选择归属地");
}
const params = {
id: this.vuex_user.Id,
name: this.userInfo.name,
sex: this.userInfo.gender,
shen: this.userInfo.region,
headSculptureUrl: this.imageUrl,
};
this.$u.api.UpdateUserApi(params).then((res) => {
if (res.succeed) {
this.$refs.uToast.show({
title: "保存成功",
type: "success",
});
} else {
this.$refs.uToast.show({
title: res.error || "保存失败",
type: "error",
});
}
});
},
// 退出登录
handleLogout() {
this.$store.commit("logout");
uni.reLaunch({
// 与项目其余位置保持一致的登录页路径
url: "/pages/login/login/index?type=" + this.vuex_userType,
});
},
2025-07-09 15:37:12 +08:00
},
};
</script>
<style lang="scss" scoped>
.userSetting-container {
2025-07-09 15:37:12 +08:00
min-height: 100vh;
padding-bottom: calc(112rpx + env(safe-area-inset-bottom));
padding: 32rpx;
padding-top: calc(88rpx + 40rpx);
background-image: url(/static//common/images/images_bg.png);
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: center;
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
// background-color: #ffffff;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
z-index: 99;
.header-left {
font-size: 36rpx;
}
.header-title {
font-size: 36rpx;
font-weight: 500;
color: #333333;
}
}
.user-info-content {
.info-card {
background-color: #ffffff;
border-radius: 20rpx;
padding: 0 32rpx;
margin-bottom: 32rpx;
.info-item {
height: 110rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #f2f2f2;
&:last-child {
border-bottom: none;
}
.item-label {
font-family: PingFang SC;
font-size: 28rpx;
color: #333333;
}
.item-content {
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
font-size: 28rpx;
color: #333333;
.item-input {
text-align: right;
width: 100%;
font-size: 28rpx;
}
.placeholder-text {
color: #cccccc;
}
.arrow-icon {
margin-left: 10rpx;
color: #cccccc;
}
}
&.avatar-item {
.avatar-content {
display: flex;
align-items: center;
}
.avatar-image {
width: 68rpx;
height: 68rpx;
border-radius: 50%;
}
}
}
}
}
.user-info-footer {
position: fixed;
bottom: 32rpx;
left: 0;
right: 0;
padding: 0 32rpx;
.user-info-footer-button {
width: 100%;
height: 85rpx;
border-radius: 16rpx;
opacity: 0.9;
font-weight: bold;
}
.save-button {
color: #ffffff;
background: #4f6aff;
margin-bottom: 32rpx;
}
.logout-button {
color: #ff4f4f;
background: #ffffff;
2025-07-09 15:37:12 +08:00
}
}
}
/* 响应式布局 - PC端样式 */
@media screen and (min-width: 768px) {
.userInfo-container {
.user-info-content {
max-width: 1200rpx;
margin: 0 auto;
}
}
}
</style>