chore:按钮 = 全局所有有商品的二级分类(去重,一直显示),选中状态在切换一级分类时保持

商品 = 切换一级分类时,用选中按钮的名称在当前一级分类下找同名 category,重新加载该 category 的商品
This commit is contained in:
2026-07-16 14:31:14 +08:00
parent 7f2e5d3934
commit 7a6495fa33
2 changed files with 129 additions and 5 deletions

View File

@@ -340,6 +340,10 @@ export default {
lastSecondCategoryName: {
type: String,
default: ''
},
currentOneCategory: {
type: Object,
default: null
}
},
mixins: [DiyMinx],
@@ -379,7 +383,8 @@ export default {
}
this.selectedSecondCategory = targetCategory.category_id;
this.secondCategoryGoodsList = [];
this.getSecondCategoryGoods(targetCategory.category_id);
// 用当前一级分类下同名二级分类的 id 查商品(而非全局按钮的 id)
this.refreshGoodsByCurrentCategory();
}
},
mounted() {
@@ -440,9 +445,18 @@ export default {
}
this.selectedSecondCategory = targetCategory.category_id;
this.secondCategoryGoodsList = [];
this.getSecondCategoryGoods(targetCategory.category_id);
this.refreshGoodsByCurrentCategory();
}
},
// 切换一级分类时, 根据当前一级分类下同名二级分类重新加载商品
currentOneCategory: {
handler() {
if (this.value.template == 99 && parseInt(this.value.level) == 2) {
this.refreshGoodsByCurrentCategory();
}
},
deep: true
},
'globalStoreInfo.store_id': {
handler(nval, oval) {
if (nval != oval) {
@@ -821,6 +835,35 @@ export default {
if (!link) return;
this.$util.diyRedirectTo(JSON.parse(link));
},
/**
* 根据当前一级分类(currentOneCategory)下与选中按钮同名的二级分类, 加载对应商品
* 按钮是全局去重的(选中状态用全局 category_id), 但商品只显示当前一级分类下的
* 当前一级分类下若没有同名二级分类, 则商品清空(按钮保持选中)
*/
refreshGoodsByCurrentCategory() {
if (this.selectedSecondCategory == null) {
this.secondCategoryGoodsList = [];
return;
}
// 取当前选中按钮的名称
const cur = (this.category.child_list || []).find(c => c.category_id === this.selectedSecondCategory);
if (!cur) {
this.secondCategoryGoodsList = [];
return;
}
const one = this.currentOneCategory;
if (!one || !one.child_list || one.child_list.length === 0) {
this.secondCategoryGoodsList = [];
return;
}
const match = one.child_list.find(c => c.category_name === cur.category_name);
if (match) {
this.getSecondCategoryGoods(match.category_id);
} else {
// 当前一级分类下没有该二级分类, 商品清空(按钮仍保持选中)
this.secondCategoryGoodsList = [];
}
},
selectSecondCategory(category) {
if (this.selectedSecondCategory === category.category_id) {
this.selectedSecondCategory = null;
@@ -828,8 +871,9 @@ export default {
} else {
this.selectedSecondCategory = category.category_id;
this.secondCategoryGoodsList = [];
this.getSecondCategoryGoods(category.category_id);
this.$emit('saveSecondCategory', category.category_name);
// 用当前一级分类下同名 category_id 查商品
this.refreshGoodsByCurrentCategory();
}
},
getSecondCategoryGoods(categoryId) {

View File

@@ -92,7 +92,19 @@
</scroll-view>
<view class="right-flex-wrap">
<scroll-view scroll-y="true" class="content-wrap" v-if="value.template == 1 || value.template == 99 || loadType == 'all'"
<!-- 模板99 + 二级分类: 全局二级分类按钮(去重, 一直显示) + 商品列表 -->
<scroll-view scroll-y="true" class="content-wrap" v-if="value.template == 99 && parseInt(value.level) == 2 && template99Category"
:refresher-enabled="true" refresher-default-style="none"
:refresher-triggered="triggered" @refresherrefresh="onRefresh" @refresherrestore="onRestore">
<diy-category-item :category="template99Category" :value="value" ref="categoryItem" :index="0" :select="0"
:oneCategorySelect="oneCategorySelect" :isList="isList"
:currentOneCategory="categoryTree && categoryTree[select] ? categoryTree[select] : null"
:lastSecondCategoryName="lastSecondCategoryName"
@tologin="toLogin" @selectsku="selectSku($event, 0)" @addCart="addCartPoint"
@saveSecondCategory="saveSecondCategoryName"></diy-category-item>
</scroll-view>
<scroll-view scroll-y="true" class="content-wrap" v-else-if="value.template == 1 || value.template == 99 || loadType == 'all'"
ref="contentWrap" :scroll-into-view="categoryId" :scroll-with-animation="true"
@scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true"
refresher-default-style="none" :refresher-triggered="triggered" @refresherrefresh="onRefresh"
@@ -196,7 +208,8 @@ export default {
templateFourData: [],
isList: false,
lang: uni.getStorageSync("lang"),
lastSecondCategoryName: ''
lastSecondCategoryName: '',
template99Category: null
};
},
created() {
@@ -363,10 +376,77 @@ export default {
return item;
});
}
// 模板99 + 二级分类: 全局查询所有有商品的二级分类(去重), 按钮一直显示
if (this.value.template == 99 && parseInt(this.value.level) == 2) {
this.loadGlobalSecondCategoryBtns();
}
}
}
});
},
/**
* 全局查询所有有商品的二级分类, 按名称去重, 汇总成虚拟分类供 template99 渲染按钮
* 只要任何商品属于该二级分类, 按钮就显示; 切换一级分类时按钮不变(一直显示)
* 新增的二级分类只要有商品也会自动包含
*/
loadGlobalSecondCategoryBtns() {
if (!this.categoryTree || !this.categoryTree.length) {
this.template99Category = { category_name: '', child_list: [] };
return;
}
// 收集所有二级分类(保留原始顺序, 不去重, 查询所有同名后再去重)
const allSecond = [];
this.categoryTree.forEach(one => {
if (one.child_list && one.child_list.length) {
one.child_list.forEach(two => {
allSecond.push(Object.assign({ _origIndex: allSecond.length }, two));
});
}
});
if (!allSecond.length) {
this.template99Category = { category_name: '', child_list: [] };
return;
}
let pending = allSecond.length;
const results = [];
const finishOne = () => {
pending--;
if (pending <= 0) {
results.sort((a, b) => a._origIndex - b._origIndex);
// 按名称去重, 同名只保留第一个有商品的(只要任一同名有商品就显示)
const deduped = [];
const seenNames = {};
results.forEach(item => {
if (!seenNames[item.category_name]) {
seenNames[item.category_name] = true;
deduped.push(item);
}
});
this.template99Category = {
category_name: '',
child_list: deduped
};
}
};
allSecond.forEach(two => {
this.$api.sendRequest({
url: '/api/goodssku/pageByCategory',
data: {
category_id: two.category_id,
page: 1,
page_size: 1
},
success: res => {
if (res && res.code == 0 && res.data && res.data.list && res.data.list.length > 0) {
results.push(two);
}
},
complete: () => {
finishOne();
}
});
});
},
/**
* 切换一级分类
* @param {Object} index