当前位置: 首页 > news >正文

开源版coreshop微信商城显示产品列表显示的修正(2)

7.进行调试

7.1 运行后台和hbuilder 进行调试

发现不能正常显示产品列表信息,问题出在下面的函数

  #region 获取所有商品分类栏目数据2025/// <summary>/// 获取所有商品分类栏目数据 ,并显示第一页产品信息/// /// </summary>/// <returns>/// 1.一个大类列表,并指定一个当前类目(选一个为当前类目,选择条件为第一个非空类目,即默认第一个大类的类目是当前类目,/// 如果第一个大类的类目下面产品是空的,就选择第二个类目为当前类目,/// 如果第二个类目下面产品还是空的,就继续往下选择,/// 如果全部类目下面都产品都是空的,还是选择第一个类目为当前类目)。///2.  返回 “当前类目”之下的的小类列表和部分产品信息。/// </returns>[HttpPost]public async Task<WebApiCallBack> GetAllCategories2025(){var jm = new WebApiCallBack() { status = true };//1.取得所有的分类 ,并以父子关系进行分类var data = await _goodsCategoryServices.QueryListByClauseAsync(p => p.isShow == true, p => p.sort,OrderByType.Asc);var wxGoodCategoryDto = new List<WxGoodCategoryDto>();//顶级分类var parents = data.Where(p => p.parentId == 0).ToList();if (parents.Any()){parents.ForEach(p =>{var model = new WxGoodCategoryDto();model.id = p.id;model.name = p.name;model.imageUrl = !string.IsNullOrEmpty(p.imageUrl) ? p.imageUrl : "/static/images/common/empty.png";model.sort = p.sort;var childs = data.Where(p => p.parentId == model.id).ToList();if (childs.Any()){var childsList = new List<WxGoodCategoryChild>();childs.ForEach(o =>{childsList.Add(new WxGoodCategoryChild(){id = o.id,imageUrl = !string.IsNullOrEmpty(o.imageUrl) ? o.imageUrl : "/static/images/common/empty.png",name = o.name,sort = o.sort});});model.child = childsList;}// 下面这列就是 返回的 大类列表 (也就是顶级类目)wxGoodCategoryDto.Add(model);});}////2。取得一第大类的产品信息// 我们默认产品信息显示区,能显示18个产品,一行3个,6行。CategoryGoodsDetail currentCategoryGoodsDetail=null;if (wxGoodCategoryDto.Count > 0){//2.0 取得第一个大类之下的产品信息。查出 18个个产品。//如果 超过18个,我只则只取前18个。第19个显示 一个更多按钮bool hasGoods = false; //当前类目下是否有产品int icurrentCategoryIndex = 0;do{//初始化 当前类目信息//在 微信商城界面上是 产品列表界面 右边的 产品信息区currentCategoryGoodsDetail = new CategoryGoodsDetail();int CategoryID = wxGoodCategoryDto[icurrentCategoryIndex].id;WxGoodCategoryDto currentTopCategory = wxGoodCategoryDto[icurrentCategoryIndex];//2.1大类之下的产品var bigCategoerGoods = _goodsServices.QueryPage( good=> ! good.isDel && good. );//.QueryListByClause(" isnull(isDel,0) <>1 and [goodsCategoryId]=" + CategoryID.ToString ());/*await _goodsServices.GetGoodsInfoList(p => p.isMarketable == true && p.isDel == false && p.goodsCategoryId == CategoryID, null, null, 1, 18, false);*/if (bigCategoerGoods.Count > 0){hasGoods = true; //当前类目下有产品}currentCategoryGoodsDetail.curentCategory = currentTopCategory;currentCategoryGoodsDetail.TopCategoryGoodsInfoList = bigCategoerGoods;//2.2 取得大类下面的子类列表if (currentTopCategory.child.Count > 0){foreach (var child in currentTopCategory.child){var thisCategoerGoods = await _goodsServices.GetGoodsInfoList(p => p.isMarketable == true && p.isDel == false && p.goodsCategoryId == child.id, null, null, 1, 18, false);subCategoryGoodsDetail subCategoryGoodsDetailTemp = new subCategoryGoodsDetail();subCategoryGoodsDetailTemp.GoodsInfoList = thisCategoerGoods;subCategoryGoodsDetailTemp.subCategory = new WxGoodCategoryDto();subCategoryGoodsDetailTemp.subCategory.id = child.id;subCategoryGoodsDetailTemp.subCategory.name = child.name;currentCategoryGoodsDetail.subGoodsInfoList.Add(subCategoryGoodsDetailTemp);hasGoods = true; //当前类目下有产品 有子类也算有产品}if (hasGoods){//找到了第一个有产品的类目,就退出循环break;}}                icurrentCategoryIndex++;}while (icurrentCategoryIndex < wxGoodCategoryDto.Count && !hasGoods );                         }jm.status = true;jm.data = new{wxGoodCategoryDto = wxGoodCategoryDto,currentCategoryGoodsDetail = currentCategoryGoodsDetail};return jm;}

主要问题就是这行代码出错

   //2.1大类之下的产品var bigCategoerGoods = await _goodsServices.GetGoodsInfoList(p => p.isMarketable == true && p.isDel == false && p.goodsCategoryId == CategoryID, null, null, 1, 18, false);

