jason 2 жил өмнө
parent
commit
14d02bdfb3
10 өөрчлөгдсөн 117 нэмэгдсэн , 98 устгасан
  1. 2 2
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
  2. 21 22
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java
  3. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java
  4. 5 7
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java
  5. 6 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java
  6. 6 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java
  7. 13 13
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java
  8. 15 4
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java
  9. 48 24
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java
  10. 0 22
      yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml

+ 2 - 2
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java

@@ -49,7 +49,7 @@ public interface ErrorCodeConstants {
     ErrorCode COMMENT_ADDITIONAL_EXISTS  = new ErrorCode(1008007003, "商品追加评价已存在");
 
     // ========== 商品 收藏 1008008000 ==========
-    ErrorCode COLLECTION_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏");
-    ErrorCode COLLECTION_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在");
+    ErrorCode PRODUCT_FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏");
+    ErrorCode PRODUCT_FAVORITE_NOT_EXISTS = new ErrorCode(1008008001, "商品收藏不存在");
 
 }

+ 21 - 22
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java

@@ -1,22 +1,20 @@
 package cn.iocoder.yudao.module.product.controller.app.favorite;
 
-import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO;
-import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService;
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO;
+import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum.COLLECT;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "用户 APP - 商品收藏")
 @RestController
