【商城项目19】剩下的API编写

本文深入解析商城项目的API设计与实现,涵盖属性管理、属性分组查询、产品属性配置、属性编辑保存、属性类型区分等核心功能,通过实例展示Spring Boot框架下RESTful API的开发流程。

【商城项目19】剩下的API编写

1.新增属性

特点:1.用到了org.springframework.beans.BeanUtils;

BeanUtils.copyProperties(attr,attrEntity);

2.用到了vo模型:把接受的json数据变成一个打自定义对象。

image-20200612151141833

http://localhost:11000/product/attr/save

{
  "attrGroupId": 0, 
  "attrName": "像素",
  "attrType": 0, 
  "catelogId": 0, 
  "enable": 0, 
  "icon": "string", 
  "searchType": 0,
  "showDesc": 0,
  "valueSelect": "string", 
  "valueType": 0
}
{
    "msg": "success",
    "code": 0
}
@RequestMapping("/save")
//@RequiresPermissions("product:attr:save")
public R save(@RequestBody AttrVo attr) throws InvocationTargetException, IllegalAccessException {
    System.out.println(attr.getAttrName());
    attrService.saveAttr(attr);

    return R.ok();
}
    @Override
    public void saveAttr(AttrVo attr) throws InvocationTargetException, IllegalAccessException {
        AttrEntity attrEntity = new AttrEntity();
//        attrEntity.setAttrName(attr.getAttrName());
        BeanUtils.copyProperties(attr,attrEntity);
        //1、保存基本数据
        this.save(attrEntity);
        System.out.println(attrEntity.getAttrName());
        //2、保存关联关系
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationDao.insert(relationEntity);
    }
2.属性分组模糊查询

特点:用wrapper封装查询条件,使用.eq like .or

http://localhost:11000/mailproducts/attrgroup/list/170?key=不

get

{
    "msg": "success",
    "code": 0,
    "page": {
        "totalCount": 1,
        "pageSize": 10,
        "totalPage": 1,
        "currPage": 1,
        "list": [
            {
                "attrGroupId": 1,
                "attrGroupName": "不知道",
                "sort": 1,
                "descript": "七大服务",
                "icon": "群文档",
                "catelogId": 170,
                "catelogPath": null
            }
        ]
    }
}
    @RequestMapping("/list/{catelogId}")
    //@RequiresPermissions("product:attrgroup:list")
    public R list(@RequestParam Map<String, Object> params,
                  @PathVariable("catelogId") Long catelogId){
//        PageUtils page = attrGroupService.queryPage(params);

        PageUtils page = attrGroupService.queryPage(params,catelogId);

        return R.ok().put("page", page);
    }
  @Override
    public PageUtils queryPage(Map<String, Object> params, Long catelogId) {
        String key = (String) params.get("key");
        //select * from pms_attr_group where catelog_id=? and (attr_group_id=key or attr_group_name like %key%)
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<AttrGroupEntity>();
        if(!StringUtils.isEmpty(key)){
            wrapper.and((obj)->{
                obj.eq("attr_group_id",key).or().like("attr_group_name",key);
            });
        }

        if( catelogId == 0){
            IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),
                    wrapper);
            return new PageUtils(page);
        }else {
            wrapper.eq("catelog_id",catelogId);
            IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),
                    wrapper);
            return new PageUtils(page);
        }
    }

3.获取某个分类的属性

http://localhost:11000/product/attr/base/listforspu/1 get

{
    "msg": "success",
    "code": 0,
    "data": [
        {
            "id": 1,
            "spuId": 1,
            "attrId": 2,
            "attrName": "尺寸",
            "attrValue": null,
            "attrSort": null,
            "quickShow": null
        },
        {
            "id": 2,
            "spuId": 1,
            "attrId": 1,
            "attrName": "像素",
            "attrValue": null,
            "attrSort": null,
            "quickShow": null
        }
    ]
}
@GetMapping("/base/listforspu/{spuId}")
public R baseAttrlistforspu(@PathVariable("spuId") Long spuId){

    List<ProductAttrValueEntity> entities = productAttrValueService.baseAttrlistforspu(spuId);

    return R.ok().put("data",entities);
}
    @Override
    public List<ProductAttrValueEntity> baseAttrlistforspu(Long spuId) {
        List<ProductAttrValueEntity> entities = this.baseMapper.selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        return entities;
    }
4.回显属性

http://localhost:11000/product/attr/info/1 get

 @RequestMapping("/info/{attrId}")
    //@RequiresPermissions("product:attr:info")
    public R info(@PathVariable("attrId") Long attrId){
		//AttrEntity attr = attrService.getById(attrId);
        AttrRespVo respVo = attrService.getAttrInfo(attrId);

        return R.ok().put("attr", respVo);
    }