这个是咱们新增加的函数,通过观察整个框架,我发现原来提供了查询功能,虽然跟我们的查询功能有差距,但是,我们应该遵循开闭原则,即对扩展开放,当需求变化或需要新功能时,可能通过扩展已有的代码(如继承、组合、依赖注入)来实现新行为;对修改关闭,不修改已稳定、经过测试的源代码,尤其是那些核心、底层的函数或类。修改原有代码可能会引入错误,破坏现在功能。
修改之后的函数代码如下:

     #region 获取所有商品分类栏目数据2025/// <summary>/// 获取所有商品分类栏目数据 ,并显示第一页产品信息/// /// </summary>/// <returns>/// 1.一个大类列表,并指定一个当前类目(选一个为当前类目,选择条件为第一个非空类目,即默认第一个大类的类目是当前类目,/// 如果第一个大类的类目下面产品是空的,就选择第二个类目为当前类目,/// 如果第二个类目下面产品还是空的,就继续往下选择,/// 如果全部类目下面都产品都是空的,还是选择第一个类目为当前类目)。///2.  返回 “当前类目”之下的的小类列表和部分产品信息。/// </returns>[HttpPost]public async Task<WebApiCallBack> GetAllCategories2025(){var jm = new WebApiCallBack() { status = true };//1.取得所有的分类 ,并以父子关系进行分类var data = await _goodsCategoryServices.QueryListByClauseAsync(p => p.isShow == true, p => p.sort,OrderByType.Asc);var wxGoodCategoryDto = new List<WxGoodCategoryDto>();//顶级分类var parents = data.Where(p => p.parentId == 0).ToList();if (parents.Any()){parents.ForEach(p =>{var model = new WxGoodCategoryDto();model.id = p.id;model.name = p.name;model.imageUrl = !string.IsNullOrEmpty(p.imageUrl) ? p.imageUrl : "/static/images/common/empty.png";model.sort = p.sort;var childs = data.Where(p => p.parentId == model.id).ToList();if (childs.Any()){var childsList = new List<WxGoodCategoryChild>();childs.ForEach(o =>{childsList.Add(new WxGoodCategoryChild(){id = o.id,imageUrl = !string.IsNullOrEmpty(o.imageUrl) ? o.imageUrl : "/static/images/common/empty.png",name = o.name,sort = o.sort});});model.child = childsList;}// 下面这列就是 返回的 大类列表 (也就是顶级类目)wxGoodCategoryDto.Add(model);});}////2。取得一第大类的产品信息// 我们默认产品信息显示区,能显示18个产品,一行3个,6行。CategoryGoodsDetail currentCategoryGoodsDetail=null;if (wxGoodCategoryDto.Count > 0){//2.0 取得第一个大类之下的产品信息。查出 18个个产品。//如果 超过18个,我只则只取前18个。第19个显示 一个更多按钮bool hasGoods = false; //当前类目下是否有产品int icurrentCategoryIndex = 0;do{//初始化 当前类目信息//在 微信商城界面上是 产品列表界面 右边的 产品信息区currentCategoryGoodsDetail = new CategoryGoodsDetail();int CategoryID = wxGoodCategoryDto[icurrentCategoryIndex].id;WxGoodCategoryDto currentTopCategory = wxGoodCategoryDto[icurrentCategoryIndex];//2.1大类之下的产品var bigCategoerGoods = _goodsServices.QueryPage( good=> ! good.isDel && good.goodsCategoryId== CategoryID,"",1,18);List<CoreGoodsInfo> bigGoods = new List<CoreGoodsInfo>();//进行类型转换if ( bigCategoerGoods.Any()){foreach(var good in bigCategoerGoods){CoreGoodsInfo coreGoodsInfo = new CoreGoodsInfo();coreGoodsInfo.id = good.id;coreGoodsInfo.name = good.name;                           coreGoodsInfo.price = good.price;coreGoodsInfo.mktprice= good.mktprice;coreGoodsInfo.image = good.image;coreGoodsInfo.isRecommend = good.isRecommend;bigGoods.Add(coreGoodsInfo);hasGoods = true; //当前类目下有产品}}currentCategoryGoodsDetail.curentCategory = currentTopCategory;currentCategoryGoodsDetail.TopCategoryGoodsInfoList = bigGoods;//2.2 取得大类下面的子类列表if (currentTopCategory.child.Count > 0){foreach (var child in currentTopCategory.child){var thisCategoerGoods = _goodsServices.QueryPage(good => !good.isDel && good.goodsCategoryId == child.id, "", 1, 18);subCategoryGoodsDetail subCategoryGoodsDetailTemp = new subCategoryGoodsDetail();currentCategoryGoodsDetail.subGoodsInfoList = new List<subCategoryGoodsDetail>();List<CoreGoodsInfo> subGoods = new List<CoreGoodsInfo>();//进行类型转换if (bigCategoerGoods.Any()){foreach (var good in bigCategoerGoods){CoreGoodsInfo coreGoodsInfo = new CoreGoodsInfo();coreGoodsInfo.id = good.id;coreGoodsInfo.name = good.name;coreGoodsInfo.price = good.price;coreGoodsInfo.mktprice = good.mktprice;coreGoodsInfo.image = good.image;coreGoodsInfo.isRecommend = good.isRecommend;subGoods.Add(coreGoodsInfo);hasGoods = true; //当前类目下有产品}}subCategoryGoodsDetailTemp.GoodsInfoList = subGoods;subCategoryGoodsDetailTemp.subCategory = new WxGoodCategoryDto();subCategoryGoodsDetailTemp.subCategory.id = child.id;subCategoryGoodsDetailTemp.subCategory.name = child.name;currentCategoryGoodsDetail.subGoodsInfoList.Add(subCategoryGoodsDetailTemp);hasGoods = true; //当前类目下有产品 有子类也算有产品}if (hasGoods){//找到了第一个有产品的类目,就退出循环break;}}                icurrentCategoryIndex++;}while (icurrentCategoryIndex < wxGoodCategoryDto.Count && !hasGoods );                         }jm.status = true;jm.data = new{wxGoodCategoryDto = wxGoodCategoryDto,currentCategoryGoodsDetail = currentCategoryGoodsDetail};return jm;}#endregion

实体类定义如下:

