304 lines
8.9 KiB
Vue
304 lines
8.9 KiB
Vue
<template>
|
||
<div class="followBox">
|
||
<div class="followBox-title">
|
||
<span>我的</span>
|
||
<span class="hightText">关注</span>
|
||
</div>
|
||
<div class="radio-group">
|
||
<label class="radio-item" style="margin-right: 25px;" :class="{ active: publish_type === '1' }">
|
||
<input type="radio" v-model="publish_type" value="1" @change="handleTypeChange">
|
||
<span class="radio-text">企业商品</span>
|
||
</label>
|
||
<label class="radio-item" :class="{ active: publish_type === '2' }">
|
||
<input type="radio" v-model="publish_type" value="2" @change="handleTypeChange">
|
||
<span class="radio-text">企业需求</span>
|
||
</label>
|
||
</div>
|
||
<div v-loading="loadingBox" class="history-list" v-if="productList.length > 0">
|
||
<div class="history-item" v-for="item in productList" :key="item.id">
|
||
<div class="history-date">
|
||
<span class="date-text">{{ formatBrowseDate(item.browse_date) }}</span>
|
||
<span class="relative-time">{{ getRelativeTime(item.browse_date) }}</span>
|
||
</div>
|
||
<div class="history-content">
|
||
<productCard
|
||
contentType="favorite"
|
||
:productList="item.products"
|
||
:type="publish_type == '1' ? 'homePage' : 'supplyAndDemandSquare'"
|
||
@delete-item="handleDeleteItem">
|
||
</productCard>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="empty-state" v-else>
|
||
<div class="empty-icon">📋</div>
|
||
<div class="empty-text">暂无关注记录</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import { reqFavoriteSearch } from '@/api/ncmatch';
|
||
import productCard from '../mainPage/productCard/index.vue';
|
||
import { formatBrowseDate, getRelativeTime } from './tool.js';
|
||
export default {
|
||
name: 'followBox',
|
||
data() {
|
||
return {
|
||
loadingBox:false,
|
||
productList: [],
|
||
value1: null,
|
||
publish_type: '1', // 默认选择企业商品
|
||
|
||
myProductList: [
|
||
|
||
]
|
||
}
|
||
},
|
||
created() {
|
||
this.reqFavoriteSearch();
|
||
},
|
||
components: {
|
||
productCard
|
||
},
|
||
methods: {
|
||
formatBrowseDate,
|
||
getRelativeTime,
|
||
handleTypeChange() {
|
||
// 当类型改变时重新获取数据
|
||
this.reqFavoriteSearch();
|
||
},
|
||
reqFavoriteSearch() {
|
||
this.loadingBox = true;
|
||
reqFavoriteSearch({
|
||
url_list: window.location.href,
|
||
publish_type: this.publish_type // 传递发布类型参数
|
||
}).then(res => {
|
||
this.loadingBox = false;
|
||
if (res.status) {
|
||
// 处理数据结构,将product_info的子项提升到上一级
|
||
this.productList = this.flattenProductInfo(res.data.favorites);
|
||
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
},
|
||
/**
|
||
* 将product_info的所有子项提升到products中每个产品的上一级,去掉product_info字段
|
||
* @param {Array} historyList - 原始的历史记录列表
|
||
* @returns {Array} 处理后的历史记录列表
|
||
*/
|
||
flattenProductInfo(historyList) {
|
||
if (!Array.isArray(historyList)) {
|
||
return [];
|
||
}
|
||
|
||
return historyList.map(historyItem => {
|
||
if (historyItem.products && Array.isArray(historyItem.products)) {
|
||
// 处理每个历史记录中的products数组
|
||
const flattenedProducts = historyItem.products.map(product => {
|
||
if (product.product_info) {
|
||
// 将product_info的所有属性合并到product的上一级
|
||
const flattenedProduct = { ...product };
|
||
|
||
// 遍历product_info的所有属性
|
||
Object.keys(product.product_info).forEach(key => {
|
||
if(key == 'id'){
|
||
flattenedProduct.productid = product.product_info.id;
|
||
}
|
||
// 如果上一级已经有同名属性,则跳过(避免覆盖)
|
||
if (!(key in flattenedProduct)) {
|
||
flattenedProduct[key] = product.product_info[key];
|
||
}
|
||
});
|
||
|
||
// 删除product_info字段
|
||
delete flattenedProduct.product_info;
|
||
|
||
return flattenedProduct;
|
||
}
|
||
return product;
|
||
});
|
||
|
||
return {
|
||
...historyItem,
|
||
products: flattenedProducts
|
||
};
|
||
}
|
||
return historyItem;
|
||
});
|
||
},
|
||
/**
|
||
* 处理删除事件,从列表中移除被删除的项目
|
||
* @param {string} deletedId - 被删除项目的ID
|
||
*/
|
||
handleDeleteItem(deletedId) {
|
||
// 遍历productList,找到包含被删除产品的历史记录
|
||
for (let i = 0; i < this.productList.length; i++) {
|
||
const historyItem = this.productList[i];
|
||
if (historyItem.products && Array.isArray(historyItem.products)) {
|
||
// 在products数组中查找并删除指定ID的产品
|
||
const productIndex = historyItem.products.findIndex(product => product.id === deletedId);
|
||
if (productIndex !== -1) {
|
||
// 删除该产品
|
||
historyItem.products.splice(productIndex, 1);
|
||
|
||
// 如果该历史记录下没有产品了,删除整个历史记录
|
||
if (historyItem.products.length === 0) {
|
||
this.productList.splice(i, 1);
|
||
}
|
||
|
||
// 更新视图
|
||
this.$forceUpdate();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style>
|
||
.followBox-title {
|
||
font-size: 32px;
|
||
font-weight: bold;
|
||
color: #363a46;
|
||
margin-bottom: 15px;
|
||
|
||
.hightText {
|
||
background: linear-gradient(90deg, #275aff, #2ebdfa);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
display: inline-block;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
|
||
.radio-group-container {
|
||
width: 100% !important;
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
max-width: 1400px;
|
||
}
|
||
|
||
.radio-group {
|
||
display: flex;
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.radio-item {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 8px 16px;
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
background: #fff;
|
||
border: 1px solid #e8e8e8;
|
||
margin-right: 4px;
|
||
font-size: 16px !important;
|
||
|
||
&:last-child {
|
||
margin-right: 0;
|
||
}
|
||
|
||
input[type="radio"] {
|
||
position: absolute;
|
||
opacity: 0;
|
||
width: 0;
|
||
height: 0;
|
||
}
|
||
|
||
.radio-text {
|
||
font-size: 16px;
|
||
color: #275AFF;
|
||
font-weight: 500;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
&:hover {
|
||
border-color: #275AFF;
|
||
}
|
||
|
||
&.active {
|
||
background: linear-gradient(to right, #275AFF, #2EBDFA);
|
||
border-color: #275AFF;
|
||
box-shadow: 0 2px 8px rgba(39, 90, 255, 0.3);
|
||
|
||
.radio-text {
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 关注记录列表样式 */
|
||
.history-list {
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.history-item {
|
||
background: #fff;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
margin-bottom: 16px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||
border: 1px solid #f0f0f0;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.history-item:hover {
|
||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||
/* transform: translateY(-2px); */
|
||
}
|
||
|
||
.history-date {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16px;
|
||
padding-bottom: 12px;
|
||
border-bottom: 1px solid #f5f5f5;
|
||
}
|
||
|
||
.date-text {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #275AFF;
|
||
margin-right: 12px;
|
||
}
|
||
|
||
.relative-time {
|
||
font-size: 14px;
|
||
color: #999;
|
||
background: #f8f9fa;
|
||
padding: 4px 8px;
|
||
border-radius: 12px;
|
||
}
|
||
|
||
.history-content {
|
||
margin-top: 8px;
|
||
}
|
||
|
||
/* 空状态样式 */
|
||
.empty-state {
|
||
text-align: center;
|
||
padding: 60px 20px;
|
||
color: #999;
|
||
}
|
||
|
||
.empty-icon {
|
||
font-size: 48px;
|
||
margin-bottom: 16px;
|
||
opacity: 0.6;
|
||
}
|
||
|
||
.empty-text {
|
||
font-size: 16px;
|
||
color: #999;
|
||
}
|
||
</style> |