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>
|