@@ -26,30 +24,31 @@ public class AppFavoriteController {
     @Resource
     private ProductFavoriteService productFavoriteService;
 
-    // TODO @jason:创建;create
-    @PostMapping(value = "/collect")
+    @PostMapping(value = "/create")
     @Operation(summary = "商品收藏")
-    public CommonResult<Boolean> collect(@RequestBody @Valid AppFavoriteReqVO reqVO) {
-        Assert.isTrue(Objects.equals(COLLECT.getType(), reqVO.getType()), "参数type 不匹配");
-        return success(productFavoriteService.collect(reqVO));
+    public CommonResult<Boolean> create(@RequestBody @Valid AppFavoriteReqVO reqVO) {
+        Long loginUserId = getLoginUserId();
+        return success(productFavoriteService.create(loginUserId, reqVO));
     }
 
-    // TODO @jason:创建;delete;使用 @DeleteMapping
-    @PostMapping(value = "/cancelCollect")
+    @DeleteMapping(value = "/delete")
     @Operation(summary = "取消商品收藏(通过商品详情)")
-    public CommonResult<Boolean> cancelCollect(@RequestBody @Valid AppFavoriteReqVO reqVO) {
-        // TODO @jason:是不是不用校验呀?
-        Assert.isTrue(Objects.equals(COLLECT.getType(), reqVO.getType()), "参数type 不匹配");
-        return success(productFavoriteService.cancelCollect(reqVO));
+    public CommonResult<Boolean> delete(@RequestBody @Valid AppFavoriteReqVO reqVO) {
+        Long loginUserId = getLoginUserId();
+        return success(productFavoriteService.delete(loginUserId,reqVO));
     }
 
-    // TODO @jason:page;分页
-    @GetMapping(value = "/collectList")
-    @Operation(summary = "商品收藏列表")
-    public CommonResult<PageResult<AppFavoriteRespVO>> pageCollectList(AppFavoritePageReqVO reqVO) {
-        return success(productFavoriteService.pageCollectList(reqVO));
+    @GetMapping(value = "/page")
+    @Operation(summary = "分页获取商品收藏列表")
+    public CommonResult<PageResult<AppFavoriteRespVO>> page(AppFavoritePageReqVO reqVO) {
+        Long userId = getLoginUserId();
+        return success(productFavoriteService.page(userId,reqVO));
     }
 
-    // TODO @json:需要在给一个,用户查询某个商品是否收藏;详情页要用
-
+    @GetMapping(value = "/checkFavorite")
+    @Operation(summary = "检查是否收藏过商品")
+    public CommonResult<Boolean> checkFavorite(AppFavoriteReqVO reqVO) {
+        Long userId = getLoginUserId();
+        return success(productFavoriteService.checkFavorite(userId,reqVO));
+    }
 }

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java

@@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull;
 
 import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
 
-@Schema(description = "用户 APP - 商品收藏创建 Request VO")
+@Schema(description = "用户 APP - 商品收藏 Request VO")
 @Data
 public class AppFavoriteReqVO {
 

+ 5 - 7
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java

@@ -3,24 +3,22 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
+
 @Schema(description = "用户APP - 商品收藏 Response VO")
 @Data
 public class AppFavoriteRespVO {
 
-    // TODO @jason:required true 哈
-    @Schema(description = "编号", example = "1")
+    @Schema(description = "编号", requiredMode = REQUIRED, example = "1")
     private Long id;
 
-    // TODO @jason:required true 哈
-    @Schema(description = "商品 SPU 编号", example = "29502")
+    @Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502")
     private Long spuId;
 
-    // TODO @jason:required true 哈
-    @Schema(description = "类型", example = "1")
+    @Schema(description = "类型", requiredMode = REQUIRED, example = "1")
     private Integer type;
 
     // ========== 商品相关字段 ==========
-
     @Schema(description = "商品 SPU 名称", example = "赵六")
     private String spuName;
 

+ 6 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java

@@ -1,8 +1,11 @@
 package cn.iocoder.yudao.module.product.convert.favorite;
 
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO;
+import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
 import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
 @Mapper
@@ -11,4 +14,7 @@ public interface ProductFavoriteConvert {
     ProductFavoriteConvert INSTANCE = Mappers.getMapper(ProductFavoriteConvert.class);
 
     ProductFavoriteDO convert(Long userId, AppFavoriteReqVO reqVO);
+    @Mapping(target = "id", source = "favoriteDO.id")
+    @Mapping(target = "spuName", source = "spuDO.name")
+    AppFavoriteRespVO convert(ProductSpuDO spuDO, ProductFavoriteDO favoriteDO);
 }

+ 6 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java

@@ -1,7 +1,8 @@
 package cn.iocoder.yudao.module.product.dal.dataobject.favorite;
 
-import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
+import cn.iocoder.yudao.module.product.enums.favorite.ProductFavoriteTypeEnum;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -20,7 +21,7 @@ import lombok.*;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class ProductFavoriteDO extends TenantBaseDO { // TODO @jason:如无必要,使用 BaseDO 哈。例如说 tenant_id 在业务里,是否需要使用到
+public class ProductFavoriteDO extends BaseDO {
 
     /**
      * 编号,主键自增
@@ -40,7 +41,9 @@ public class ProductFavoriteDO extends TenantBaseDO { // TODO @jason:如无必
      */
     private Long spuId;
     /**
-     * 类型  1 收藏;2 点赞 // TODO @jason:不要注释 1 收藏 2 点赞;而是注释好,它对应的枚举类
+     * 类型
+     *
+     * 枚举 {@link ProductFavoriteTypeEnum}
      */
     private Integer type;
 

+ 13 - 13
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java

@@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
 import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO;
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -15,24 +16,23 @@ import org.apache.ibatis.annotations.Param;
 @Mapper
 public interface ProductFavoriteMapper extends BaseMapperX<ProductFavoriteDO> {
 
-    default  ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type) {
-        Assert.notNull(userId, "the userId argument  must not be null");
-        Assert.notNull(spuId, "the spuId argument must not be null");
-        Assert.notNull(type, "the type argument must not be null");
+    default ProductFavoriteDO selectByUserAndSpuAndType(Long userId, Long spuId, Integer type) {
+        Assert.notNull(userId, "the userId must not be null");
+        Assert.notNull(spuId, "the spuId must not be null");
+        Assert.notNull(type, "the type must not be null");
         return selectOne(new LambdaQueryWrapperX<ProductFavoriteDO>()
                 .eq(ProductFavoriteDO::getUserId, userId)
                 .eq(ProductFavoriteDO::getSpuId, spuId)
                 .eq(ProductFavoriteDO::getType, type));
     }
 
-    default PageResult<AppFavoriteRespVO> selectPageByUserAndType(Long userId, Integer type, PageParam pageParam){
-        Page<AppFavoriteRespVO> page =  MyBatisUtils.buildPage(pageParam);
-        page = selectFavoriteProductList(page, userId, type);
-        return new PageResult<>(page.getRecords(), page.getTotal());
+    default PageResult<ProductFavoriteDO> selectPageByUserAndType(Long userId, Integer type, PageParam pageParam) {
+        Assert.notNull(userId, "the userId must not be null");
+        Assert.notNull(type, "the type must not be null");
+        Assert.notNull(pageParam, "the pageParam must not be null");
+        return selectPage(pageParam, new LambdaQueryWrapper<ProductFavoriteDO>()
+                .eq(ProductFavoriteDO::getUserId, userId)
+                .eq(ProductFavoriteDO::getType, type)
+                .orderByDesc(ProductFavoriteDO::getId));
     }
-
-    // TODO @jason:内存中拼接哈。这样好兼容更多的 db 类型;
-    Page<AppFavoriteRespVO> selectFavoriteProductList(Page<AppFavoriteRespVO> page,
-                                                      @Param("userId") Long userId,
-                                                      @Param("type") Integer type);
 }

+ 15 - 4
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java

@@ -15,20 +15,31 @@ import javax.validation.Valid;
 public interface ProductFavoriteService {
 
     /**
-     * 商品收藏
+     * 创建商品收藏
+     * @param userId 用户id
      * @param reqVO 请求vo
      */
-    Boolean collect(@Valid  AppFavoriteReqVO reqVO);
+    Boolean create(Long userId, @Valid AppFavoriteReqVO reqVO);
 
     /**
      * 取消商品收藏 (通过商品详情页面)
+     * @param userId 用户id
      * @param reqVO 请求vo
      */
-    Boolean cancelCollect(@Valid AppFavoriteReqVO reqVO);
+    Boolean delete(Long userId, @Valid AppFavoriteReqVO reqVO);
 
     /**
      * 分页查询用户收藏列表
+     * @param userId 用户id
      * @param reqVO 请求 vo
      */
-    PageResult<AppFavoriteRespVO> pageCollectList(@Valid AppFavoritePageReqVO reqVO);
+    PageResult<AppFavoriteRespVO> page(Long userId, @Valid AppFavoritePageReqVO reqVO);
+
+    /**
+     * 检查是否收藏过商品
+     * @param userId 用户id
+     * @param reqVO 请求 vo
+     * @return true: 已收藏  false: 未收藏
+     */
+    Boolean checkFavorite(Long userId, @Valid AppFavoriteReqVO reqVO);
 }

+ 48 - 24
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java

@@ -1,23 +1,29 @@
 package cn.iocoder.yudao.module.product.service.favorite;
 
+import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO;
 import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
 import cn.iocoder.yudao.module.product.dal.mysql.favorite.ProductFavoriteMapper;
 import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO;
+import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTION_EXISTS;
-import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTION_NOT_EXISTS;
+import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_FAVORITE_EXISTS;
+import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_FAVORITE_NOT_EXISTS;
 
 /**
  * 商品收藏 Service 实现类
@@ -27,43 +33,61 @@ import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.COLLECTIO
 @Service
 @Validated
 public class ProductFavoriteServiceImpl implements ProductFavoriteService {
-
+    @Resource
+    private ProductSpuService productSpuService;
     @Resource
     private ProductFavoriteMapper mapper;
 
     @Override
-    public Boolean collect(@Valid AppFavoriteReqVO reqVO) {
-        // TODO @jason:userId 要从 Controller 传递过来,Service 不能有转台
-        Long userId = getLoginUserId();
-       // TODO @jason:代码缩进不对;
+    public Boolean create(Long userId, @Valid AppFavoriteReqVO reqVO) {
+        Assert.notNull(userId, "the userId must not be null");
         ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType());
         if (Objects.nonNull(favoriteDO)) {
-            throw exception(COLLECTION_EXISTS);
+            throw exception(PRODUCT_FAVORITE_EXISTS);
         }
-
-        // TODO @jason:插入只有成功,不用判断 1
         ProductFavoriteDO entity = ProductFavoriteConvert.INSTANCE.convert(userId, reqVO);
-        int count = mapper.insert(entity);
-        return count == 1;
+        mapper.insert(entity);
+        return Boolean.TRUE;
     }
 
     @Override
-    public Boolean cancelCollect(@Valid AppFavoriteReqVO reqVO) {
-        // TODO @jason:代码缩进不对;
-        Long loginUserId = getLoginUserId();
-        ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(loginUserId, reqVO.getSpuId(), reqVO.getType());
+    public Boolean delete(Long userId, @Valid AppFavoriteReqVO reqVO) {
+        Assert.notNull(userId, "the userId must not be null ");
+        ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType());
         if (Objects.isNull(favoriteDO)) {
-            throw exception(COLLECTION_NOT_EXISTS);
+            throw exception(PRODUCT_FAVORITE_NOT_EXISTS);
         }
-        // TODO @jason:插入只有成功,不用判断 1
-        int count = mapper.deleteById(favoriteDO.getId());
-        return count == 1;
+        mapper.deleteById(favoriteDO.getId());
+        return Boolean.TRUE;
     }
 
     @Override
-    public PageResult<AppFavoriteRespVO> pageCollectList(@Valid AppFavoritePageReqVO reqVO) {
-        Long userId = getLoginUserId();
-        return mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO);
+    public PageResult<AppFavoriteRespVO> page(Long userId, @Valid AppFavoritePageReqVO reqVO) {
+        Assert.notNull(userId, "the userId must not be null ");
+        PageResult<ProductFavoriteDO> favorites = mapper.selectPageByUserAndType(userId, reqVO.getType(), reqVO);
+        if (favorites.getTotal() > 0) {
+            PageResult<AppFavoriteRespVO> pageResult = new PageResult<>(favorites.getTotal());
+            List<ProductFavoriteDO> list = favorites.getList();
+            //得到商品spu 信息
+            List<Long> spuIds = CollectionUtils.convertList(list, ProductFavoriteDO::getSpuId);
+            Map<Long, ProductSpuDO> spuMap = CollectionUtils.convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId, val -> val);
+            List<AppFavoriteRespVO> resultList = new ArrayList<>(list.size());
+            for (ProductFavoriteDO item : list) {
+                ProductSpuDO spuDO = spuMap.get(item.getSpuId());
+                resultList.add(ProductFavoriteConvert.INSTANCE.convert(spuDO, item));
+            }
+            pageResult.setList(resultList);
+            return pageResult;
+        }else {
+            return PageResult.empty();
+        }
+    }
+
+    @Override
+    public Boolean checkFavorite(Long userId, @Valid AppFavoriteReqVO reqVO) {
+        Assert.notNull(userId, "the userId must not be null ");
+        ProductFavoriteDO favoriteDO = mapper.selectByUserAndSpuAndType(userId, reqVO.getSpuId(), reqVO.getType());
+        return Objects.nonNull(favoriteDO);
     }
 
 }

+ 0 - 22
yudao-module-mall/yudao-module-product-biz/src/main/resources/mapper/favorite/ProductFavoriteMapper.xml

@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="cn.iocoder.yudao.module.product.dal.mysql.favorite.ProductFavoriteMapper">
-
-    <!--
-        一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
-        无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
-        代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
-        文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
-     -->
-
-    <select id="selectFavoriteProductList"
-            resultType="cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO">
-        SELECT f.id, f.type, f.spu_id as spuId , p.name as spuName, p.pic_url as picUrl , p.price
-        FROM product_favorite f
-        INNER JOIN product_spu p ON f.spu_id = p.id and f.deleted = 0
-        where f.type = #{type} and f.user_id = #{userId}
-        ORDER BY f.id DESC
-
-    </select>
-
-</mapper>