@Override
    public AttrRespVo getAttrInfo(Long attrId) {
        AttrRespVo respVo = new AttrRespVo();
        AttrEntity attrEntity = this.getById(attrId);
        BeanUtils.copyProperties(attrEntity,respVo);



            //1、设置分组信息
            AttrAttrgroupRelationEntity attrgroupRelation = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
            if(attrgroupRelation!=null){
                respVo.setAttrGroupId(attrgroupRelation.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupRelation.getAttrGroupId());
                if(attrGroupEntity!=null){
                    respVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }


        //2、设置分类信息
        Long catelogId = attrEntity.getCatelogId();
        Long[] catelogPath = categoryService.findCatelogPath(catelogId);
        respVo.setCatelogPath(catelogPath);

        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
        if(categoryEntity!=null){
            respVo.setCatelogName(categoryEntity.getName());
        }


        return respVo;
    }
{
    "msg": "success",
    "code": 0,
    "attr": {
        "attrId": 1,
        "attrName": "像素",
        "searchType": 0,
        "valueType": null,
        "icon": "string",
        "valueSelect": "string",
        "attrType": 1,
        "enable": 1,
        "catelogId": 170,
        "showDesc": 0,
        "attrGroupId": 1,
        "catelogName": "影视",
        "groupName": "不知道",
        "catelogPath": [
            1,
            23,
            170
        ]
    }
}
5.属性修改后保存

http://localhost:11000/product/attr/update post

{
  "attrId": 1,
  "attrGroupId": 0,
  "attrName": "属性名",
  "attrType": 0, 
  "catelogId": 1,
  "enable": 0, 
  "icon": "string", 
  "searchType": 0,
  "showDesc": 0, 
  "valueSelect": "string", 
  "valueType": 0 
}
  @RequestMapping("/update")
    //@RequiresPermissions("product:attr:update")
    public R update(@RequestBody AttrVo attr){
		attrService.updateAttr(attr);

        return R.ok();
    }
AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);
        this.updateById(attrEntity);

        if(attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            //1、修改分组关联
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();

            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attr.getAttrId());

            Integer count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
            if(count>0){

                relationDao.update(relationEntity,new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attr.getAttrId()));

            }else{
                relationDao.insert(relationEntity);
            }
        }

6.属性区分销售属性还是分类属性

ProductConstant:

package com.ufo.common.constant;

import lombok.Data;

public class ProductConstant {


    public enum  AttrEnum{
        ATTR_TYPE_BASE(1,"基本属性"),ATTR_TYPE_SALE(0,"销售属性");
        private int code;
        private String msg;

        AttrEnum(int code,String msg){
            this.code = code;
            this.msg = msg;
        }

        public int getCode() {
            return code;
        }

        public String getMsg() {
            return msg;
        }
    }
}

   @GetMapping("/{attrType}//list/{catelogId}")
    public R baseAttrList(@RequestParam Map<String, Object> params,
                          @PathVariable("catelogId") Long catelogId,
                          @PathVariable("attrType")String type){

        PageUtils page = attrService.queryBaseAttrPage(params,catelogId,type);
        return R.ok().put("page", page);
    }

实现类:查询

 @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>();

        if(catelogId != 0){
            queryWrapper.eq("catelog_id",catelogId).eq("attr_type","base".equalsIgnoreCase(type)?1:0);
        }

        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            //attr_id  attr_name
            queryWrapper.and((wrapper)->{
                wrapper.eq("attr_id",key).or().like("attr_name",key);
            });
        }

        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );

        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> records = page.getRecords();
        List<AttrRespVo> respVos = records.stream().map((attrEntity) -> {
            AttrRespVo attrRespVo = new AttrRespVo();
            BeanUtils.copyProperties(attrEntity, attrRespVo);

            //1、设置分类和分组的名字
            if("base".equalsIgnoreCase(type)){
                AttrAttrgroupRelationEntity attrId = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
                if (attrId != null && attrId.getAttrGroupId()!=null) {
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrId.getAttrGroupId());
                    attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }

            }


            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
            if (categoryEntity != null) {
                attrRespVo.setCatelogName(categoryEntity.getName());
            }
            return attrRespVo;
        }).collect(Collectors.toList());

        pageUtils.setList(respVos);
        return pageUtils;
    }

