SSM搭建二手市場交易平臺(十七):前臺商品列表,搜索,動態排序

寫在前面

在前面的某一篇裏面,我們完成了後臺商品詳情,列表,搜索,動態排序功能的開發。那麼本篇我們來介紹前臺商品詳情,列表,搜索,動態排序功能的開發,這個和那個不一樣,希望大家多看幾遍,好好理解一下其中的不同。

前臺商品詳情獲取

我們打開controller包,在裏面的portal包裏面新建ProductController.java文件,裏面寫入以下代碼:

   /***
     * 前臺獲取商品的詳情信息
     * @author lenovo
     * */
    @RequestMapping(value = "detail.do")  //這裏就是具體的每個方法的url鏈接
    @ResponseBody   //自動序列化json功能
    public ServerResponse<ProductDetailVo> detail(Integer productId){
        //前臺和後臺關於商品詳情信息的獲取是非常相似的,除了前臺需要判斷商品的狀態,如果下線或者刪除就返回一個錯誤或者是不進行返回
        return iProductService.getProductDetail(productId);
    }

接着打開ProductServiceImpl.java文件,在裏面新增以下代碼:

    @Autowired
    private CategoryMapper categoryMapper;

    /***
     *前臺獲取商品的詳情信息
     * */
    public ServerResponse<ProductDetailVo> getProductDetail(Integer productId){
        //判斷商品是否存在
        if (productId == null) {   //商品id不存在
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }

        Product product = productMapper.selectByPrimaryKey(productId);
        if (product == null) {
            return ServerResponse.createByErrorMessage("該商品已下架或者刪除!");
        }

        if(product.getStatus() != Const.ProductStatusEnum.ON_SALE.getCode()){
            return ServerResponse.createByErrorMessage("該商品已下架或者刪除!");
        }

        //商品存在,我們現在是進行信息的傳遞
        ProductDetailVo productDetailVo =assembleProductDetailVo(product);
        return ServerResponse.createBySuccess(productDetailVo);
    }

這段代碼基本上和我們之前後臺獲取商品詳情的邏輯一樣,但是多了一部就是需要判斷商品的狀態,對於那些不存在或者已經下架的商品我們就不需要顯示了,直接返回提示信息。

看到if(product.getStatus() != Const.ProductStatusEnum.ON_SALE.getCode()){ return ServerResponse.createByErrorMessage("該商品已下架或者刪除!"); }這行代碼,說明我們需要新建一個枚舉類,打開之前的Comm包下面的Const這個java文件,在裏面新增以下代碼:

public enum ProductStatusEnum{
        ON_SALE(1,"在線")
        ;
        private String value;
        private int code;

        ProductStatusEnum(int code,String value){
            this.code =code;
            this.value=value;
        }

        public String getValue() {
            return value;
        }

        public int getCode() {
            return code;
        }
    }

最後打開IProductService這個接口,我們把剛纔的實現類的接口代碼添加進去:

ServerResponse<ProductDetailVo> getProductDetail(Integer productId);   //前臺獲取商品的詳情信息

這樣我們關於前臺商品詳情獲取的功能開發就完成了,接下來就是前臺列表的分頁,搜索,動態排序功能了。

前臺列表分頁,搜索,動態排序實現

老規矩,我們打開ProductController.java文件,裏面寫入以下代碼:

    /***
     * 前臺獲取商品列表並進行分頁,搜索,動態排序
     * @author lenovo
     * */
    @RequestMapping(value = "list.do")  //這裏就是具體的每個方法的url鏈接
    @ResponseBody   //自動序列化json功能
    public ServerResponse<PageInfo> list (@RequestParam(value = "keyword" ,required = false) String keyword,
                                          @RequestParam(value = "categoryId" ,required = false)Integer categoryId,
                                          @RequestParam(value = "pageNum" ,defaultValue = "1")int pageNum,
                                          @RequestParam(value = "pageSize" ,defaultValue = "10")int pageSize,
                                          @RequestParam(value = "orderBy" ,defaultValue = "")String orderBy
                                          ){
        return iProductService.getProductByKeywordCategory(keyword,categoryId,pageNum,pageSize,orderBy);

    }

