YingXingAI/pages/my/myDetails/myInterest.vue

280 lines
6.5 KiB
Vue
Raw Normal View History

2025-06-30 14:43:02 +08:00
<template>
<view class="flex-col preference-page">
<u-navbar title="兴趣爱好" :border-bottom="false" />
<view class="selected-count">
已选择{{ selectedInterests.length }}/10
<text class="desc"
>您选择的标签将影响系统推荐给你的信息类型</text
>
</view>
<view class="selected-tags">
<view
v-for="item in selectedInterests"
:key="item.lableId"
class="tag selected"
>
{{ item.lableName }}
<image
class="close-btn"
src="/static/common/img/handDelete.png"
@click.stop="removeInterest(item)"
></image>
</view>
</view>
<view class="line"></view>
<view class="all-tags">
<view class="title">兴趣爱好</view>
<view class="tags-list">
<view
v-for="item in interestList"
:key="item.lableId"
class="tag"
:class="{ selected: selectedInterests.includes(item) }"
@click="toggleInterest(item)"
>{{ item.lableName }}</view
>
</view>
</view>
<view class="line-shadow"></view>
<view class="btn-box">
<u-button
shape="circle"
class="button"
type="primary"
@click="finishPreference"
>完成</u-button
>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
export default {
data() {
return {
interestList: [],
selectedInterests: [],
};
},
created(){
this.initData()
},
onShow(){
this.echoData()
},
methods: {
async initData() {
await this.GetInterestLable()
},
echoData(){
// 如果有兴趣则回显,并在全部中过滤掉已选择的
if (this.vuex_user_hobby) {
this.selectedInterests = JSON.parse(JSON.stringify(this.vuex_user_hobby))
// 修改过滤逻辑
const selectedIds = this.selectedInterests.map(item => item.lableId)
const hobbyIds = this.selectedInterests.map(item => {
return { lableId: item.lableId };
})
this.$u.vuex("vuex_hobby", hobbyIds);
this.interestList = this.interestList.filter(item => !selectedIds.includes(item.lableId))
}
},
async GetInterestLable() {
const res = await this.$u.apiList.GetInterestLable();
this.interestList = res;
},
toggleInterest(item) {
// 从 interestList 中移除
const interestIndex = this.interestList.findIndex(
(i) => i.lableId === item.lableId
);
if (interestIndex > -1) {
// 添加到已选择列表
if (this.selectedInterests.length >= 10) {
this.$refs.uToast.show({
title: "最多选择10个",
type: "error",
});
return;
}
this.interestList.splice(interestIndex, 1);
this.selectedInterests.push(item);
}
},
removeInterest(item) {
// 从已选择列表中移除
const selectedIndex = this.selectedInterests.findIndex(
(i) => i.lableId === item.lableId
);
if (selectedIndex > -1) {
this.selectedInterests.splice(selectedIndex, 1);
// 添加回 interestList
this.interestList.push(item);
}
},
// 完成偏好设置
async finishPreference() {
if (
this.selectedInterests.length === 0
) {
this.$refs.uToast.show({
title: "请至少选择一个标签",
type: "error",
});
return;
}
const interestList = this.selectedInterests.map((item) => ({
lableId: item.lableId,
}));
// console.log('interestList',interestList,this.selectedInterests);
this.$u.vuex("vuex_user_hobby", this.selectedInterests);
this.$u.vuex("vuex_hobby", interestList);
// 保存到vuex里面
uni.navigateBack({
delta: 1,
});
},
},
};
</script>
<style lang="scss" scoped>
.preference-page {
background: #fff;
height: calc(100vh - 200rpx);
display: flex;
flex-direction: column;
overflow-y: auto;
.selected-count {
padding: 24rpx;
font-weight: bold;
font-size: 32rpx;
line-height: 48rpx;
color: rgba(0, 0, 0, 0.9);
.desc {
display: block;
font-weight: 400;
font-size: 24rpx;
color: rgba(0, 0, 0, 0.6);
line-height: 40rpx;
margin-top: 8rpx;
}
}
.selected-tags {
padding: 0 24rpx;
display: flex;
flex-wrap: wrap;
gap: 24rpx 24rpx;
.tag {
display: flex;
align-items: center;
background: #3cb5fb;
color: #fff;
border-radius: 64rpx;
padding: 20rpx;
font-size: 28rpx;
position: relative;
// max-width: 200rpx;
margin-right: 0;
margin-bottom: 0;
box-sizing: border-box;
justify-content: flex-start;
gap: 6rpx;
}
.close-btn {
font-size: 28rpx;
margin-right: 8rpx;
cursor: pointer;
color: #fff;
font-weight: bold;
line-height: 1;
display: inline-block;
width: 32rpx;
height: 32rpx;
text-align: center;
border-radius: 50%;
background: rgba(255, 255, 255, 0.18);
}
}
.line {
width: 100%;
height: 4rpx;
background: #f6f8f9;
margin-top: 24rpx;
margin-bottom: 44rpx;
}
.line-shadow {
width: 100%;
height: 2rpx;
background: #ffffff;
box-shadow: 0rpx -6rpx 12rpx 0rpx rgba(0, 0, 0, 0.05);
margin-top: 56rpx;
}
.all-tags {
padding: 0 24rpx;
.title {
font-weight: bold;
font-size: 32rpx;
color: rgba(0, 0, 0, 0.9);
margin-bottom: 18rpx;
}
.tags-list {
display: flex;
flex-wrap: wrap;
gap: 24rpx 24rpx;
margin-bottom: 32rpx;
.tag {
background: #f6f8f9;
color: #333;
border-radius: 200rpx;
padding: 20rpx 32rpx;
font-size: 28rpx;
&.selected {
background: #3cb5fb;
color: #fff;
}
}
.industry-tag {
background: #f0f4f8;
color: #333;
border-radius: 200rpx;
padding: 20rpx 32rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
text-align: center;
line-height: 28rpx;
box-sizing: border-box;
&.selected {
background: #3cb5fb;
color: #fff;
}
}
}
}
.btn-box {
position: fixed;
bottom: 62rpx;
left: 0;
right: 0;
padding: 0 24rpx;
}
.button {
margin: 48rpx 0 0 0;
width: 100%;
}
}
</style>