【尚庭公寓SpringBoot + Vue 项目实战】移动端浏览历史(二十二)

【尚庭公寓SpringBoot + Vue 项目实战】移动端浏览历史(二十二)


文章目录

1、业务介绍

浏览历史指的是浏览房间详情的历史,关于浏览历史,有两项工作需要完成,一是提供一个查询浏览历史列表的接口,二是在浏览完房间详情后,增加保存浏览历史的逻辑

2.接口开发
2.1.分页查询浏览历史列表

查看接口

代码开发

首先在BrowsingHistoryController中注入BrowsingHistoryService,如下

java 复制代码
@RestController
@Tag(name = "浏览历史管理")
@RequestMapping("/app/history")
public class BrowsingHistoryController {

    @Autowired
    private BrowsingHistoryService service;
}
  • 查看请求和响应的数据结构

    • 请求的数据结构

      currentsize为分页相关参数,分别表示当前所处页面每个页面的记录数

    • 响应的数据结构

      查看web-admin模块 下的com.atguigu.lease.web.app.vo.history.HistoryItemVo,如下

      java 复制代码
      @Data
      @Schema(description = "浏览历史基本信息")
      public class HistoryItemVo extends BrowsingHistory {
      
          @Schema(description = "房间号")
          private String roomNumber;
      
          @Schema(description = "租金")
          private BigDecimal rent;
      
          @Schema(description = "房间图片列表")
          private List<GraphVo> roomGraphVoList;
      
          @Schema(description = "公寓名称")
          private String apartmentName;
      
          @Schema(description = "省份名称")
          private String provinceName;
      
          @Schema(description = "城市名称")
          private String cityName;
      
          @Schema(description = "区县名称")
          private String districtName;
      }
  • 编写Controller层逻辑

    BrowsingHistoryController中增加如下内容

    java 复制代码
    @Operation(summary = "获取浏览历史")
    @GetMapping("pageItem")
    private Result<IPage<HistoryItemVo>> page(@RequestParam long current, @RequestParam long size) {
        Page<HistoryItemVo> page = new Page<>(current, size);
        IPage<HistoryItemVo> result = service.pageHistoryItemByUserId(page, LoginUserHolder.getLoginUser().getUserId());
        return Result.ok(result);
    }
  • 编写Service层逻辑

    • BrowsingHistoryService中增加如下逻辑

      java 复制代码
      IPage<HistoryItemVo> pageHistoryItemByUserId(Page<HistoryItemVo> page, Long userId);
    • BrowsingHistoryServiceImpl中增加如下逻辑

      java 复制代码
      @Override
      public IPage<HistoryItemVo> pageHistoryItemByUserId(Page<HistoryItemVo> page, Long userId) {
          return browsingHistoryMapper.pageHistoryItemByUserId(page, userId);
      }
  • 编写Mapper层逻辑

    • BrowsingHistoryMapper中增加如下逻辑

      java 复制代码
      IPage<HistoryItemVo> pageHistoryItemByUserId(Page<HistoryItemVo> page, Long userId);
    • BrowsingHistoryMapper.xml中增加如下逻辑

      xml 复制代码
      <resultMap id="HistoryItemVoMap" type="com.atguigu.lease.web.app.vo.history.HistoryItemVo" autoMapping="true">
          <id property="id" column="id"/>
          <result property="roomId" column="room_id"/>
          <collection property="roomGraphVoList" ofType="com.atguigu.lease.web.app.vo.graph.GraphVo"
                      select="selectGraphVoByRoomId" column="room_id"/>
      </resultMap>
      
      <select id="pageHistoryItemByUserId" resultMap="HistoryItemVoMap">
          select bh.id,
                 bh.user_id,
                 bh.room_id,
                 bh.browse_time,
                 ri.room_number,
                 ri.rent,
                 ai.name apartment_name,
                 ai.district_name,
                 ai.city_name,
                 ai.province_name
          from browsing_history bh
                   left join room_info ri on bh.room_id = ri.id and ri.is_deleted=0
                   left join apartment_info ai on ri.apartment_id = ai.id and ai.is_deleted=0
          where bh.is_deleted = 0
            and bh.user_id = #{userId}
          order by browse_time desc
      </select>
      
      <select id="selectGraphVoByRoomId" resultType="com.atguigu.lease.web.app.vo.graph.GraphVo">
          select url,
                 name
          from graph_info
          where is_deleted = 0
            and item_type = 2
            and item_id = #{room_id}
      </select>