接着打開ProductServiceImpl.java文件,在裏面新增以下代碼:

   /***
     * 前臺獲取商品列表並進行分頁,搜索,動態排序
     * @author lenovo
     * */
    public ServerResponse<PageInfo> getProductByKeywordCategory(String keyword,Integer categoryId,int pageNum,int pageSize,String orderBy){
        //判斷一下keyword和categoryId是否爲空,如果是的話就顯示參數錯誤
        if(StringUtils.isBlank(keyword)  && categoryId ==null){
            return ServerResponse.createByErrorCodeMessage(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getDesc());
        }

        List<Integer> categoryIdList = new ArrayList<Integer>();  //這裏聲明一個list用於保存通過遞歸得到的它的及其子類id

        if(categoryId !=null){
            //通過categoryId來獲取category這個對象
            Category category =categoryMapper.selectByPrimaryKey(categoryId);

            if(category ==null&&StringUtils.isBlank(keyword)){
                //沒有該分類,並且還沒有關鍵字,這個時候返回一個空的結果集,不能報錯
                //這裏的意思就是說假設前端請求categoryId==1,但是我們數據庫裏面沒有1只有2,這就是不匹配而已,並不是錯誤
                PageHelper.startPage(pageNum,pageSize);
                List<ProductListVo> productListVoList =Lists.newArrayList();
                PageInfo pageInfo =new PageInfo(productListVoList);
                return ServerResponse.createBySuccess(pageInfo);
            }

            //這是通過之前寫的遞歸算法拿到了它的分類以及其子分類
            categoryIdList =iCategoryService.selectCategoryAndChildrenById(category.getId()).getData();   //這裏需要去CategoryServiceImpl裏面對我們之前寫的關於遞歸查詢子節點的函數進行一個修改,添加返回值的類型List<Integer>
        }

        //判斷keyword是否爲空
        if(StringUtils.isNotBlank(keyword)){
            //將keyword變成%keyword%用於模糊查詢操作
            keyword =new StringBuilder().append("%").append(keyword).append("%").toString();
        }
        PageHelper.startPage(pageNum,pageSize);

        //進行排序處理
        //我們和前端約定弄一個接口去實現orderBy的選擇
        //判斷orderBy這個字段不爲空
        if(StringUtils.isNotBlank(orderBy)){
            //判斷前端傳的orderBy是否在我們定義的Const集合中
            if(Const.ProductListOrderBy.PRICE_ASC_DESC.contains(orderBy)){
                //因爲pageHelper.orderBy裏面的參格式是price desc,所以我們需要對集合中的"price_desc"和"price_asc"進行分割
                String[] orderByArray =orderBy.split("_");
                PageHelper.orderBy(orderByArray[0]+" "+orderByArray[1]);  //注意一下這裏雙引號之間有一個空格
            }
        }


        //進行動態搜索
        //這裏注意我們的keyword就是productName

        //僅僅使用下面的這行代碼是不可以的,因爲keyword和categoryIdList有可能沒有,所以我們需要使用三元運算符進行判斷
       // List<Product> productList =productMapper.selectByNameAndCategoryIds(keyword,categoryIdList);
        //將之前的(keyword,categoryIdList)變成(StringUtils.isBlank(keyword)?null:keyword,categoryIdList.size()==0?null:categoryIdList)

        //使用sql語句獲取的結果
        List<Product> productList =productMapper.selectByNameAndCategoryIds(StringUtils.isBlank(keyword)?null:keyword,categoryIdList.size()==0?null:categoryIdList);
        List<ProductListVo> productListVoList =Lists.newArrayList();
        for(Product product:productList){
            ProductListVo productListVo =assembleProductListVo(product);
            productListVoList.add(productListVo);
        }

        PageInfo pageInfo =new PageInfo(productList);  //注意這裏傳入的就是通過sql語句獲得的列表
        pageInfo.setList(productListVoList);
        return ServerResponse.createBySuccess(pageInfo);

    }