/************************************************************************            Project: CoreCms*        ProjectName: 核心内容管理系统                                *                Web: https://www.corecms.net                      *             Author: 大灰灰                                          *              Email: jianweie@163.com*         CreateTime: 2021-06-08 22:14:58*        Description: 暂无
***********************************************************************/
using CoreCms.Net.Model.ViewModels.DTO;
using SqlSugar;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;namespace CoreCms.Net.Model.Entities
{/// <summary>/// 商品信息表 返回微信小程序端所需字段/// </summary>public class CoreGoodsInfo{/// <summary>/// 商品ID/// </summary>public int id { get; set; }/// <summary>/// 商品名称/// </summary>public string name { get; set; }/// <summary>/// 商品主图/// </summary>public string image { get; set; }/// <summary>/// 销售价格/// </summary>public decimal price { get; set; }/// <summary>/// 市场价格/// </summary>public decimal mktprice { get; set; }/// <summary>/// 是否推荐/// </summary>public bool isRecommend { get; set; }/// <summary>/// 是否热门/// </summary>public bool isHot { get; set; }/// <summary>/// 评论数量/// </summary>public int commentsCount { get; set; }/// <summary>/// 销量/// </summary>public int buyCount { get; set; }/// <summary>/// 排序值/// </summary>public int sort { get; set; }}/// <summary>/// 子分类商品详情DTO/// </summary>public class SubCategoryGoodsDetail{/// <summary>/// 子分类信息/// </summary>public WxGoodCategoryDto subCategory { get; set; }/// <summary>/// 该子分类下的商品列表/// </summary>public List<CoreGoodsInfo> GoodsInfoList { get; set; } = new List<CoreGoodsInfo>();/// <summary>/// 是否展开(前端使用)/// </summary>public bool expanded { get; set; }}/// <summary>/// 分类商品详情DTO/// </summary>public class CategoryGoodsDetail{/// <summary>/// 当前分类信息/// </summary>public WxGoodCategoryDto curentCategory { get; set; }/// <summary>/// 顶级分类下的商品列表/// </summary>public List<CoreGoodsInfo> TopCategoryGoodsInfoList { get; set; } = new List<CoreGoodsInfo>();/// <summary>/// 子分类商品列表/// </summary>public List<SubCategoryGoodsDetail> subGoodsInfoList { get; set; } = new List<SubCategoryGoodsDetail>();}/// <summary>/// 分类页面数据DTO/// </summary>public class CategoryData{/// <summary>/// 顶级分类列表/// </summary>public List<WxGoodCategoryDto> wxGoodCategoryDto { get; set; }/// <summary>/// 当前分类的商品详情/// </summary>public CategoryGoodsDetail currentCategoryGoodsDetail { get; set; }}}

程序所涉及的实体类还有:

/************************************************************************            Project: CoreCms*        ProjectName: 核心内容管理系统*                Web: https://www.corecms.net*             Author: 大灰灰*              Email: jianweie@163.com*         CreateTime: 2021/7/16 1:14:14*        Description: 暂无***********************************************************************/using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
using SqlSugar;namespace CoreCms.Net.Model.Entities
{/// <summary>///     商品表/// </summary>public partial class CoreCmsGoods{/// <summary>///     商品ID/// </summary>[Display(Name = "商品ID")][SugarColumn(IsPrimaryKey = true, IsIdentity = true)][Required(ErrorMessage = "请输入{0}")]public int id { get; set; }/// <summary>///     商品条码/// </summary>[Display(Name = "商品条码")][Required(ErrorMessage = "请输入{0}")][StringLength(30, ErrorMessage = "{0}不能超过{1}字")]public string bn { get; set; }/// <summary>///     商品条码/// </summary>[Display(Name = "原厂编码")]        [StringLength(30, ErrorMessage = "{0}不能超过{1}字")]public string oeMcode { get; set; }/// <summary>///     商品名称/// </summary>[Display(Name = "商品名称")][Required(ErrorMessage = "请输入{0}")][StringLength(200, ErrorMessage = "{0}不能超过{1}字")]public string name { get; set; }/// <summary>///     商品简介/// </summary>[Display(Name = "商品简介")][StringLength(255, ErrorMessage = "{0}不能超过{1}字")]public string brief { get; set; }/// <summary>///     缩略图/// </summary>[Display(Name = "缩略图")][StringLength(255, ErrorMessage = "{0}不能超过{1}字")]public string image { get; set; }/// <summary>///     图集/// </summary>[Display(Name = "图集")]public string images { get; set; }/// <summary>///     视频/// </summary>[Display(Name = "视频")][StringLength(255, ErrorMessage = "{0}不能超过{1}字")]public string video { get; set; }/// <summary>///     佣金分配方式/// </summary>[Display(Name = "佣金分配方式")][Required(ErrorMessage = "请输入{0}")]public int productsDistributionType { get; set; }/// <summary>///     商品分类/// </summary>[Display(Name = "商品分类")][Required(ErrorMessage = "请输入{0}")]public int goodsCategoryId { get; set; }/// <summary>///     商品类别/// </summary>[Display(Name = "商品类别")][Required(ErrorMessage = "请输入{0}")]public int goodsTypeId { get; set; }/// <summary>///     sku序列/// </summary>[Display(Name = "sku序列")][StringLength(255, ErrorMessage = "{0}不能超过{1}字")]public string goodsSkuIds { get; set; }/// <summary>///     参数序列/// </summary>[Display(Name = "参数序列")][StringLength(255, ErrorMessage = "{0}不能超过{1}字")]public string goodsParamsIds { get; set; }/// <summary>///     品牌/// </summary>[Display(Name = "品牌")][Required(ErrorMessage = "请输入{0}")]public int brandId { get; set; }/// <summary>///     是否虚拟商品/// </summary>[Display(Name = "是否虚拟商品")][Required(ErrorMessage = "请输入{0}")]public bool isNomalVirtual { get; set; }/// <summary>///     是否上架/// </summary>[Display(Name = "是否上架")][Required(ErrorMessage = "请输入{0}")]public bool isMarketable { get; set; }/// <summary>///     商品单位/// </summary>[Display(Name = "商品单位")][StringLength(20, ErrorMessage = "{0}不能超过{1}字")]public string unit { get; set; }/// <summary>///     商品详情/// </summary>[Display(Name = "商品详情")]public string intro { get; set; }/// <summary>///     商品规格序列号存储/// </summary>[Display(Name = "商品规格序列号存储")]public string spesDesc { get; set; }/// <summary>///     参数序列化/// </summary>[Display(Name = "参数序列化")]public string parameters { get; set; }/// <summary>///     评论次数/// </summary>[Display(Name = "评论次数")][Required(ErrorMessage = "请输入{0}")]public int commentsCount { get; set; }/// <summary>///     浏览次数/// </summary>[Display(Name = "浏览次数")][Required(ErrorMessage = "请输入{0}")]public int viewCount { get; set; }/// <summary>///     购买次数/// </summary>[Display(Name = "购买次数")][Required(ErrorMessage = "请输入{0}")]public int buyCount { get; set; }/// <summary>///     上架时间/// </summary>[Display(Name = "上架时间")]public DateTime? uptime { get; set; }/// <summary>///     下架时间/// </summary>[Display(Name = "下架时间")]public DateTime? downtime { get; set; }/// <summary>///     商品排序/// </summary>[Display(Name = "商品排序")][Required(ErrorMessage = "请输入{0}")]public int sort { get; set; }/// <summary>///     标签id逗号分隔/// </summary>[Display(Name = "标签id逗号分隔")][StringLength(50, ErrorMessage = "{0}不能超过{1}字")]public string labelIds { get; set; }/// <summary>///     自定义规格名称/// </summary>[Display(Name = "自定义规格名称")]public string newSpec { get; set; }/// <summary>///     开启规则/// </summary>[Display(Name = "开启规则")][Required(ErrorMessage = "请输入{0}")]public int openSpec { get; set; }/// <summary>///     创建时间/// </summary>[Display(Name = "创建时间")]public DateTime? createTime { get; set; }/// <summary>///     更新时间/// </summary>[Display(Name = "更新时间")]public DateTime? updateTime { get; set; }/// <summary>///     是否推荐/// </summary>[Display(Name = "是否推荐")][Required(ErrorMessage = "请输入{0}")]public bool isRecommend { get; set; }/// <summary>///     是否热门/// </summary>[Display(Name = "是否热门")][Required(ErrorMessage = "请输入{0}")]public bool isHot { get; set; }/// <summary>///     是否删除/// </summary>[Display(Name = "是否删除")][Required(ErrorMessage = "请输入{0}")]public bool isDel { get; set; }/// <summary>/// 店铺id/// </summary>[Display(Name = "店铺ID")]public int storeId { get; set; } }
}

8。修改之后的代码

8.1微信小程序端代码如下:

<template><view class="u-wrap"><u-toast ref="uToast" /><u-no-network></u-no-network><u-navbar :is-back="false" :background="background"><view class="slot-wrap"><u-search :show-action="true" shape="round" v-model="searchKey" action-text="搜索" placeholder="请输入搜索内容" @custom="goSearch" @search="goSearch" :action-style="actionStyle"></u-search></view></u-navbar>        <view v-if="categoryList.length === 0" class="empty-category"><u-empty :src="$globalConstVars.apiFilesUrl+'/static/images/common/empty.png'" icon-size="300" text="暂无商品分类" mode="list"></u-empty></view><view class="u-menu-wrap" v-else><!-- 左边大类菜单 --><scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop"><view v-for="(item,index) in categoryList" :key="index" class="u-tab-item" :class="[currentCategory==index ? 'u-tab-item-active' : '']":data-current="index" @tap.stop="switchCategory(index,item.id)"><text class="u-line-1">{{item.name}}</text></view></scroll-view><scroll-view scroll-y class="right-box"><!-- 当前大类的信息 --><view v-if="currentCategoryData" class="current-category-info"><!-- 调试信息 --><view class="debug-info" style="padding: 20rpx; background: #f5f5f5; color: #666; font-size: 24rpx;"><text>大类商品数: {{currentCategoryData.topCategoryGoodsInfoList ? currentCategoryData.topCategoryGoodsInfoList.length : 0}}</text><text> | 子分类数: {{currentCategoryData.subGoodsInfoList ? currentCategoryData.subGoodsInfoList.length : 0}}</text><text> | 当前分类: {{currentCategory}}</text></view><!-- 大类标题 --><view class="category-title">{{currentCategoryData.curentCategory && currentCategoryData.curentCategory.name}}</view><!-- 1. 大类下的直接商品 --><view v-if="currentCategoryData.topCategoryGoodsInfoList && currentCategoryData.topCategoryGoodsInfoList.length > 0" class="category-section"><view class="section-title">本类热门商品 (共{{currentCategoryData.topCategoryGoodsInfoList.length}}件)</view><view class="goods-grid"><view class="goods-item" v-for="(item, index) in currentCategoryData.topCategoryGoodsInfoList" :key="index" @click="goGoodsDetail(item.id)"><view class="good_box"><u-lazy-load threshold="-150" border-radius="10" :image="item.image" :index="index"></u-lazy-load><view class="good_title u-line-2">{{item.name || '未知商品'}}</view><view class="good-price">{{item.price || 0}}元 <span class="u-font-xs coreshop-text-through u-margin-left-15 coreshop-text-gray">{{item.mktprice || 0}}元</span></view><view class="good-tag-recommend" v-if="item.isRecommend">推荐</view><view class="good-tag-hot" v-if="item.isHot">热门</view></view></view></view></view><!-- 如果没有大类商品,显示提示 --><view v-else-if="currentCategoryData.topCategoryGoodsInfoList && currentCategoryData.topCategoryGoodsInfoList.length === 0" class="no-goods-tip"><text>该大类下暂无直接商品</text></view><!-- 2. 子分类列表 --><view v-if="currentCategoryData.subGoodsInfoList && currentCategoryData.subGoodsInfoList.length > 0" class="subcategory-list-section"><view class="section-title">子分类</view><view class="subcategory-grid"><view v-for="(subCategory, subIndex) in currentCategoryData.subGoodsInfoList" :key="subIndex" class="subcategory-item" @click="toggleSubCategory(subIndex)"><view class="subcategory-content"><view class="subcategory-name">{{subCategory.subCategory && subCategory.subCategory.name}}</view><view class="subcategory-count">共{{subCategory.goodsInfoList ? subCategory.goodsInfoList.length : 0}}件商品</view><view class="subcategory-arrow" :class="{'subcategory-arrow-up': subCategory.expanded}"><u-icon name="arrow-down" size="24"></u-icon></view></view><!-- 3. 子分类下的商品列表(可折叠) --><view v-if="subCategory.expanded && subCategory.goodsInfoList && subCategory.goodsInfoList.length > 0" class="subcategory-goods"><view class="goods-grid"><view class="goods-item" v-for="(item, index) in subCategory.goodsInfoList" :key="index" @click.stop="goGoodsDetail(item.id)"><view class="good_box"><u-lazy-load threshold="-150" border-radius="10" :image="item.image" :index="index"></u-lazy-load><view class="good_title u-line-2">{{item.name}}</view><view class="good-price">{{item.price}}元 <span class="u-font-xs coreshop-text-through u-margin-left-15 coreshop-text-gray">{{item.mktprice}}元</span></view><view class="good-tag-recommend" v-if="item.isRecommend">推荐</view><view class="good-tag-hot" v-if="item.isHot">热门</view></view></view></view></view><!-- 子分类为空的状态 --><view v-else-if="subCategory.expanded && (!subCategory.goodsInfoList || subCategory.goodsInfoList.length === 0)" class="empty-subcategory-goods"><u-empty :src="$globalConstVars.apiFilesUrl+'/static/images/common/empty.png'" icon-size="120" :text="(subCategory.subCategory && subCategory.subCategory.name) + '下暂无商品'" mode="list"></u-empty></view></view></view></view><!-- 如果没有商品显示空状态 --><view v-if="(!currentCategoryData.topCategoryGoodsInfoList || currentCategoryData.topCategoryGoodsInfoList.length === 0) && (!currentCategoryData.subGoodsInfoList || currentCategoryData.subGoodsInfoList.length === 0)" class="empty-category-goods"><u-empty :src="$globalConstVars.apiFilesUrl+'/static/images/common/empty.png'" icon-size="300" text="该分类下暂无商品" mode="list"></u-empty></view></view><!-- 加载状态 --><view v-else class="loading-state"><u-loading mode="circle" size="40"></u-loading><text class="loading-text">加载中...</text></view></scroll-view>          </view><!-- 在模板中添加测试按钮 --><view class="test-buttons" style="padding: 20rpx;"><button @click="testAddGoods" size="mini">测试添加商品</button><button @click="logCurrentData" size="mini">打印当前数据</button></view></view>
</template><script>import { goods } from '@/common/mixins/mixinsHelper.js';export default {mixins: [goods],data() {return {background: {backgroundColor: '#e54d42',},actionStyle: {color: '#ffffff',},categoryList: [], // 大类列表currentCategory: 0, // 当前选中大类索引currentCategoryData: null, // 当前大类的详细数据scrollTop: 0,menuHeight: 0,menuItemHeight: 0,searchKey: '',loading: false,expandedSubCategories: [] // 记录展开的子分类索引}},onShow() {console.log("onShow");this.loadAllCategories();},methods: {// 加载所有分类数据loadAllCategories() {				console.log("-----------loadAllCategories----------------");							    this.loading = true;const _this = this;			    this.$u.api.getAllCategories2025().then(res => {console.log("res=", res);			        console.log("res.status",res.status);if (res.status) {// 直接赋值,注意字段名大小写_this.categoryList = res.data.wxGoodCategoryDto || [];_this.currentCategoryData = res.data.currentCategoryGoodsDetail;console.log('分类列表:', _this.categoryList);console.log('当前分类数据:', _this.currentCategoryData);if (_this.currentCategoryData) {console.log('大类商品数量:', _this.currentCategoryData.topCategoryGoodsInfoList ? _this.currentCategoryData.topCategoryGoodsInfoList.length : 0);console.log('子分类数量:', _this.currentCategoryData.subGoodsInfoList ? _this.currentCategoryData.subGoodsInfoList.length : 0);if (_this.currentCategoryData.topCategoryGoodsInfoList) {console.log('大类商品详情:', _this.currentCategoryData.topCategoryGoodsInfoList);}}// 初始化子分类的展开状态if (_this.currentCategoryData && _this.currentCategoryData.subGoodsInfoList) {_this.currentCategoryData.subGoodsInfoList.forEach((item, index) => {_this.$set(item, 'expanded', index === 0);});}// 如果后端没有返回当前分类数据,默认显示第一个分类if (!_this.currentCategoryData && _this.categoryList.length > 0) {_this.switchCategory(0, _this.categoryList[0].id);}} else {_this.$refs.uToast.show({title: res.msg || '加载失败',type: 'error',});}}).catch(error => {console.log('加载分类数据失败:', error);_this.$refs.uToast.show({title: '网络错误,请重试',type: 'error',});}).finally(() => {_this.loading = false;});},// 切换大类async switchCategory(index, categoryId) {console.log("switchCategory, index=", index, "categoryId=", categoryId);if (this.loading) return;this.currentCategory = index;this.loading = true;try {// 调用接口获取指定分类的数据// 尝试不同的接口名称let res = null;try {// 先尝试 getCategoryGoods2025res = await this.$u.api.getCategoryGoods2025({ id: categoryId });console.log("getCategoryGoods2025 返回:", res);} catch (error1) {console.log("getCategoryGoods2025 接口不存在,尝试 getCategoryGoods");try {// 如果不存在,尝试 getCategoryGoodsres = await this.$u.api.getCategoryGoods({ categoryId: categoryId });console.log("getCategoryGoods 返回:", res);} catch (error2) {console.log("getCategoryGoods 接口也不存在");throw new Error("分类商品接口不存在");}}if (res && res.status) {// 注意:后端返回的数据结构可能是 res.data 或 res.data.currentCategoryGoodsDetailif (res.data.currentCategoryGoodsDetail) {this.currentCategoryData = res.data.currentCategoryGoodsDetail;} else {this.currentCategoryData = res.data;}console.log("切换分类后的数据:", this.currentCategoryData);// 初始化子分类的展开状态if (this.currentCategoryData && this.currentCategoryData.subGoodsInfoList) {this.currentCategoryData.subGoodsInfoList.forEach((item, index) => {this.$set(item, 'expanded', index === 0);});}} else {const errorMsg = res ? res.msg : '接口返回数据异常';this.$refs.uToast.show({title: errorMsg || '加载商品失败',type: 'error',});}} catch (error) {console.error('加载分类商品失败:', error);this.$refs.uToast.show({title: '网络错误,请重试: ' + error.message,type: 'error',});// 如果切换分类失败,回退到初始数据this.currentCategoryData = null;} finally {this.loading = false;}// 滚动条定位await this.scrollToCurrentCategory();},// 切换子分类展开/收起toggleSubCategory(subIndex) {if (this.currentCategoryData && this.currentCategoryData.subGoodsInfoList) {const subCategory = this.currentCategoryData.subGoodsInfoList[subIndex];this.$set(subCategory, 'expanded', !subCategory.expanded);}},// 滚动条定位async scrollToCurrentCategory() {if (this.menuHeight === 0 || this.menuItemHeight === 0) {await this.getElRect('menu-scroll-view', 'menuHeight');await this.getElRect('u-tab-item', 'menuItemHeight');}this.scrollTop = this.currentCategory * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;},getElRect(elClass, dataVal) {return new Promise((resolve) => {const query = uni.createSelectorQuery().in(this);query.select('.' + elClass).fields({ size: true }, res => {if (!res) {setTimeout(() => {this.getElRect(elClass, dataVal).then(resolve);}, 10);return;}this[dataVal] = res.height;resolve();}).exec();});},goSearch() {if (this.searchKey !== '') {this.$u.route('/pages/category/list/list?key=' + this.searchKey);} else {this.$refs.uToast.show({title: '请输入查询关键字',type: 'warning',});}},// 跳转商品详情goGoodsDetail(goodsId) {this.$u.route('/pages/goods/detail/detail?id=' + goodsId);},// 测试添加商品数据testAddGoods() {if (!this.currentCategoryData) {this.currentCategoryData = {curentCategory: { name: '测试分类' },topCategoryGoodsInfoList: [],subGoodsInfoList: []};}// 添加测试商品const testGoods = {id: 1,name: '测试商品',image: '/static/images/common/empty.png',price: 99.00,mktprice: 129.00,isRecommend: true,isHot: false};if (!this.currentCategoryData.topCategoryGoodsInfoList) {this.$set(this.currentCategoryData, 'topCategoryGoodsInfoList', []);}this.currentCategoryData.topCategoryGoodsInfoList.push(testGoods);console.log('测试商品已添加');},// 打印当前数据logCurrentData() {console.log('当前分类数据:', this.currentCategoryData);console.log('当前分类索引:', this.currentCategory);if (this.currentCategoryData) {if (this.currentCategoryData.topCategoryGoodsInfoList) {console.log('大类商品列表:', this.currentCategoryData.topCategoryGoodsInfoList);}if (this.currentCategoryData.subGoodsInfoList) {console.log('子分类列表:', this.currentCategoryData.subGoodsInfoList);}}}}}
</script><style lang="scss" scoped>/* 样式保持不变,与您原来的代码一致 */.u-wrap {height: 100vh;display: flex;flex-direction: column;}.empty-category {padding: 100rpx 0;display: flex;justify-content: center;align-items: center;height: 100%;}.u-menu-wrap {display: flex;flex: 1;height: 100%;}.u-tab-view {width: 200rpx;height: 100%;background: #f8f8f8;}.u-tab-item {height: 100rpx;display: flex;align-items: center;justify-content: center;font-size: 28rpx;color: #666;padding: 0 20rpx;border-left: 4rpx solid transparent;}.u-tab-item-active {background: #fff;color: #e54d42;border-left-color: #e54d42;}.right-box {flex: 1;height: 100%;background: #fff;}.current-category-info {min-height: 100vh;padding-bottom: 100rpx;}.category-title {padding: 30rpx;font-size: 36rpx;font-weight: bold;color: #333;background: #fff;border-bottom: 1rpx solid #f5f5f5;}.section-title {padding: 20rpx 30rpx;font-size: 32rpx;font-weight: bold;color: #333;background: #f8f8f8;margin: 0;}.category-section,.subcategory-list-section {margin-bottom: 30rpx;}.goods-grid {display: flex;flex-wrap: wrap;padding: 20rpx;gap: 20rpx;}.goods-item {width: calc(50% - 10rpx);padding: 10rpx;box-sizing: border-box;margin-bottom: 20rpx;}/* 其他样式保持不变... */
</style>

8.2 后台的代码如下:

#region 返回特定 大类ID之所有子类,并返回该子类下的产品信息/// <summary>/// 根据顶级分类ID获取商品数据/// </summary>[HttpPost]public async Task<WebApiCallBack> GetCategoryGoods2025([FromBody] FMIntId entity){var jm = new WebApiCallBack() { status = true };try{int categoryId = entity.id;// 0. 取得该分类信息CoreCmsGoodsCategory currentTopCategory1 = await _goodsCategoryServices.QueryByIdAsync(categoryId);if (currentTopCategory1 == null){jm.status = false;jm.msg = "分类不存在";return jm;}// 将分类信息转换为 DTOWxGoodCategoryDto currentTopCategory = new WxGoodCategoryDto{id = currentTopCategory1.id,name = currentTopCategory1.name,imageUrl = !string.IsNullOrEmpty(currentTopCategory1.imageUrl) ? currentTopCategory1.imageUrl : "/static/images/common/empty.png",sort = currentTopCategory1.sort};// 1. 获取该分类的子分类var subCategories = await _goodsCategoryServices.QueryListByClauseAsync(p => p.parentId == categoryId, p => p.sort, OrderByType.Asc);if (subCategories.Any()){var childList = new List<WxGoodCategoryChild>();foreach (var subCategory in subCategories){childList.Add(new WxGoodCategoryChild(){id = subCategory.id,name = subCategory.name,imageUrl = !string.IsNullOrEmpty(subCategory.imageUrl) ? subCategory.imageUrl : "/static/images/common/empty.png",sort = subCategory.sort});}currentTopCategory.child = childList;}// 2. 创建分类商品详情var currentCategoryGoodsDetail = new CategoryGoodsDetail{curentCategory = currentTopCategory};// 3. 获取该分类下的直接商品(使用与 GetAllCategories2025 相同的方法)List<CoreGoodsInfo> topCategoryGoods = GetGoodInfoFromCategoryID(categoryId);currentCategoryGoodsDetail.TopCategoryGoodsInfoList = topCategoryGoods;currentCategoryGoodsDetail.subGoodsInfoList = new List<SubCategoryGoodsDetail>();// 4. 获取子分类的商品信息if (currentTopCategory.child != null && currentTopCategory.child.Count > 0){foreach (var child in currentTopCategory.child){var subCategoryGoodsDetailTemp = new SubCategoryGoodsDetail();// 获取子分类的商品(使用与 GetAllCategories2025 相同的方法)List<CoreGoodsInfo> subGoods = GetGoodInfoFromCategoryID(child.id);subCategoryGoodsDetailTemp.GoodsInfoList = subGoods;subCategoryGoodsDetailTemp.subCategory = new WxGoodCategoryDto{id = child.id,name = child.name,imageUrl = child.imageUrl,sort = child.sort};subCategoryGoodsDetailTemp.expanded = false; // 默认不展开currentCategoryGoodsDetail.subGoodsInfoList.Add(subCategoryGoodsDetailTemp);}}jm.status = true;jm.data = new CategoryData{wxGoodCategoryDto = null, // 这个接口不需要返回顶级分类列表currentCategoryGoodsDetail = currentCategoryGoodsDetail};}catch (Exception ex){jm.status = false;jm.msg = "获取分类商品失败:" + ex.Message;}return jm;}/// <summary>/// 从分类ID获取商品信息(与 GetAllCategories2025 使用相同的方法)/// </summary>private List<CoreGoodsInfo> GetGoodInfoFromCategoryID(int categoryId){// 使用与 GetAllCategories2025 相同的查询逻辑var goodsList = _goodsServices.QueryPage(good => !good.isDel && good.goodsCategoryId == categoryId, "", 1, 18);List<CoreGoodsInfo> result = new List<CoreGoodsInfo>();if (goodsList != null && goodsList.Any()){foreach (var good in goodsList){CoreGoodsInfo coreGoodsInfo = new CoreGoodsInfo();coreGoodsInfo.id = good.id;coreGoodsInfo.name = good.name;coreGoodsInfo.price = good.price;coreGoodsInfo.mktprice = good.mktprice;coreGoodsInfo.image = good.image;coreGoodsInfo.isRecommend = good.isRecommend;coreGoodsInfo.isHot = good.isHot;coreGoodsInfo.commentsCount = good.commentsCount;coreGoodsInfo.buyCount = good.buyCount;coreGoodsInfo.sort = good.sort;result.Add(coreGoodsInfo);}}return result;}#endregionprivate List<CoreGoodsInfo> getGoodInfoFromCategoryID( int categoryId){//2.1 大类之下的产品var bigCategoryGoods =_goodsServices.QueryPage(good => !good.isDel && good.goodsCategoryId == categoryId, "", 1, 18);List<CoreGoodsInfo> bigGoods = new List<CoreGoodsInfo>();//进行类型转换if (bigCategoryGoods != null && bigCategoryGoods.Any()){foreach (var good in bigCategoryGoods){CoreGoodsInfo coreGoodsInfo = new CoreGoodsInfo();coreGoodsInfo.id = good.id;coreGoodsInfo.name = good.name;coreGoodsInfo.price = good.price;coreGoodsInfo.mktprice = good.mktprice;coreGoodsInfo.image = good.image;coreGoodsInfo.isRecommend = good.isRecommend;coreGoodsInfo.isHot = good.isHot;coreGoodsInfo.commentsCount = good.commentsCount;coreGoodsInfo.buyCount = good.buyCount;coreGoodsInfo.sort = good.sort;bigGoods.Add(coreGoodsInfo);}}return bigGoods;}#region 获取所有商品分类栏目数据2025/// <summary>/// 获取所有商品分类栏目数据 ,并显示第一页产品信息/// /// </summary>/// <returns>/// 1.一个大类列表,并指定一个当前类目(选一个为当前类目,选择条件为第一个非空类目,即默认第一个大类的类目是当前类目,/// 如果第一个大类的类目下面产品是空的,就选择第二个类目为当前类目,/// 如果第二个类目下面产品还是空的,就继续往下选择,/// 如果全部类目下面都产品都是空的,还是选择第一个类目为当前类目)。///2.  返回 "当前类目"之下的的小类列表和部分产品信息。/// </returns>[HttpPost]public async Task<WebApiCallBack> GetAllCategories2025(){var jm = new WebApiCallBack() { status = true };try{//1.取得所有的分类 ,并以父子关系进行分类var data = await _goodsCategoryServices.QueryListByClauseAsync(p => p.isShow == true, p => p.sort,OrderByType.Asc);var wxGoodCategoryDto = new List<WxGoodCategoryDto>();//顶级分类var parents = data.Where(p => p.parentId == 0).ToList();if (parents.Any()){parents.ForEach(p =>{var model = new WxGoodCategoryDto();model.id = p.id;model.name = p.name;model.imageUrl = !string.IsNullOrEmpty(p.imageUrl) ? p.imageUrl : "/static/images/common/empty.png";model.sort = p.sort;var childs = data.Where(o => o.parentId == model.id).ToList();if (childs.Any()){var childsList = new List<WxGoodCategoryChild>();childs.ForEach(o =>{childsList.Add(new WxGoodCategoryChild(){id = o.id,imageUrl = !string.IsNullOrEmpty(o.imageUrl) ? o.imageUrl : "/static/images/common/empty.png",name = o.name,sort = o.sort});});model.child = childsList;}// 下面这列就是 返回的 大类列表 (也就是顶级类目)wxGoodCategoryDto.Add(model);});}//2.取得第一个大类的产品信息// 我们默认产品信息显示区,能显示18个产品,一行3个,6行。CategoryGoodsDetail currentCategoryGoodsDetail = null;if (wxGoodCategoryDto.Count > 0){bool hasGoods = false; //当前类目下是否有产品int currentCategoryIndex = 0;do{//初始化 当前类目信息currentCategoryGoodsDetail = new CategoryGoodsDetail();int categoryId = wxGoodCategoryDto[currentCategoryIndex].id;WxGoodCategoryDto currentTopCategory = wxGoodCategoryDto[currentCategoryIndex];//2.1 大类之下的产品                        List<CoreGoodsInfo> bigGoods = getGoodInfoFromCategoryID(categoryId);// new List<CoreGoodsInfo>();if(bigGoods.Any()){                             hasGoods = true;}currentCategoryGoodsDetail.curentCategory = currentTopCategory;currentCategoryGoodsDetail.TopCategoryGoodsInfoList = bigGoods;currentCategoryGoodsDetail.subGoodsInfoList = new List<SubCategoryGoodsDetail>();//2.2 取得大类下面的子类列表if (currentTopCategory.child != null && currentTopCategory.child.Count > 0){foreach (var child in currentTopCategory.child){var subCategoryGoodsDetailTemp = new SubCategoryGoodsDetail();// 获取子分类的商品                              List<CoreGoodsInfo> subGoods = getGoodInfoFromCategoryID(child.id); if (subGoods.Any()) hasGoods = true;subCategoryGoodsDetailTemp.GoodsInfoList = subGoods;subCategoryGoodsDetailTemp.subCategory = new WxGoodCategoryDto{id = child.id,name = child.name,imageUrl = child.imageUrl,sort = child.sort};subCategoryGoodsDetailTemp.expanded = false; // 默认不展开currentCategoryGoodsDetail.subGoodsInfoList.Add(subCategoryGoodsDetailTemp);// 有子类也算有产品if (subGoods.Any()) hasGoods = true;}}// 如果当前分类有商品或者子分类有商品,就退出循环if (hasGoods){break;}currentCategoryIndex++;}while (currentCategoryIndex < wxGoodCategoryDto.Count);// 如果所有分类都没有商品,仍然使用第一个分类if (!hasGoods && wxGoodCategoryDto.Count > 0){int firstCategoryId = wxGoodCategoryDto[0].id;WxGoodCategoryDto firstTopCategory = wxGoodCategoryDto[0];currentCategoryGoodsDetail = new CategoryGoodsDetail{curentCategory = firstTopCategory,TopCategoryGoodsInfoList = new List<CoreGoodsInfo>(),subGoodsInfoList = new List<SubCategoryGoodsDetail>()};// 添加子分类(即使没有商品)if (firstTopCategory.child != null && firstTopCategory.child.Count > 0){foreach (var child in firstTopCategory.child){currentCategoryGoodsDetail.subGoodsInfoList.Add(new SubCategoryGoodsDetail{subCategory = new WxGoodCategoryDto{id = child.id,name = child.name,imageUrl = child.imageUrl,sort = child.sort},GoodsInfoList = new List<CoreGoodsInfo>(),expanded = false});}}}}jm.status = true;jm.data = new CategoryData{wxGoodCategoryDto = wxGoodCategoryDto,currentCategoryGoodsDetail = currentCategoryGoodsDetail};}catch (Exception ex){jm.status = false;jm.msg = "获取分类数据失败:" + ex.Message;}return jm;}#endregion

修改之后运行代码界面如下
在这里插入图片描述
运行成功。教程完结。

http://www.dtcms.com/a/577948.html

相关文章:

  • 昆山建设局图审中心网站温州做网站老师
  • 网站判断手机跳转代码用wordpress搭建娱乐网
  • 追剧喵 v3.2.0 手机影视播放器工具
  • 三角洲行动-java游戏程序
  • 清晰地说明 NVM、NPM 和 NRM 在 Node.js 开发过程中的作用
  • Java IDEA学习之路:第七、八周课程笔记归纳
  • Vue2 首屏加载慢打包优化的详细记录
  • 【AI应用探索】-LLaMA-Factory微调模型
  • 最有效的网站推广方案企业网站管理系统怎么用
  • linux系统如何做网站小程序会员系统怎么做
  • 网站建设费用福州建设工程招投标信息网
  • 使用 llama.cpp 在本地高效运行大语言模型,支持 Docker 一键启动,兼容CPU与GPU
  • MTPA-最大转矩电流比控制解析
  • 【BUG调查日记】用于压测的机器人进程内存压不住且脱离分配器的管理
  • wordpress 招聘类网站郑州网站制作工作室
  • php可以做视频网站吗搜索网站怎么做
  • 什么是3D贴纸SDK?
  • Kafka系列之:生产环境替换kafka集群机器详细方案
  • 颠覆知识工作流:谷歌NotebookLM的“疯狂”用法与深度洞察
  • 基于LLM+SearxNG的实时网络搜索agent
  • FPC回流焊治具过炉托盘核心作用及设计要点
  • 移动云网站建设钓鱼网站图片
  • C++笔记——STL list
  • 前端技术方案博客文档汇总
  • 校园跑腿配送系统搭建:从0到1的完整解决方案
  • 蓝牙钥匙 第52次 深入解析安全启动与可信执行环境:从硬件根基到系统安全
  • Docker 自动化管理脚本大全
  • LangFlow 源码分析:Trace 追踪机制核心问题与解决方案
  • SpringBoot+Vue3全栈开发笔记后端部分
  • 网站服务器模式温江 网站建设