280 lines
6.5 KiB
Vue
280 lines
6.5 KiB
Vue
<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> |