2.2.保存浏览历史
  • 触发保存浏览历史

    保存浏览历史的动作应该在浏览房间详情时触发,所以在RoomInfoServiceImpl中的getDetailById方法的最后增加如下内容

    java 复制代码
    browsingHistoryService.saveHistory(LoginUserContext.getLoginUser().getUserId(), id);
  • 编写Service层逻辑

    • BrowsingHistoryService中增加如下内容

      java 复制代码
      void saveHistory(Long userId, Long roomId);
    • BrowsingHistoryServiceImpl中增加如下内容

      java 复制代码
      @Override
      public void saveHistory(Long userId, Long roomId) {
      
          LambdaQueryWrapper<BrowsingHistory> queryWrapper = new LambdaQueryWrapper<>();
          queryWrapper.eq(BrowsingHistory::getUserId, userId);
          queryWrapper.eq(BrowsingHistory::getRoomId, roomId);
          BrowsingHistory browsingHistory = browsingHistoryMapper.selectOne(queryWrapper);
      
          if (browsingHistory != null) {
              browsingHistory.setBrowseTime(new Date());
              browsingHistoryMapper.updateById(browsingHistory);
          } else {
              BrowsingHistory newBrowsingHistory = new BrowsingHistory();
              newBrowsingHistory.setUserId(userId);
              newBrowsingHistory.setRoomId(roomId);
              newBrowsingHistory.setBrowseTime(new Date());
              browsingHistoryMapper.insert(newBrowsingHistory);
          }
      }

      知识点

      保存浏览历史的动作不应影响前端获取房间详情信息,故此处采取异步操作。Spring Boot提供了@Async注解来完成异步操作,具体使用方式为:

      • 启用Spring Boot异步操作支持

        在 Spring Boot 主应用程序类上添加 @EnableAsync 注解,如下

        java 复制代码
        @SpringBootApplication
        @EnableAsync
        public class AppWebApplication {
            public static void main(String[] args) {
                SpringApplication.run(AppWebApplication.class);
            }
        }
      • 在要进行异步处理的方法上添加 @Async 注解,如下

        java 复制代码
        @Override
        @Async
        public void saveHistory(Long userId, Long roomId) {
        
            LambdaQueryWrapper<BrowsingHistory> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BrowsingHistory::getUserId, userId);
            queryWrapper.eq(BrowsingHistory::getRoomId, roomId);
            BrowsingHistory browsingHistory = browsingHistoryMapper.selectOne(queryWrapper);
        
            if (browsingHistory != null) {
                browsingHistory.setBrowseTime(new Date());
                browsingHistoryMapper.updateById(browsingHistory);
            } else {
                BrowsingHistory newBrowsingHistory = new BrowsingHistory();
                newBrowsingHistory.setUserId(userId);
                newBrowsingHistory.setRoomId(roomId);
                newBrowsingHistory.setBrowseTime(new Date());
                browsingHistoryMapper.insert(newBrowsingHistory);
            }
        }
相关推荐
gnip1 小时前
企业级配置式表单组件封装
前端·javascript·vue.js
一只叫煤球的猫2 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
excel3 小时前
Three.js 材质(Material)详解 —— 区别、原理、场景与示例
前端
掘金安东尼3 小时前
抛弃自定义模态框:原生Dialog的实力
前端·javascript·github
hj5914_前端新手7 小时前
javascript基础- 函数中 this 指向、call、apply、bind
前端·javascript
薛定谔的算法7 小时前
低代码编辑器项目设计与实现:以JSON为核心的数据驱动架构
前端·react.js·前端框架
Hilaku7 小时前
都2025年了,我们还有必要为了兼容性,去写那么多polyfill吗?
前端·javascript·css
yangcode7 小时前
iOS 苹果内购 Storekit 2
前端
LuckySusu7 小时前
【js篇】JavaScript 原型修改 vs 重写:深入理解 constructor的指向问题
前端·javascript
LuckySusu7 小时前
【js篇】如何准确获取对象自身的属性?hasOwnProperty深度解析
前端·javascript