Ai_GirlFriend/xuniYou/pages/mine/index.vue
2026-01-31 19:15:41 +08:00

1036 lines
22 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page fc">
<uni-nav-bar fixed statusBar right-icon="gear" background-color="transparent" :border="false"
:style="{ '--right-padding': getMenuInfoList + 'px' }" @clickRight="tosetUp" title="我的"></uni-nav-bar>
<view class="back"></view>
<scroll-view scroll-y="true" class="scroll-view f1" show-scrollbar>
<view class="body">
<view class="user">
<view class="user_body">
<view class="user_content fa">
<view class="user_wrapper">
<image class="user_avatar"
:src="getBobbiesList.avatar ? getBobbiesList.avatar : '/static/images/avatar.png'"
mode="aspectFill"></image>
<!-- APP环境下使用普通按钮 -->
<!-- #ifdef APP-PLUS -->
<button class="user_button" @click="chooseAvatar">
选择头像
</button>
<!-- #endif -->
<!-- 小程序环境下使用微信原生头像选择 -->
<!-- #ifndef APP-PLUS -->
<button class="user_button" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
</button>
<!-- #endif -->
</view>
<view class="user_module f1">
<view class="user_name fa">
<image class="user_logo" v-if="getBobbiesList.vip >= 1"
src="https://nvlovers.oss-cn-qingdao.aliyuncs.com/uploads/20251231/c7dc9393a0d08ba379cb24b485e3e43e.png"
mode="widthFix"></image>
{{ getBobbiesList.nickname ? getBobbiesList.nickname : '四青上将'
}}
<image class="user_name_image" @click="nameClick" src="/static/images/mine_edit.png"
mode="widthFix">
</image>
</view>
<view class="user_id">
ID{{ getBobbiesList.user_number ? getBobbiesList.user_number : '135497645' }}
</view>
</view>
</view>
<!-- <view class="user_tag">隔壁班的下坡男神</view> -->
<view class="user_detail fa wp">
<view class="user_item faj" v-for="(item, index) in getBobbiesList.hobbies" :key="index">
{{ item }}
<!-- <image v-if="editStats" src="/static/images/replacement_delete.png"></image> -->
</view>
<image class="user_edit" v-if="!editStats" @click="editClick"
src="/static/images/mine_edit.png" mode="widthFix"></image>
<view class="user_text faj" @click="alertClick()" v-if="editStats">+</view>
<view class="user_text faj" @click="successClick" v-if="editStats">完成</view>
</view>
</view>
</view>
<view class="member" @click="tomember">
<view class="member_content" v-if="getBobbiesList.vip == 0">
<view class="member_title">开启您会员之旅</view>
<view class="member_desc">首次购买最低可享受8元无限畅聊+语音</view>
<view class="member_btn faj">开通会员</view>
</view>
<view class="member_contents fa" v-if="getBobbiesList.vip != 0">
<image
src="https://nvlovers.oss-cn-qingdao.aliyuncs.com/uploads/20260104/06d13ae30ec708df26b922bd101a70e4.png"
mode="widthFix"></image>
<view class="member_module">
<view class="member_title">您已开通VIP会员</view>
<view class="member_time">到期时间: {{ vipEndTimeFormatted }}</view>
</view>
</view>
</view>
<view class="intimate" @click="toIntimacy">
<view class="intimate_content fa">
<image src="/static/images/index_intimate.png" mode="widthFix"></image>
<view class="intimate_text">亲密度Lv.{{ getBobbiesList.level ? getBobbiesList.level : 0 }}</view>
</view>
<view class="intimate_module fa sb">
<view class="intimate_detail">
<view class="intimate_level">Lv.{{ getBobbiesList.level ? getBobbiesList.level : 0 }}</view>
<view class="intimate_progress fa">
<view class="intimate_line" :style="{ width: calculateProgressWidth() + 'rpx' }">
</view>
</view>
<!-- next_level_intimacy总亲密度intimacy当前的intimacy_percent百分比 -->
</view>
<image :src="loverBasicList.image_url ? loverBasicList.image_url : '/static/images/avatar.png'"
mode="aspectFill"></image>
</view>
<view class="intimate_desc">每日登录、消费将提升亲密度</view>
</view>
<view class="list fa sb">
<view class="list_content f1 faj" @click="toaccount">
<view class="list_module">
<view class="list_title">我的金币</view>
<view class="list_num">{{ getBobbiesList.money ? getBobbiesList.money : 0 }}</view>
</view>
<image class="list_logo" src="/static/images/mine_b1.png" mode="aspectFill"></image>
</view>
<view class="list_content f1 faj" @click="tostore">
<view class="list_module">
<view class="list_title">金币商店</view>
<view class="list_desc">装扮来了</view>
</view>
<image class="list_logo" src="/static/images/mine_b2.png" mode="aspectFill"></image>
</view>
</view>
<image class="banner" @click="toinvite"
src="https://nvlovers.oss-cn-qingdao.aliyuncs.com/uploads/20251226/87ad5de553f5a119109468d2e27b21c1.png"
mode="widthFix"></image>
</view>
</scroll-view>
<tab-bar></tab-bar>
<view class="alert faj" v-if="alertStats">
<view class="alert_content">
<image src="/static/images/close.png" mode="widthFix" @click="alertClick()"></image>
<view class="alert_title">添加标签</view>
<view class="alert_module fa wp">
<view class="alert_item" :class="{ 'alert_active': selectedHobbies.includes(item.name) }"
v-for="(item, index) in selectCList" :key="index" @click="toggleHobby(item.name)">
{{ item.name }}
</view>
</view>
<view class="alert_detail fa">
<input class="f1" v-model="Addform.name" placeholder="请输入自定义标签" placeholder-class="alert_input" />
<view class="alert_add faj" @click="AddClick">添加</view>
</view>
<view class="alert_sure faj"><text class="faj" @click="saveHobbies()">确定</text></view>
</view>
</view>
<view class="name faj" v-if="nameStats">
<view class="name_content">
<image src="/static/images/close.png" mode="widthFix" @click="nameClick()"></image>
<view class="name_title">修改名称</view>
<view class="name_detail fa">
<input type="nickname" class="f1" v-model="form.nickname" placeholder="请输入名称"
placeholder-class="name_input" />
</view>
<view class="name_sure faj"><text class="faj" @click="saveName()">确定</text></view>
</view>
</view>
</view>
</template>
<script>
import {
GetBobbies,
GetUserBasic,
AddBobbies,
SetUserBasicSingle,
} from '@/utils/api.js'
import notHave from '@/components/not-have.vue';
import topSafety from '@/components/top-safety.vue';
import tabBar from '@/components/tab-bar.vue';
import Image from '../create/image.vue';
export default {
components: {
notHave,
topSafety,
tabBar,
},
data() {
return {
global: this.baseURL,
form: {
nickname: '',
hobbies: [],
avatar: ''
},
editStats: false,
alertStats: false,
nameStats: false,
selectCList: [],
getBobbiesList: '',
Addform: {
name: ''
},
selectedHobbies: [],
loverBasicList: '',
getMenuInfoList: '',
}
},
computed: {
vipEndTimeFormatted() {
if (!this.getBobbiesList.vip_endtime) return '';
// 只取日期部分,去掉时间部分
return this.getBobbiesList.vip_endtime.split(' ')[0];
}
},
onLoad() {
},
onShow() {
// #ifdef MP-WEIXIN
this.getMenuInfo()
// #endif
this.getBobbies()
this.getUserBasic()
this.loverBasicList = uni.getStorageSync('loverBasicList') || '';
},
methods: {
getBobbies() {
GetBobbies({}).then(res => {
if (res.code == 1) {
this.selectCList = res.data
} else {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
}
})
},
getUserBasic() {
GetUserBasic({}).then(res => {
if (res.code == 1) {
this.getBobbiesList = res.data
if (res.data.hobbies && Array.isArray(res.data.hobbies)) {
this.selectedHobbies = [...res.data.hobbies] // 复制数组,避免引用问题
}
console.log('getBobbiesList', this.getBobbiesList)
uni.setStorageSync('userinfo', this.getBobbiesList);
} else {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
}
})
},
addBobbies() {
AddBobbies(this.Addform).then(res => {
if (res.code == 1) {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
this.Addform.name = ''
this.getBobbies()
} else {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
}
})
},
setUserBasicSingle() {
console.log(this.form)
SetUserBasicSingle(this.form).then(res => {
if (res.code == 1) {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
this.getUserBasic()
this.form.nickname = ''
this.form.hobbies = []
this.form.avatar = ''
this.alertStats = false;
} else {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
}
})
},
loverBasic() {
LoverBasic().then(res => {
if (res.code == 1) {
this.loverBasicList = res.data
} else {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
}
})
},
toggleHobby(name) {
const index = this.selectedHobbies.indexOf(name);
if (index > -1) {
// 如果已存在,则移除
this.selectedHobbies.splice(index, 1);
} else {
// 如果不存在,则添加
this.selectedHobbies.push(name);
}
},
// 小程序环境下选择头像
// #ifndef APP-PLUS
onChooseAvatar(e) {
console.log(this.baseURL)
uni.uploadFile({
url: this.baseURL + '/api/common/upload',
filePath: e.detail.avatarUrl,
name: 'file',
header: {
"Content-Type": "application/x-www-form-urlencoded",
'token': uni.getStorageSync('token'),
},
success: (res) => {
var data = JSON.parse(res.data);
console.log(data)
this.form.avatar = data.data.fullurl;
console.log(this.form.avatar)
this.setUserBasicSingle()
}
});
},
// #endif
calculateProgressWidth() {
// next_level_intimacy总亲密度intimacy当前的intimacy_percent百分比
if (this.getBobbiesList.intimacy == null || this.getBobbiesList.next_level_intimacy == null) {
return 0;
}
// 根据比例计算实际宽度确保不超过最大宽度400rpx
const actualWidth = (this.getBobbiesList.intimacy / this.getBobbiesList.next_level_intimacy) * 400;
const result = Math.min(actualWidth, 400);
return result;
},
// APP环境下选择头像
// #ifdef APP-PLUS
chooseAvatar() {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const avatarPath = res.tempFilePaths[0];
this.uploadAvatar(avatarPath);
},
fail: (err) => {
console.error('选择头像失败:', err);
uni.showToast({
title: '选择头像失败',
icon: 'none'
});
}
});
},
// #endif
// 上传头像
uploadAvatar(avatarPath) {
uni.uploadFile({
url: this.baseURL + '/api/common/upload',
filePath: avatarPath,
name: 'file',
header: {
"Content-Type": "application/x-www-form-urlencoded",
'token': uni.getStorageSync('token'),
'sid': this.sid
},
success: (res) => {
var data = JSON.parse(res.data);
console.log(data)
this.form.avatar = data.data.fullurl;
console.log(this.form.avatar)
this.setUserBasicSingle()
},
fail: (err) => {
console.error('上传头像失败:', err);
uni.showToast({
title: '上传头像失败',
icon: 'none'
});
}
});
},
saveName() {
this.nameStats = false
this.setUserBasicSingle()
},
AddClick() {
this.addBobbies()
},
editClick() {
this.editStats = true
},
successClick() {
this.editStats = false
},
alertClick() {
if (this.alertStats) {
if (this.getBobbiesList.hobbies && Array.isArray(this.getBobbiesList.hobbies)) {
this.selectedHobbies = [...this.getBobbiesList.hobbies];
}
this.alertStats = false
} else {
this.alertStats = true
}
},
nameClick() {
if (this.nameStats) {
this.nameStats = false
} else {
this.nameStats = true
}
},
tosetUp() {
uni.navigateTo({
url: '/pages/mine/setUp'
})
},
tomember() {
uni.navigateTo({
url: '/pages/mine/member'
})
},
toaccount() {
uni.navigateTo({
url: '/pages/mine/account'
})
},
tostore() {
if (this.getBobbiesList.reg_step != 4) {
uni.showToast({
title: '请先完善恋人资料',
icon: 'none',
position: 'top'
})
return
} else {
uni.navigateTo({
url: '/pages/mine/store'
})
}
},
toinvite() {
uni.navigateTo({
url: '/pages/mine/invite'
})
},
toIntimacy() {
// 检查是否开启了青少年模式
const underAgeEnabled = uni.getStorageSync('underAgeEnabled');
if (underAgeEnabled) {
uni.showToast({
title: '青少年模式下无法访问此功能',
icon: 'none',
position: 'top'
});
return;
}
if (this.getBobbiesList.reg_step != 4) {
uni.showToast({
title: '请先完善恋人资料',
icon: 'none',
position: 'top'
})
return
} else {
uni.navigateTo({
url: '/pages/index/intimacy'
})
}
},
saveHobbies() {
this.form.hobbies = [...this.selectedHobbies];
console.log(this.form.hobbies);
this.setUserBasicSingle()
},
getMenuInfo() {
const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
const systemInfo = uni.getSystemInfoSync();
console.log('胶囊信息:', menuButtonInfo);
// 胶囊宽度
const capsuleWidth = menuButtonInfo.width;
// 胶囊距离右侧的距离 = 屏幕宽度 - 胶囊右边界的x坐标
const distanceFromRight = systemInfo.windowWidth - menuButtonInfo.right;
console.log('胶囊宽度:', capsuleWidth);
console.log('胶囊距离右侧的距离:', distanceFromRight);
this.getMenuInfoList = capsuleWidth + distanceFromRight;
return {
width: capsuleWidth,
distanceFromRight: distanceFromRight,
menuButtonInfo: menuButtonInfo
};
},
}
}
</script>
<style>
page {
background: #F7F7F7;
}
</style>
<style>
.page {
position: relative;
height: 100vh;
overflow: hidden;
}
.scroll-view {
overflow: hidden;
}
.body {
position: relative;
padding: 40rpx 40rpx 200rpx 40rpx;
}
.back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 596rpx;
background: linear-gradient(180deg, #FFE3E9 0%, #F7F7F7 100%);
}
.user {
position: relative;
width: 100%;
background: linear-gradient(rgba(250, 234, 255, 0.5) 0%, rgba(255, 255, 255, 0.5) 100%);
border: 3rpx solid #FFFFFF;
border-radius: 24rpx;
}
.user_body {
position: relative;
padding: 36rpx 30rpx 16rpx 30rpx;
}
.user_content {
position: relative;
}
.user_wrapper {
position: relative;
display: inline-block;
}
.user_avatar {
width: 128rpx;
height: 128rpx;
border-radius: 50%;
flex-shrink: 0;
display: block;
}
.user_button {
position: absolute;
top: 0;
left: 0;
width: 128rpx;
height: 128rpx;
border-radius: 50%;
opacity: 0;
/* 使按钮透明,但保持可点击 */
background: transparent;
border: none;
}
.user_button::after {
border: none;
/* 去除按钮默认边框 */
}
.user_module {
position: relative;
margin: 0 0 0 22rpx;
}
.user_logo {
margin: 0 14rpx 0 0;
width: 50rpx;
height: 50rpx;
display: block;
}
.user_name {
font-weight: 500;
font-size: 36rpx;
color: #000000;
line-height: 50rpx;
}
.user_name_image {
margin: 0 0 0 14rpx;
width: 26rpx;
height: 26rpx;
}
.user_id {
margin: 10rpx 0 0 0;
font-weight: 400;
font-size: 24rpx;
color: #A7A7A7;
line-height: 50rpx;
}
.user_tag {
margin: 24rpx 0 0 0;
font-weight: 500;
font-size: 30rpx;
color: #333333;
line-height: 50rpx;
}
.user_detail {
position: relative;
margin: 24rpx 0 0 0;
}
.user_item {
position: relative;
margin: 0 20rpx 20rpx 0;
padding: 0 20rpx;
font-weight: 400;
font-size: 26rpx;
color: #FF51B3;
line-height: 50rpx;
background: rgba(255, 81, 179, 0.1);
border-radius: 10rpx;
}
.user_item image {
position: absolute;
right: 0;
top: 0;
width: 20rpx;
height: 20rpx;
}
.user_edit {
margin: 0 20rpx 20rpx 0;
width: 30rpx;
height: 30rpx;
}
.user_text {
margin: 0 20rpx 20rpx 0;
padding: 0 18rpx;
font-weight: 400;
font-size: 26rpx;
color: #FF51B3;
line-height: 50rpx;
background: #FFFFFF;
border-radius: 10rpx;
}
.member {
position: relative;
margin: 30rpx 0 0 0;
box-sizing: border-box;
}
.member_content {
position: relative;
padding: 60rpx 30rpx;
width: 100%;
background: linear-gradient(135deg, #8EA0FF 0%, #8449FE 100%);
border-radius: 32rpx;
box-sizing: border-box;
}
.member_contents {
position: relative;
padding: 0 30rpx;
width: 100%;
background: linear-gradient(135deg, #FF72C7 0%, #8449FE 100%);
border-radius: 32rpx;
box-sizing: border-box;
}
.member_contents image {
margin: 0 15rpx 0 0;
width: 220rpx;
height: 220rpx;
display: block;
}
.member_title {
width: 350rpx;
font-weight: 500;
font-size: 34rpx;
color: #FCFCFC;
line-height: 41rpx;
}
.member_desc {
margin: 18rpx 0 0 0;
font-weight: 400;
font-size: 32rpx;
color: #DBDBDB;
line-height: 38rpx;
}
.member_time {
margin: 18rpx 0 0 0;
font-weight: 400;
font-size: 28rpx;
color: #FCFCFC;
line-height: 38rpx;
}
.member_btn {
position: absolute;
top: 28rpx;
right: 40rpx;
padding: 15rpx 20rpx 15rpx 32rpx;
font-weight: 400;
font-size: 30rpx;
color: #5909FF;
line-height: 36rpx;
background: linear-gradient(134deg, #D0E3FF 0%, #8973FF 100%);
clip-path: polygon(20rpx 0%, 100% 0%, 100% 100%, 20rpx 100%, 0% 100%);
border-radius: 10rpx;
}
.intimate {
position: relative;
margin: 30rpx 0 0 0;
padding: 24rpx 32rpx;
background: #FFFFFF;
border-radius: 32rpx;
}
.intimate_content {
position: relative;
}
.intimate_content image {
width: 40rpx;
height: 40rpx;
}
.intimate_text {
margin: 0 0 0 24rpx;
font-weight: 500;
font-size: 32rpx;
color: #222222;
line-height: 50rpx;
}
.intimate_module {
position: relative;
}
.intimate_detail {
position: relative;
}
.intimate_level {
margin: 0 0 0 30rpx;
font-weight: 500;
font-size: 32rpx;
line-height: 50rpx;
color: linear-gradient(28.45468288413665deg, #E72F9F 0%, #9147F9 100%);
}
.intimate_progress {
position: relative;
margin: 12rpx 0 0 0;
width: 400rpx;
height: 8rpx;
background: #FFDDF0;
clip-path: polygon(1% 0%, 100% 0%, 99% 100%, 0% 100%);
}
.intimate_line {
position: absolute;
top: 0;
left: 0;
height: 100%;
background: linear-gradient(90deg, #8D48FE 0%, #EC2E99 100%);
clip-path: polygon(1% 0%, 100% 0%, 99% 100%, 0% 100%);
}
.intimate_module image {
width: 109rpx;
height: 109rpx;
display: block;
border-radius: 50%;
flex-shrink: 0;
}
.intimate_desc {
font-weight: 400;
font-size: 26rpx;
color: #222222;
line-height: 50rpx;
}
.list {
position: relative;
margin: 30rpx 0 0 0;
}
.list_content {
position: relative;
margin: 0 50rpx 0 0;
padding: 32rpx 15rpx 34rpx 34rpx;
background: #FFFFFF;
border-radius: 32rpx;
justify-content: space-between;
}
.list_content:nth-child(2) {
margin: 0 0 0 0;
}
.list_module {
/* position: relative; */
}
.list_title {
font-weight: 500;
font-size: 32rpx;
color: #222222;
line-height: 50rpx;
}
.list_num {
margin: 10rpx 0 0 0;
font-weight: 700;
font-size: 40rpx;
color: #222222;
line-height: 50rpx;
text-align: center;
}
.list_desc {
margin: 10rpx 0 0 0;
font-weight: 400;
font-size: 30rpx;
color: #A7A7A7;
line-height: 50rpx;
/* text-align: center; */
}
.list_logo {
/* margin: 0 0 0 30rpx; */
width: 82rpx;
height: 82rpx;
/* display: block; */
}
.banner {
margin: 30rpx 0 0 0;
width: 100%;
display: block;
border-radius: 32rpx;
}
.alert {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0 40rpx;
box-sizing: border-box;
background: rgba(0, 0, 0, 0.2);
z-index: 2;
}
.alert_content {
position: relative;
background: #FFFFFF;
border-radius: 20rpx;
padding: 80rpx 50rpx;
}
.alert_content image {
position: absolute;
right: 20rpx;
top: 20rpx;
width: 30rpx;
height: 30rpx;
}
.alert_title {
font-weight: 500;
font-size: 32rpx;
color: #161616;
line-height: 38rpx;
text-align: center;
}
.alert_module {
position: relative;
margin: 30rpx 0 0 0;
}
.alert_item {
margin: 0 20rpx 20rpx 0;
padding: 0 18rpx;
font-weight: 400;
font-size: 26rpx;
color: #9E9E9E;
line-height: 50rpx;
background: #F6F8FA;
border-radius: 10rpx;
}
.alert_active {
color: #FF51B3;
background: #FCE6F3;
}
.alert_detail {
position: relative;
margin: 20rpx 0 0 0;
}
.alert_detail input {
padding: 15rpx;
font-weight: 400;
font-size: 26rpx;
color: #000000;
line-height: 50rpx;
border-radius: 12rpx;
border: 1px solid #989898;
}
.alert_input {
color: #161616;
}
.alert_add {
margin: 0 0 0 10rpx;
padding: 15rpx 30rpx;
font-weight: 400;
font-size: 26rpx;
color: #FFFFFF;
line-height: 50rpx;
background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
border-radius: 10rpx;
}
.alert_sure {
margin: 20rpx 0 0 0;
}
.alert_sure text {
padding: 15rpx 60rpx;
font-weight: 400;
font-size: 26rpx;
color: #FFFFFF;
line-height: 50rpx;
background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
border-radius: 10rpx;
}
.name {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
padding: 0 40rpx;
box-sizing: border-box;
background: rgba(0, 0, 0, 0.2);
z-index: 2;
}
.name_content {
position: relative;
background: #FFFFFF;
border-radius: 20rpx;
padding: 60rpx 100rpx;
}
.name_content image {
position: absolute;
right: 20rpx;
top: 20rpx;
width: 30rpx;
height: 30rpx;
}
.name_title {
font-weight: 500;
font-size: 32rpx;
color: #161616;
line-height: 38rpx;
text-align: center;
}
.name_detail {
position: relative;
margin: 20rpx 0 0 0;
}
.name_detail input {
padding: 15rpx;
font-weight: 400;
font-size: 26rpx;
color: #000000;
line-height: 50rpx;
border-radius: 12rpx;
border: 1px solid #989898;
}
.name_input {
color: #161616;
}
.name_sure {
margin: 20rpx 0 0 0;
}
.name_sure text {
padding: 15rpx 60rpx;
font-weight: 400;
font-size: 26rpx;
color: #FFFFFF;
line-height: 50rpx;
background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
border-radius: 10rpx;
}
.uni-navbar__header-btns {
padding-right: var(--right-padding, 0);
}
</style>