Ai_GirlFriend/xuniYou/pages/mine/index.vue

1036 lines
22 KiB
Vue
Raw Normal View History

2026-01-31 19:15:41 +08:00
<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>