SSM - Springboot - MyBatis-Plus 全栈体系(三十五)

第八章 项目实战

四、后台功能开发

2. 首页模块开发

2.1 查询首页分类
2.1.1 需求描述

在这里插入图片描述

  • 进入新闻首页,查询所有分类并动态展示新闻类别栏位
2.1.2 接口描述
  • url 地址:portal/findAllTypes

  • 请求方式:get

  • 请求参数:无

  • 响应数据:

    • 成功
    {
       "code":"200",
       "message":"OK"
       "data":{
                [
                    {
                        "tid":"1",
                        "tname":"新闻"
                    },
                    {
                        "tid":"2",
                        "tname":"体育"
                    },
                    {
                        "tid":"3",
                        "tname":"娱乐"
                    },
                    {
                        "tid":"4",
                        "tname":"科技"
                    },
                    {
                        "tid":"5",
                        "tname":"其他"
                    }
                ]
        }
    }
    
2.1.3 代码实现
  • controller
@RestController
@RequestMapping("portal")
@CrossOrigin
public class PortalController {

    @Autowired
    private TypeService typeService;

    /**
     * 查询全部类别信息
     * @return
     */
    @GetMapping("findAllTypes")
    public Result findAllTypes(){
        //直接调用业务层,查询全部数据
        List<Type> list = typeService.list();
        return Result.ok(list);
    }
}
2.2 分类查询首页头条信息
2.2.1 需求描述

在这里插入图片描述

  • 客户端向服务端发送查询关键字,新闻类别,页码数,页大小
  • 服务端根据条件搜索分页信息,返回含页码数,页大小,总页数,总记录数,当前页数据等信息,并根据时间降序,浏览量降序排序
2.2.2 接口描述
  • url 地址:portal/findNewsPage
  • 请求方式:post
  • 请求参数:
{
    "keyWords":"马斯克", // 搜索标题关键字
    "type":0,           // 新闻类型
    "pageNum":1,        // 页码数
    "pageSize":10     // 页大小
}
  • 响应数据:

    • 成功
    {
       "code":"200",
       "message":"success"
       "data":{
          "pageInfo":{
            "pageData":[
              {
                "hid":"1",                     // 新闻id
                "title":"小帽课堂宣布 ... ...",   // 新闻标题
                "type":"1",                    // 新闻所属类别编号
                "pageViews":"40",              // 新闻浏览量
                "pastHours":"3" ,              // 发布时间已过小时数
                "publisher":"1"                // 发布用户ID
            },
            {
                "hid":"1",                     // 新闻id
                "title":"小帽课堂宣布 ... ...",   // 新闻标题
                "type":"1",                    // 新闻所属类别编号
                "pageViews":"40",              // 新闻浏览量
                "pastHours":"3",              // 发布时间已过小时数
                "publisher":"1"                // 发布用户ID
            },
            {
                "hid":"1",                     // 新闻id
                "title":"小帽课堂宣布 ... ...",   // 新闻标题
                "type":"1",                    // 新闻所属类别编号
                "pageViews":"40",              // 新闻浏览量
                "pastHours":"3",               // 发布时间已过小时数
                "publisher":"1"                // 发布用户ID
            }
            ],
          "pageNum":1,    //页码数
          "pageSize":10,  // 页大小
          "totalPage":20, // 总页数
          "totalSize":200 // 总记录数
        }
      }
    }
    
2.2.3 代码实现
2.2.3.1 准备条件实体类
@Data
public class PortalVo {

    private String keyWords;
    private Integer type;
    private Integer pageNum = 1;
    private Integer pageSize = 10;
}
2.2.3.2 controller
/**
 * 首页分页查询
 * @return
 */
@PostMapping("findNewPage")
public Result findNewPage(@RequestBody PortalVo portalVo){
    Result result = headlineService.findNewPage(portalVo);
    return result;
}
2.2.3.3 service
@Service
public class HeadlineServiceImpl extends ServiceImpl<HeadlineMapper, Headline>
    implements HeadlineService{

    @Autowired
    private HeadlineMapper headlineMapper;

    /**
     * 首页数据查询
     * @param portalVo
     * @return
     */
    @Override
    public Result findNewPage(PortalVo portalVo) {

        //1.条件拼接 需要非空判断
        LambdaQueryWrapper<Headline> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(portalVo.getKeyWords()),Headline::getTitle,portalVo.getKeyWords())
                .eq(portalVo.getType()!= null,Headline::getType,portalVo.getType());

        //2.分页参数
        IPage<Headline> page = new Page<>(portalVo.getPageNum(),portalVo.getPageSize());

        //3.分页查询
        //查询的结果 "pastHours":"3"   // 发布时间已过小时数 我们查询返回一个map
        //自定义方法
        headlineMapper.selectPageMap(page, portalVo);

        //4.结果封装
        //分页数据封装
        Map<String,Object> pageInfo =new HashMap<>();
        pageInfo.put("pageData",page.getRecords());
        pageInfo.put("pageNum",page.getCurrent());
        pageInfo.put("pageSize",page.getSize());
        pageInfo.put("totalPage",page.getPages());
        pageInfo.put("totalSize",page.getTotal());

        Map<String,Object> pageInfoMap=new HashMap<>();
        pageInfoMap.put("pageInfo",pageInfo);
        // 响应JSON
        return Result.ok(pageInfoMap);
    }
}
2.2.3.4 mapper
  • 接口
