mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 01:01:52 +08:00
feature(uniapp分类): 分类列表以及商品加载
This commit is contained in:
parent
f3c83488a3
commit
e2a6530acb
@ -0,0 +1,40 @@
|
|||||||
|
package cn.iocoder.yudao.module.product.controller.app.category;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO;
|
||||||
|
import cn.iocoder.yudao.module.product.convert.category.CategoryConvert;
|
||||||
|
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||||
|
import cn.iocoder.yudao.module.product.service.category.CategoryService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
@Api(tags = "用户 APP - 商品分类")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/product/category")
|
||||||
|
@Validated
|
||||||
|
public class AppCategoryController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CategoryService categoryService;
|
||||||
|
|
||||||
|
@GetMapping("/list")
|
||||||
|
@ApiOperation("获得商品分类列表")
|
||||||
|
public CommonResult<List<AppCategoryListRespVO>> listByQuery() {
|
||||||
|
List<CategoryDO> list = categoryService.getCategoryList();
|
||||||
|
list.sort(Comparator.comparing(CategoryDO::getSort));
|
||||||
|
return success(CategoryConvert.INSTANCE.convertList03(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.iocoder.yudao.module.product.controller.app.category.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "App - 商品分类 列表 Request VO", description = "参数和 CategoryBaseVO 是一致的")
|
||||||
|
public class AppCategoryListRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类编号", required = true, example = "2")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "父分类编号", required = true, example = "1")
|
||||||
|
@NotNull(message = "父分类编号不能为空")
|
||||||
|
private Long parentId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类名称", required = true, example = "办公文具")
|
||||||
|
@NotBlank(message = "分类名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类图标")
|
||||||
|
@NotBlank(message = "分类图标不能为空")
|
||||||
|
private String icon;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类图片", required = true)
|
||||||
|
@NotBlank(message = "分类图片不能为空")
|
||||||
|
private String bannerUrl;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类排序", required = true, example = "1")
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类描述", required = true, example = "描述")
|
||||||
|
private String description;
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package cn.iocoder.yudao.module.product.controller.app.spu;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.SpuRespVO;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
|
||||||
|
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
@Api(tags = "用户 APP - 商品spu")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/product/spu")
|
||||||
|
@Validated
|
||||||
|
public class AppProductSpuController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ProductSpuService spuService;
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@ApiOperation("获得商品spu分页")
|
||||||
|
public CommonResult<PageResult<AppSpuPageRespVO>> getSpuPage(@Valid AppSpuPageReqVO pageVO) {
|
||||||
|
return success(spuService.getSpuPage(pageVO));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package cn.iocoder.yudao.module.product.controller.app.spu.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@ApiModel("App - 商品spu分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class AppSpuPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类id")
|
||||||
|
private Long categoryId;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package cn.iocoder.yudao.module.product.controller.app.spu.vo;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@ApiModel("App - 商品spu分页 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AppSpuPageRespVO {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "主键", required = true, example = "1")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "卖点", required = true)
|
||||||
|
@NotNull(message = "卖点不能为空")
|
||||||
|
private String sellPoint;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "描述", required = true)
|
||||||
|
@NotNull(message = "描述不能为空")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分类id", required = true)
|
||||||
|
@NotNull(message = "分类id不能为空")
|
||||||
|
private Long categoryId;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商品主图地址,* 数组,以逗号分隔,最多上传15张", required = true)
|
||||||
|
@NotNull(message = "商品主图地址,* 数组,以逗号分隔,最多上传15张不能为空")
|
||||||
|
private List<String> picUrls;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "排序字段", required = true)
|
||||||
|
@NotNull(message = "排序字段不能为空")
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "点赞初始人数")
|
||||||
|
private Integer likeCount;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "价格 单位使用:分")
|
||||||
|
private Integer price;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "库存数量")
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "上下架状态: 0 上架(开启) 1 下架(禁用)")
|
||||||
|
private Boolean status;
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,7 @@ import java.util.*;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
|
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
|
||||||
@ -31,4 +32,5 @@ public interface CategoryConvert {
|
|||||||
|
|
||||||
List<CategoryExcelVO> convertList02(List<CategoryDO> list);
|
List<CategoryExcelVO> convertList02(List<CategoryDO> list);
|
||||||
|
|
||||||
|
List<AppCategoryListRespVO> convertList03(List<CategoryDO> list);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import java.util.*;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.Named;
|
import org.mapstruct.Named;
|
||||||
@ -40,6 +42,11 @@ public interface ProductSpuConvert {
|
|||||||
|
|
||||||
List<SpuExcelVO> convertList02(List<ProductSpuDO> list);
|
List<SpuExcelVO> convertList02(List<ProductSpuDO> list);
|
||||||
|
|
||||||
|
SpuPageReqVO convert(AppSpuPageReqVO bean);
|
||||||
|
|
||||||
|
@Mapping(source = "picUrls", target = "picUrls", qualifiedByName = "tokenizeToStringArray")
|
||||||
|
AppSpuPageRespVO convertAppResp(ProductSpuDO list);
|
||||||
|
|
||||||
@Named("tokenizeToStringArray")
|
@Named("tokenizeToStringArray")
|
||||||
default List<String> translatePicUrlsArrayFromString(String picUrls) {
|
default List<String> translatePicUrlsArrayFromString(String picUrls) {
|
||||||
return Arrays.asList(StringUtils.tokenizeToStringArray(picUrls, ","));
|
return Arrays.asList(StringUtils.tokenizeToStringArray(picUrls, ","));
|
||||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.service.category;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
|
import cn.iocoder.yudao.module.product.controller.admin.category.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO;
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
@ -83,4 +84,11 @@ public interface CategoryService {
|
|||||||
* @param categoryId 分类id
|
* @param categoryId 分类id
|
||||||
*/
|
*/
|
||||||
void validatedCategoryById(Long categoryId);
|
void validatedCategoryById(Long categoryId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* app端获得商品分类列表
|
||||||
|
*
|
||||||
|
* @return 商品分类列表
|
||||||
|
*/
|
||||||
|
List<CategoryDO> getCategoryList();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.product.service.category;
|
package cn.iocoder.yudao.module.product.service.category;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
@ -13,6 +14,7 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
|
||||||
@ -106,4 +108,13 @@ public class CategoryServiceImpl implements CategoryService {
|
|||||||
return categoryMapper.selectList(treeListReqVO);
|
return categoryMapper.selectList(treeListReqVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CategoryDO> getCategoryList() {
|
||||||
|
return categoryMapper.selectList()
|
||||||
|
.stream()
|
||||||
|
.filter(v->v.getStatus().equals(CommonStatusEnum.ENABLE.getStatus()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.product.service.spu;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import javax.validation.*;
|
import javax.validation.*;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
|
||||||
@ -67,4 +69,13 @@ public interface ProductSpuService {
|
|||||||
*/
|
*/
|
||||||
List<ProductSpuDO> getSpuList(SpuExportReqVO exportReqVO);
|
List<ProductSpuDO> getSpuList(SpuExportReqVO exportReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得商品spu分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 商品spu分页
|
||||||
|
*/
|
||||||
|
PageResult<AppSpuPageRespVO> getSpuPage(AppSpuPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,10 @@ import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
|
|||||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
|
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
||||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
|
||||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO;
|
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||||
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
|
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
|
||||||
@ -175,4 +176,17 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
return ProductSpuMapper.selectList(exportReqVO);
|
return ProductSpuMapper.selectList(exportReqVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<AppSpuPageRespVO> getSpuPage(AppSpuPageReqVO pageReqVO) {
|
||||||
|
PageResult<ProductSpuDO> productSpuDOPageResult = ProductSpuMapper.selectPage(ProductSpuConvert.INSTANCE.convert(pageReqVO));
|
||||||
|
PageResult<AppSpuPageRespVO> pageResult = new PageResult<>();
|
||||||
|
List<AppSpuPageRespVO> collect = productSpuDOPageResult.getList()
|
||||||
|
.stream()
|
||||||
|
.map(ProductSpuConvert.INSTANCE::convertAppResp)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
pageResult.setList(collect);
|
||||||
|
pageResult.setTotal(productSpuDOPageResult.getTotal());
|
||||||
|
return pageResult;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
5
yudao-ui-app/api/category.js
Normal file
5
yudao-ui-app/api/category.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||||
|
const { http } = uni.$u
|
||||||
|
|
||||||
|
// 查询分类列表
|
||||||
|
export const categoryListData = params => http.get('product/category/list', { params })
|
5
yudao-ui-app/api/product.js
Normal file
5
yudao-ui-app/api/product.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//请求工具参考https://ext.dcloud.net.cn/plugin?id=392
|
||||||
|
const { http } = uni.$u
|
||||||
|
|
||||||
|
// 查询商品spu列表
|
||||||
|
export const productSpuPage = params => http.get('/product/spu/page', { params })
|
@ -12,6 +12,14 @@
|
|||||||
"navigationBarTitleText": "分类"
|
"navigationBarTitleText": "分类"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/category/product-list",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTextStyle": "white"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/cart/cart",
|
"path": "pages/cart/cart",
|
||||||
"style": {
|
"style": {
|
||||||
@ -112,7 +120,7 @@
|
|||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationBarTitleText": "yudao-ui-app",
|
"navigationBarTitleText": "yudao-ui-app",
|
||||||
"navigationBarBackgroundColor": "#F8F8F8",
|
"navigationBarBackgroundColor": "#ffffff",
|
||||||
"backgroundColor": "#FFFFFF"
|
"backgroundColor": "#ffffff"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,56 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
|
<!-- 搜索框 -->
|
||||||
<view class="search-wrap">
|
<view class="search-wrap">
|
||||||
<u-search placeholder="搜索" disabled height="32" :show-action="false" @click="handleSearchClick"></u-search>
|
<u-search placeholder="搜索" disabled height="32" bgColor="#f2f2f2" margin="0 20rpx" :show-action="false"
|
||||||
|
@click="handleSearchClick"></u-search>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 分类内容 -->
|
||||||
<view class="category-box">
|
<view class="category-box">
|
||||||
<view class="box-left">
|
<!-- 左侧导航栏 -->
|
||||||
<view>
|
<scroll-view scroll-y="true" class='box-left'>
|
||||||
<view class="category-item" v-for="(item, index) in categoryList" :key="item.id">
|
<view class="category-item" v-for="(item, index) in categoryList" :key="item.id">
|
||||||
<view class="item-title" :class="{ active: currentIndex === index }" @click="handleCategoryClick(index)">
|
<view class="item-title" :class="{ active: currentIndex === index }" @click="handleCategoryClick(index)">
|
||||||
<text>{{ item.name }}</text>
|
<text>{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- 右侧分类内容 -->
|
||||||
|
<scroll-view scroll-y="true" class="box-right">
|
||||||
|
<view class="category-image">
|
||||||
|
<image :showLoading="true" :src="categoryList[currentIndex].bannerUrl" mode='widthFix' @click="click"></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
<view class="box-right">
|
|
||||||
<image class="category-image" :showLoading="true" :src="categoryList[currentIndex].image" width="530rpx" height="160rpx" @click="click"></image>
|
|
||||||
<view class="sub-category-box" v-for="(item, index) in categoryList[currentIndex].children" :key="item.id">
|
<view class="sub-category-box" v-for="(item, index) in categoryList[currentIndex].children" :key="item.id">
|
||||||
<view class="sub-category-header">
|
<view class="sub-category-header">
|
||||||
<view class="title">{{ item.title }}</view>
|
<view class="title">{{ item.name }}</view>
|
||||||
<view class="more">查看更多</view>
|
<view class="more" @click="handleCategory(item, 0)">查看更多</view>
|
||||||
</view>
|
</view>
|
||||||
<u-grid class="sub-category-grid" col="3">
|
|
||||||
<u-grid-item v-for="(subItem, subIndex) in item.category" :key="subItem.id">
|
<view class="sub-category-grid">
|
||||||
<view class="sub-category-item">
|
<u-grid col="3">
|
||||||
<u-icon name="photo" :size="80"></u-icon>
|
<u-grid-item v-for="(subItem, subIndex) in item.children" :key="subItem.id">
|
||||||
<text class="sub-category-title">{{ subItem.title }}</text>
|
<view class="sub-category-item" @click="handleCategory(item, subIndex)">
|
||||||
|
<u-icon name="photo" :size="80" v-if="subItem.bannerUrl === null"></u-icon>
|
||||||
|
<image :src="item.bannerUrl" v-if="subItem.bannerUrl != null" mode='widthFix' />
|
||||||
|
<text class="sub-category-title">{{ subItem.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
</u-grid-item>
|
</u-grid-item>
|
||||||
</u-grid>
|
</u-grid>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import { categoryListData } from '../../api/category';
|
||||||
|
import { handleTree, convertTree } from '../../utils/tree.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentIndex: 0,
|
currentIndex: 0,
|
||||||
@ -43,114 +58,120 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
for (let i = 0; i < 10; i++) {
|
this.handleCategoryList();
|
||||||
this.categoryList.push({
|
|
||||||
id: i,
|
|
||||||
image: 'https://cdn.uviewui.com/uview/swiper/swiper1.png',
|
|
||||||
name: '商品分类' + i,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
title: '分类' + i + '-1',
|
|
||||||
category: [
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
image: '',
|
|
||||||
title: '分类' + i + '-1-1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
image: '',
|
|
||||||
title: '分类' + i + '-1-2'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
image: '',
|
|
||||||
title: '分类' + i + '-1-3'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: '分类' + i + '-2',
|
|
||||||
category: [
|
|
||||||
{
|
|
||||||
id: 0,
|
|
||||||
image: '',
|
|
||||||
title: '分类' + i + '-2-1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
image: '',
|
|
||||||
title: '分类' + i + '-2-2'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
image: '',
|
|
||||||
title: '分类' + i + '-2-3'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 点击搜索框
|
||||||
handleSearchClick(e) {
|
handleSearchClick(e) {
|
||||||
uni.$u.route('/pages/search/search')
|
uni.$u.route('/pages/search/search')
|
||||||
},
|
},
|
||||||
|
// 点击左侧导航栏
|
||||||
handleCategoryClick(index) {
|
handleCategoryClick(index) {
|
||||||
if (this.currentIndex !== index) {
|
if (this.currentIndex !== index) {
|
||||||
this.currentIndex = index
|
this.currentIndex = index
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
// 获取分类列表并构建树形结构
|
||||||
|
handleCategoryList() {
|
||||||
|
categoryListData().then(res => {
|
||||||
|
this.categoryList = handleTree(res.data, "id", "parentId");
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCategory(item, index){
|
||||||
|
// console.log(item)
|
||||||
|
// console.log(index)
|
||||||
|
uni.navigateTo({
|
||||||
|
url:"./product-list?item="+encodeURIComponent(JSON.stringify(item))+"&index="+index
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.search-wrap {
|
||||||
|
background: #ffffff;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.07);
|
||||||
|
padding: 20rpx 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
.search-wrap {
|
.category-box {
|
||||||
background: $custom-bg-color;
|
position: fixed;
|
||||||
padding: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-box {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 100rpx;
|
||||||
|
height: calc(100% - 100rpx);
|
||||||
|
|
||||||
.box-left {
|
.box-left {
|
||||||
width: 200rpx;
|
width: 200rpx;
|
||||||
padding-top: 20rpx;
|
padding-top: 5rpx;
|
||||||
border-right: $custom-border-style;
|
overflow: scroll;
|
||||||
|
z-index: 2;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
|
||||||
.category-item {
|
.category-item {
|
||||||
border-bottom: $custom-border-style;
|
line-height: 80rpx;
|
||||||
padding: 20rpx 0;
|
height: 80rpx;
|
||||||
|
text-align: center;
|
||||||
|
color: #777;
|
||||||
|
|
||||||
.item-title {
|
.item-title {
|
||||||
padding-left: 30rpx;
|
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border-left: 6rpx solid $u-primary;
|
font-size: 28rpx;
|
||||||
font-weight: 700;
|
font-weight: bold;
|
||||||
|
position: relative;
|
||||||
|
background: #fff;
|
||||||
|
color: $u-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active::before {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
content: "";
|
||||||
|
width: 8rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
top: 25rpx;
|
||||||
|
background: $u-primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-right {
|
.box-right {
|
||||||
flex: 1;
|
width: 550rpx;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
.category-image {
|
.category-image {
|
||||||
width: 510rpx;
|
width: 510rpx;
|
||||||
height: 160rpx;
|
box-sizing: border-box;
|
||||||
padding: 20rpx;
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
margin: 30rpx 20rpx 0;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sub-category-box {
|
.sub-category-box {
|
||||||
.sub-category-header {
|
.sub-category-header {
|
||||||
@include flex-space-between;
|
@include flex-space-between;
|
||||||
padding: 30rpx 20rpx;
|
padding: 20rpx 20rpx;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
font-weight: 700;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
.more {
|
.more {
|
||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
color: #939393;
|
color: #939393;
|
||||||
@ -164,13 +185,21 @@ export default {
|
|||||||
@include flex-center(column);
|
@include flex-center(column);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
||||||
|
image {
|
||||||
|
text-align: center;
|
||||||
|
width: 150rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
line-height: 150rpx;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.sub-category-title {
|
.sub-category-title {
|
||||||
margin: 15rpx 0;
|
margin: 15rpx 0;
|
||||||
font-size: 24rpx;
|
font-size: 22rpx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
161
yudao-ui-app/pages/category/product-list.vue
Normal file
161
yudao-ui-app/pages/category/product-list.vue
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<u-navbar :title="title" :autoBack="true" placeholder="true" titleStyle="font-size: 28rpx">
|
||||||
|
</u-navbar>
|
||||||
|
<view class="context">
|
||||||
|
<view class="tabs-top">
|
||||||
|
<u-tabs :list="categoryList" @click="changeTabs" :current="current" lineHeight="2" lineWidth="85rpx"
|
||||||
|
itemStyle="padding-left: 15px; padding-right: 15px; height: 85rpx;"></u-tabs>
|
||||||
|
</view>
|
||||||
|
<scroll-view scroll-y="true" class="product-list" enable-flex="true">
|
||||||
|
<view class="flex-box">
|
||||||
|
<block v-for="(item, index) in productList[current]" :key="index">
|
||||||
|
<view class="product-item">
|
||||||
|
<view class="product-image">
|
||||||
|
<image :src="item.picUrls[0]" mode='widthFix' />
|
||||||
|
</view>
|
||||||
|
<view class="product-button">
|
||||||
|
<view class="product-text">【{{ item.sellPoint }}】{{ item.name }}</view>
|
||||||
|
<view class="product-price-button">
|
||||||
|
<text class="product-price">¥
|
||||||
|
<text class="price-size">{{ towNumber(item.price) }}</text></text>
|
||||||
|
<text class="product-like-ccount">销量 {{ item.likeCount }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
productSpuPage
|
||||||
|
} from '../../api/product';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
title: "",
|
||||||
|
current: 0,
|
||||||
|
categoryList: [],
|
||||||
|
productList: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad(option) {
|
||||||
|
const item = JSON.parse(decodeURIComponent(option.item))
|
||||||
|
this.title = item.name
|
||||||
|
this.categoryList = item.children
|
||||||
|
this.handleProductSpu(option.index);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeTabs(item) {
|
||||||
|
if (item.index != this.current) {
|
||||||
|
this.handleProductSpu(item.index)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleProductSpu(index) {
|
||||||
|
let param = {}
|
||||||
|
param.categoryId = this.categoryList[index].id
|
||||||
|
console.log(this.categoryList)
|
||||||
|
console.log(index)
|
||||||
|
productSpuPage(param).then(res => {
|
||||||
|
this.productList[index] = res.data.list
|
||||||
|
this.current = index
|
||||||
|
})
|
||||||
|
},
|
||||||
|
towNumber(val) {
|
||||||
|
return (val / 100).toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.context {
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
top: 160rpx;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs-top {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 85rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-list {
|
||||||
|
position: relative;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
height: calc(100vh - 88rpx - 100rpx - var(--status-bar-height));
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.flex-box {
|
||||||
|
width: 730rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
@include flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: left;
|
||||||
|
|
||||||
|
.product-item {
|
||||||
|
width: 345rpx;
|
||||||
|
height: 450rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx 10rpx 0;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
|
||||||
|
.product-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 300rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-button {
|
||||||
|
width: 330rpx;
|
||||||
|
margin: 15rpx auto 0;
|
||||||
|
|
||||||
|
.product-text {
|
||||||
|
font-size: 25rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-price-button {
|
||||||
|
font-size: 20rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
|
.product-price {
|
||||||
|
color: red;
|
||||||
|
|
||||||
|
.price-size {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-like-ccount {
|
||||||
|
font-size: 16rpx;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user