实现类:更新

 @Transactional
    @Override
    public void updateAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr,attrEntity);
        this.updateById(attrEntity);
        if(attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            //1、修改分组关联
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();

            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attr.getAttrId());

            Integer count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
            if (count > 0) {

                relationDao.update(relationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));

            } else {
                relationDao.insert(relationEntity);
            }
        }


    }

新增:

   @Override
    public void saveAttr(AttrVo attr) throws InvocationTargetException, IllegalAccessException {
        AttrEntity attrEntity = new AttrEntity();
//        attrEntity.setAttrName(attr.getAttrName());
        BeanUtils.copyProperties(attr,attrEntity);
        //1、保存基本数据
        this.save(attrEntity);
        //2、保存关联关系
        if(attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId()!=null){
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attr.getAttrGroupId());
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationDao.insert(relationEntity);
        }
7…

查询一个品牌有哪些分类GET
http://localhost:11000/product/categorybrandrelation/catelog/list?brandId=1
@RequestParam(“brandId”)Long brandId

给品牌新增分类:
http://localhost:11000/product/categorybrandrelation/save
{“brandId”:2,“catelogId”:5}
@RequestBody CategoryBrandRelationEntity categoryBrandRelation

image-20200612163956574

<template> <view> <!-- 搜索框 --> <view class="search-container"> <view class="search-box" @click="gotosearch"> <image src="/static/搜索.png" class="search-icon"></image> <input class="search-input" placeholder="请输入关键词" placeholder-class="placeholder-style" confirm-type="search" /> </view> </view> <!-- 分类列表 --> <view class="container"> <!-- 左侧分类列表 --> <scroll-view class="category-list" scroll-y> <view v-for="(category, index) in categories" :key="index" class="category-item" :class="{ active: currentIndex === index }" @click="selectCategory(index)"> {{ category.name }} </view> </scroll-view> <!-- 右侧商品内容 --> <scroll-view class="product-list" scroll-y @click="gotoDetails"> <view v-if="currentProducts.length > 0"> <!-- 商品1放大显示 --> <view class="featured-product"> <image :src="currentProducts[0].image" class="featured-image"></image> </view> <!-- 剩下的商品按三列布局 --> <view class="normal-products"> <view v-for="(product, index) in currentProducts.slice(1)" :key="index" class="normal-product-item"> <image :src="product.image" class="normal-product-image"></image> <text class="normal-product-name">{{ product.name }}</text> </view> </view> </view> <view v-else class="empty-tip">暂无商品</view> </scroll-view> </view> </view> </template> <script> import TabBarVue from '../TabBar/TabBar.vue'; import { ProductList } from '../../Utils/api'; import { mapMutations, mapState } from 'vuex'; import modelVue from '../model.vue'; import { get_address } from '@/Utils/api.js' export default { data() { return { // 分类数据 categories: [ { name: "精选推荐", products: [ { name: "商品1", image: "/static/大商品.png" }, { name: "商品2", image: "/static/商品.png" }, { name: "商品3", image: "/static/商品.png" }, { name: "商品4", image: "/static/商品.png" }, { name: "商品5", image: "/static/商品.png" }, { name: "商品6", image: "/static/商品.png" }, { name: "商品7", image: "/static/商品.png" }, { name: "商品8", image: "/static/商品.png" }, { name: "商品9", image: "/static/商品.png" }, { name: "商品10", image: "/static/商品.png" }, ], }, { name: "商务文具", products: [ { name: "商品1", image: "/static/大商品.png" }, { name: "商品2", image: "/static/商品.png" }, { name: "商品3", image: "/static/商品.png" }, { name: "商品4", image: "/static/商品.png" }, { name: "商品5", image: "/static/商品.png" }, { name: "商品6", image: "/static/商品.png" }, { name: "商品7", image: "/static/商品.png" }, { name: "商品8", image: "/static/商品.png" }, { name: "商品9", image: "/static/商品.png" }, { name: "商品10", image: "/static/商品.png" }, ], }, { name: "家具生活", products: [ { name: "商品1", image: "/static/大商品.png" }, { name: "商品2", image: "/static/商品.png" }, { name: "商品3", image: "/static/商品.png" }, { name: "商品4", image: "/static/商品.png" }, { name: "商品5", image: "/static/商品.png" }, { name: "商品6", image: "/static/商品.png" }, { name: "商品7", image: "/static/商品.png" }, { name: "商品8", image: "/static/商品.png" }, { name: "商品9", image: "/static/商品.png" }, { name: "商品10", image: "/static/商品.png" }, ], }, { name: "数码家电", products: [ { name: "商品1", image: "/static/大商品.png" }, { name: "商品2", image: "/static/商品.png" }, { name: "商品3", image: "/static/商品.png" }, { name: "商品4", image: "/static/商品.png" }, { name: "商品5", image: "/static/商品.png" }, { name: "商品6", image: "/static/商品.png" }, { name: "商品7", image: "/static/商品.png" }, { name: "商品8", image: "/static/商品.png" }, { name: "商品9", image: "/static/商品.png" }, { name: "商品10", image: "/static/商品.png" }, ], }, { name: "服饰鞋包", products: [ { name: "商品1", image: "/static/大商品.png" }, { name: "商品2", image: "/static/商品.png" }, { name: "商品3", image: "/static/商品.png" }, { name: "商品4", image: "/static/商品.png" }, { name: "商品5", image: "/static/商品.png" }, { name: "商品6", image: "/static/商品.png" }, { name: "商品7", image: "/static/商品.png" }, { name: "商品8", image: "/static/商品.png" }, { name: "商品9", image: "/static/商品.png" }, { name: "商品10", image: "/static/商品.png" }, ], }, { name: "美食清酒", products: [ { name: "商品1", image: "/static/大商品.png" }, { name: "商品2", image: "/static/商品.png" }, { name: "商品3", image: "/static/商品.png" }, { name: "商品4", image: "/static/商品.png" }, { name: "商品5", image: "/static/商品.png" }, { name: "商品6", image: "/static/商品.png" }, { name: "商品7", image: "/static/商品.png" }, { name: "商品8", image: "/static/商品.png" }, { name: "商品9", image: "/static/商品.png" }, { name: "商品10", image: "/static/商品.png" }, ], } ], // 当前选中的分类索引 currentIndex: 0, // 当前显示的商品列表 currentProducts: [] }; }, components: { TabBarVue }, methods: { // 导航到搜索界面 gotosearch() { uni.navigateTo({ url: "/pages/Classification/search" // 搜索页面的路径 }); }, gotoDetails() { uni.navigateTo({ url: "/pages/Classification/Claassification-Details" // 搜索页面的路径 }); }, // 点击分类项 selectCategory(index) { this.currentIndex = index; this.currentProducts = this.categories[index].products; } }, onLoad() { // 初始化时加载第一个分类的商品 this.currentProducts = this.categories[0].products; } } </script> <style lang="scss"> /* 搜索框样式 */ .search-container { /* 固定定位 */ position: fixed; top: 0; left: 0; width: 100%; /* 设置内边距防止内容紧贴边缘 */ padding: 15rpx 30rpx; /* 背景颜色 */ background: #ffffff; /* 保证层级在最上层 */ z-index: 999; box-sizing: border-box; } .search-box { /* 弹性布局 */ display: flex; align-items: center; height: 70rpx; background: #f5f5f5; border-radius: 20rpx; /* 圆角效果 */ padding: 0 20rpx; } .search-icon { width: 32rpx; height: 32rpx; margin-right: 15rpx; } .search-input { flex: 1; font-size: 28rpx; } /* 容器样式 */ .container { display: flex; height: 100vh; } /* 左侧分类列表 */ .category-list { width: 200rpx; background-color: #f5f5f5; border-right: 1px solid #ddd; .category-item { padding: 20rpx; text-align: center; font-size: 28rpx; color: #333; &.active { background-color: #fff; color: #1aad19; font-weight: bold; } } } /* 右侧商品内容 */ .product-list { flex: 1; padding: 20rpx; /* 特别展示的商品1 */ .featured-product { display: flex; flex-direction: column; align-items: center; margin-bottom: 20rpx; .featured-image { width: 100%; height: 250rpx; border-radius: 10rpx; } .featured-name { font-size: 32rpx; color: #333; margin-top: 10rpx; } } /* 剩下的商品三列布局 */ .normal-products { display: flex; flex-wrap: wrap; .normal-product-item { width: 33.33%; box-sizing: border-box; padding: 10rpx; .normal-product-image { width: 150rpx; height: 150rpx; border-radius: 50%; display: block; margin: 0 auto; } .normal-product-name { font-size: 24rpx; color: #333; text-align: center; margin-left: 25%; margin-top: 10rpx; } } } .empty-tip { text-align: center; font-size: 28rpx; color: #999; margin-top: 100rpx; } } </style> 根据以上代码编写商品列表详情页,要求编写的顶部有精选标签四个字作为页面标题,右上角有搜索符号,标题和右上角搜索符号下为导航栏,导航栏为上述代码中左侧列表的横板形式,导航栏下则以两个商品为一行的形式从上往下渲染上述代码中的商品
最新发布
05-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值