public interface HeadlineMapper extends BaseMapper<Headline> {

    //自定义分页查询方法
    IPage<Map> selectPageMap(IPage<Headline> page,
                @Param("portalVo") PortalVo portalVo);
}
  • mapperxml:
<select id="selectPageMap" resultType="map">
    select hid,title,type,page_views pageViews,TIMESTAMPDIFF(HOUR,create_time,NOW()) pastHours,
            publisher from news_headline where is_deleted=0
            <if test="portalVo.keyWords !=null and portalVo.keyWords.length()>0 ">
                and title like concat('%',#{portalVo.keyWords},'%')
            </if>
            <if test="portalVo.type != null and portalVo.type != 0">
                and type = #{portalVo.type}
            </if>
</select>
2.3 查询头条详情
2.3.1 需求描述

在这里插入图片描述

  • 用户点击"查看全文"时,向服务端发送新闻 id
  • 后端根据新闻 id 查询完整新闻文章信息并返回
  • 后端要同时让新闻的浏览量+1
2.3.2 接口描述
  • url 地址:portal/showHeadlineDetail
  • 请求方式:post
  • 请求参数:
hid=1 param形成参数
  • 响应数据:

    • 成功
    {
        "code":"200",
        "message":"success",
        "data":{
            "headline":{
                "hid":"1",                     // 新闻id
                "title":"马斯克宣布 ... ...",   // 新闻标题
                "article":"... ..."            // 新闻正文
                "type":"1",                    // 新闻所属类别编号
                "typeName":"科技",             // 新闻所属类别
                "pageViews":"40",              // 新闻浏览量
                "pastHours":"3" ,              // 发布时间已过小时数
                "publisher":"1" ,              // 发布用户ID
                "author":"张三"                 // 新闻作者
            }
        }
    }
    
2.3.3 代码实现
2.3.3.1 controller
 /**
 * 首页详情接口
 * @param hid
 * @return
 */
@PostMapping("showHeadlineDetail")
public Result showHeadlineDetail(Integer hid){
    Result result = headlineService.showHeadlineDetail(hid);
    return result;
}
2.3.3.2 service
/**
 * 详情数据查询
 * "headline":{
 * "hid":"1",                     // 新闻id
 * "title":"马斯克宣布 ... ...",   // 新闻标题
 * "article":"... ..."            // 新闻正文
 * "type":"1",                    // 新闻所属类别编号
 * "typeName":"科技",             // 新闻所属类别
 * "pageViews":"40",              // 新闻浏览量
 * "pastHours":"3" ,              // 发布时间已过小时数
 * "publisher":"1" ,              // 发布用户ID
 * "author":"张三"                 // 新闻作者
 * }
 * 注意: 是多表查询 , 需要更新浏览量+1
 *
 * @param hid
 * @return
 */
@Override
public Result showHeadlineDetail(Integer hid) {

    //1.实现根据id的查询(多表)
    Map headLineDetail = headlineMapper.selectDetailMap(hid);
    //2.拼接头条对象(阅读量和version)进行数据更新
    Headline headline = new Headline();
    headline.setHid(hid);
    headline.setPageViews((Integer) headLineDetail.get("pageViews")+1); //阅读量+1
    headline.setVersion((Integer) headLineDetail.get("version")); //设置版本
    headlineMapper.updateById(headline);

    Map<String,Object> pageInfoMap=new HashMap<>();
    pageInfoMap.put("headline",headLineDetail);
    return Result.ok(pageInfoMap);
}
2.3.3.3 mapper
  • 接口:
/**
 * 分页查询头条详情
 * @param hid
 * @return
 */
Map selectDetailMap(Integer hid);
  • mapperxml:
<!--    Map selectDetailMap(Integer hid);-->
<select id="selectDetailMap" resultType="map">
    select hid,title,article,type, h.version ,tname typeName ,page_views pageViews
            ,TIMESTAMPDIFF(HOUR,create_time,NOW()) pastHours,publisher
                    ,nick_name author from news_headline h
                        left join news_type t on h.type = t.tid
                                left join news_user u  on h.publisher = u.uid
                                            where hid = #{hid}
</select>