這段代碼是核心代碼,對此我有幾個注意事項需要說明:
1、首先我們這個商品的查詢是通過keyword來實現的,採用模糊查詢。
2、假設前端請求categoryId==1,但是我們數據庫裏面沒有1只有2,這就是不匹配而已,並不是錯誤所以我們需要進行一個信息提示。
3、我們前面參數中的categoryId是用來獲取category這個對象,然後利用這個對象來調用遞歸算法拿到了它的分類以及其子分類組成的列表。
4、排序處理的時候,我們打開Const這個類,在裏面新增以下代碼:

    public interface ProductListOrderBy{
        //這裏使用set是因爲set的contain函數的時間複雜度是O(1),而List的contain函數的時間複雜度則是O(n);
        Set<String> PRICE_ASC_DESC = Sets.newHashSet("price_desc","price_asc");  //按照價格進行排序
    }

這個就是排序的依據,而且不知道你注意到沒有,我們這裏使用了set是因爲set的contains函數的時間複雜度是O(1),而List的contains函數的時間複雜度則是O(n);

5、因爲pageHelper.orderBy裏面的參格式是price desc,所以我們需要對集合中的"price_desc""price_asc"進行分割,我們知道split函數最後返回的就是一個String類型的數組,最後直接調用它的PageHelper.orderBy(orderByArray[0]+" "+orderByArray[1]);就可以了。
6、動態搜索,這裏注意我們的keyword就是productName,而且keyword和categoryIdList有可能沒有,所以我們需要使用三元運算符進行判斷:

StringUtils.isBlank(keyword)?null:keyword,categoryIdList.size()==0?null:categoryIdList

7、注意這裏的selectByNameAndCategoryIds函數,所以我們需要ProductMapper.java文件,新增以下代碼:

  //注意在mybatis裏面,多個參數時需要使用param註解
    List<Product> selectByNameAndCategoryIds(@Param(value = "productName") String productName,@Param("categoryIdList")List<Integer> categoryIdList);

然後記得打開ProductMapper.xml文件,新增sql語句:

    <select id="selectByNameAndCategoryIds" resultMap="BaseResultMap" parameterType="map">
        SELECT
        <include refid="Base_Column_List"/>
        from store_product
        where status = 1
        <if test="productName != null">
            and name like #{productName}
        </if>
        <if test="categoryIdList != null" >
            and category_id in
            <foreach item="item" index="index" open="(" separator="," close=")" collection="categoryIdList">
                #{item}
            </foreach>
        </if>
    </select>

8、categoryIdList=iCategoryService.selectCategoryAndChildrenById(category.getId()).getData();這裏需要去CategoryServiceImpl裏面對我們之前寫的關於遞歸查詢子節點的函數進行一個修改,添加返回值的類型List<Integer>:

public ServerResponse<List<Integer>> selectCategoryAndChildrenById(Integer categoryId){

以及iCategoryService.java文件,修改爲以下代碼:

 ServerResponse<List<Integer>> selectCategoryAndChildrenById(Integer categoryId);    //後臺管理員遞歸查詢本節點及子節點的id並返回列表

最後記得打開IProductService這個接口,我們把剛纔的實現類的接口代碼添加進去:

 ServerResponse<PageInfo> getProductByKeywordCategory(String keyword,Integer categoryId,int pageNum,int pageSize,String orderBy);   //前臺獲取商品列表並進行分頁,搜索,動態排序

這樣我們本篇關於前臺商品詳情,列表,搜索,動態排序功能的開發介紹就到此爲止了,接下來是進行各個相關接口的測試。

由於測試比較簡單,這裏直接附上幾張測試截圖即可,不作過多說明:

這樣我們本篇關於前臺商品詳情,列表,搜索,動態排序功能開發的介紹就到此爲止了,感謝你的賞閱!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章