当前位置: 首页 > news >正文

[尚庭公寓]15-个人中心

浏览历史

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

1. 分页查询浏览历史列表

package com.atguigu.lease.web.app.controller.history;@RestController
@Tag(name = "浏览历史管理")
@RequestMapping("/app/history")
public class BrowsingHistoryController {@Autowiredprivate BrowsingHistoryService browsingHistoryService;@Operation(summary = "获取浏览历史")@GetMapping("pageItem")private Result<IPage<HistoryItemVo>> page(@RequestParam long current, @RequestParam long size) {IPage<HistoryItemVo> page = new Page<>(current, size);Long userId = LoginUserHolder.getLoginUser().getUserId();IPage<HistoryItemVo> res = browsingHistoryService.pageHistoryItemByUserId(page, userId)return Result.ok(res);}
}
package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【browsing_history(浏览历史)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
public class BrowsingHistoryServiceImpl extends ServiceImpl<BrowsingHistoryMapper, BrowsingHistory>implements BrowsingHistoryService {@AutowiredBrowsingHistoryMapper browsingHistoryMapper;@Overridepublic IPage<HistoryItemVo> pageHistoryItemByUserId(IPage<HistoryItemVo> page, Long userId) {return browsingHistoryMapper.pageHistoryItemByUserId(page, userId);}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.lease.web.app.mapper.BrowsingHistoryMapper"><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="selectGraphListById" column="room_id"/></resultMap><select id="pageHistoryItemByUserId" resultMap="HistoryItemVoMap">select bh.id,bh.room_id,bh.user_id,bh.browse_time,ri.room_number,ri.rent,ai.name as apartment_name,ai.province_name,ai.city_name,ai.district_namefrom browsing_history bhleft join room_info ri on bh.room_id = ri.id and ri.is_deleted = 0left join apartment_info ai on ri.apartment_id = ai.id and ai.is_deleted = 0where bh.user_id = #{userId}and bh.is_deleted = 0order by bh.browse_time desc</select><select id="selectGraphListById" resultType="com.atguigu.lease.web.app.vo.graph.GraphVo">select name,urlfrom graph_infowhere item_type = 2and item_id = #{roomId}and is_deleted = 0</select>
</mapper>

2. 保存浏览历史

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

package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【room_info(房间信息表)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
@Slf4j
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>implements RoomInfoService {@Autowiredprivate BrowsingHistoryService browsingHistoryService;@Overridepublic RoomDetailVo getDetailById(Long id) {... ...// 保存浏览记录browsingHistoryService.saveHistory(LoginUserHolder.getLoginUser().getUserId(), id);return roomDetailVo;}}

 在`BrowsingHistoryService`中增加如下内容

package com.atguigu.lease.web.app.service;/**
* @author liubo
* @description 针对表【browsing_history(浏览历史)】的数据库操作Service
* @createDate 2023-07-26 11:12:39
*/
public interface BrowsingHistoryService extends IService<BrowsingHistory> {IPage<HistoryItemVo> pageHistoryItemByUserId(IPage<HistoryItemVo> page, Long userId);void saveHistory(Long userId, Long roomId);
}
package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【browsing_history(浏览历史)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
public class BrowsingHistoryServiceImpl extends ServiceImpl<BrowsingHistoryMapper, BrowsingHistory>implements BrowsingHistoryService {@AutowiredBrowsingHistoryMapper browsingHistoryMapper;@Overridepublic void saveHistory(Long userId, Long roomId) {LambdaQueryWrapper<BrowsingHistory> wrapper = new LambdaQueryWrapper<>();wrapper.eq(BrowsingHistory::getUserId, userId);wrapper.eq(BrowsingHistory::getRoomId, roomId);BrowsingHistory browsingHistory = browsingHistoryMapper.selectOne(wrapper);if (browsingHistory == null) {BrowsingHistory history = new BrowsingHistory();history.setUserId(userId);history.setRoomId(roomId);history.setBrowseTime(new Date());browsingHistoryMapper.insert(history);} else {browsingHistory.setBrowseTime(new Date());browsingHistoryMapper.updateById(browsingHistory);}}
}

知识点

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

  1.  启用Spring Boot异步操作支持

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

      @SpringBootApplication@EnableAsyncpublic class AppWebApplication {public static void main(String[] args) {SpringApplication.run(AppWebApplication.class);}}
  1. 在要进行异步处理的方法上添加 `@Async` 注解,如下
      @Override@Asyncpublic void saveHistory(Long userId, Long roomId) {... ...}

预约看房

保存或更新看房预约

package com.atguigu.lease.web.app.controller.appointment;@Tag(name = "看房预约信息")
@RestController
@RequestMapping("/app/appointment")
public class ViewAppointmentController {@AutowiredViewAppointmentService viewAppointmentService;@Operation(summary = "保存或更新看房预约")@PostMapping("/saveOrUpdate")public Result saveOrUpdate(@RequestBody ViewAppointment viewAppointment) {viewAppointment.setUserId(LoginUserHolder.getLoginUser().getUserId());viewAppointmentService.saveOrUpdate(viewAppointment);return Result.ok();}}

查询个人预约看房列表

package com.atguigu.lease.web.app.controller.appointment;@Tag(name = "看房预约信息")
@RestController
@RequestMapping("/app/appointment")
public class ViewAppointmentController {@AutowiredViewAppointmentService viewAppointmentService;@Operation(summary = "查询个人预约看房列表")@GetMapping("listItem")public Result<List<AppointmentItemVo>> listItem() {List<AppointmentItemVo> list = viewAppointmentService.listItemByUserId(LoginUserHolder.getLoginUser().getUserId());return Result.ok(list);}}
package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【view_appointment(预约看房信息表)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
public class ViewAppointmentServiceImpl extends ServiceImpl<ViewAppointmentMapper, ViewAppointment>implements ViewAppointmentService {@Autowiredprivate ViewAppointmentMapper viewAppointmentMapper;@Overridepublic List<AppointmentItemVo> listItemByUserId(Long userId) {return viewAppointmentMapper.listItemByUserId(userId);}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.lease.web.app.mapper.ViewAppointmentMapper"><resultMap id="AppointmentItemVoMap" type="com.atguigu.lease.web.app.vo.appointment.AppointmentItemVo"autoMapping="true"><collection property="graphVoList" ofType="com.atguigu.lease.web.app.vo.graph.GraphVo" autoMapping="true"></collection></resultMap><select id="listItemByUserId" resultMap="AppointmentItemVoMap">select va.id,va.apartment_id,va.appointment_time,va.appointment_status,ai.name as apartment_name,gi.name,gi.urlfrom view_appointment valeft join apartment_info ai on ai.id = va.apartment_id and ai.is_deleted = 0left join graph_info gi on gi.item_id = ai.id and gi.item_type = 1 and gi.is_deleted = 0where va.user_id = #{userId}and va.is_deleted = 0order by va.appointment_time desc</select>
</mapper>

根据ID查询预约详情信息

package com.atguigu.lease.web.app.controller.appointment;@Tag(name = "看房预约信息")
@RestController
@RequestMapping("/app/appointment")
public class ViewAppointmentController {@AutowiredViewAppointmentService viewAppointmentService;@GetMapping("getDetailById")@Operation(summary = "根据ID查询预约详情信息")public Result<AppointmentDetailVo> getDetailById(Long id) {AppointmentDetailVo appointmentDetailVo = viewAppointmentService.getDetailById(id);return Result.ok(appointmentDetailVo);}}
package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【view_appointment(预约看房信息表)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
public class ViewAppointmentServiceImpl extends ServiceImpl<ViewAppointmentMapper, ViewAppointment>implements ViewAppointmentService {@Autowiredprivate ViewAppointmentMapper viewAppointmentMapper;@Autowiredprivate ApartmentInfoServiceImpl apartmentInfoService;@Overridepublic AppointmentDetailVo getDetailById(Long id) {// 预约看房基础信息ViewAppointment viewAppointment = viewAppointmentMapper.selectById(id);// 房间详情ApartmentItemVo apartmentItemVo = apartmentInfoService.selectApartmentItemVoById(viewAppointment.getApartmentId());AppointmentDetailVo appointmentDetailVo = new AppointmentDetailVo();BeanUtils.copyProperties(viewAppointment, appointmentDetailVo);appointmentDetailVo.setApartmentItemVo(apartmentItemVo);return appointmentDetailVo;}
}

租约管理

获取个人租约基本信息列表

查看响应的数据结构

查看**web-appp模块**下的`com.atguigu.lease.web.app.vo.agreement.AgreementItemVo`,内容如下

@Data@Schema(description = "租约基本信息")public class AgreementItemVo {@Schema(description = "租约id")private Long id;@Schema(description = "房间图片列表")private List<GraphVo> roomGraphVoList;@Schema(description = "公寓名称")private String apartmentName;@Schema(description = "房间号")private String roomNumber;@Schema(description = "租约状态")private LeaseStatus leaseStatus;@Schema(description = "租约开始日期")@JsonFormat(pattern = "yyyy-MM-dd")private Date leaseStartDate;@Schema(description = "租约结束日期")@JsonFormat(pattern = "yyyy-MM-dd")private Date leaseEndDate;@Schema(description = "租约来源")private LeaseSourceType sourceType;@Schema(description = "租金")private BigDecimal rent;}

编写Controller层逻辑

 在`LeaseAgreementController`中增加如下内容

package com.atguigu.lease.web.app.controller.agreement;@RestController
@RequestMapping("/app/agreement")
@Tag(name = "租约信息")
public class LeaseAgreementController {@Autowiredprivate LeaseAgreementService leaseAgreementService;@Operation(summary = "获取个人租约基本信息列表")@GetMapping("listItem")public Result<List<AgreementItemVo>> listItem() {List<AgreementItemVo> result = leaseAgreementService.listItemByPhone(LoginUserHolder.getLoginUser().getUsername());return Result.ok(result);}}
package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【lease_agreement(租约信息表)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
public class LeaseAgreementServiceImpl extends ServiceImpl<LeaseAgreementMapper, LeaseAgreement>implements LeaseAgreementService {@Autowiredprivate LeaseAgreementMapper leaseAgreementMapper;@Overridepublic List<AgreementItemVo> listItemByPhone(String phone) {return leaseAgreementMapper.listItemByPhone(phone);}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.lease.web.app.mapper.LeaseAgreementMapper"><resultMap id="AgreementItemVoMap" type="com.atguigu.lease.web.app.vo.agreement.AgreementItemVo"><collection property="roomGraphVoList" ofType="com.atguigu.lease.web.app.vo.graph.GraphVo" autoMapping="true"></collection></resultMap><select id="listItemByPhone" resultMap="AgreementItemVoMap">select la.id,la.status,la.lease_start_date,la.lease_end_date,la.source_type,la.rent,ri.room_number,ri.id   as room_id,ai.name as apartment_name,gi.name,gi.urlfrom lease_agreement laleft join room_info ri on la.room_id = ri.id and ri.is_deleted = 0left join apartment_info ai on room_id = ai.id and ai.is_deleted = 0left join graph_info gi on room_id = gi.item_id ans gi.item_type = 2 and gi.is_deleted = 0where la.phone = #{phone}and la.is_deleted = 0</select>
</mapper>

根据ID获取租约详细信息

查看响应的数据结构

查看**web-app模块**下的`com.atguigu.lease.web.app.vo.agreement.AgreementDetailVo`,内容如下

@Data@Schema(description = "租约详细信息")public class AgreementDetailVo extends LeaseAgreement {@Schema(description = "租约id")private Long id;@Schema(description = "公寓名称")private String apartmentName;@Schema(description = "公寓图片列表")private List<GraphVo> apartmentGraphVoList;@Schema(description = "房间号")private String roomNumber;@Schema(description = "房间图片列表")private List<GraphVo> roomGraphVoList;@Schema(description = "支付方式")private String paymentTypeName;@Schema(description = "租期月数")private Integer leaseTermMonthCount;@Schema(description = "租期单位")private String leaseTermUnit;}

编写Controller层逻辑

package com.atguigu.lease.web.app.controller.agreement;@RestController
@RequestMapping("/app/agreement")
@Tag(name = "租约信息")
public class LeaseAgreementController {@Autowiredprivate LeaseAgreementService leaseAgreementService;@Operation(summary = "根据id获取租约详细信息")@GetMapping("getDetailById")public Result<AgreementDetailVo> getDetailById(@RequestParam Long id) {AgreementDetailVo agreementDetailVo = leaseAgreementService.getDetailById(id);return Result.ok(agreementDetailVo);}}
package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【lease_agreement(租约信息表)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
public class LeaseAgreementServiceImpl extends ServiceImpl<LeaseAgreementMapper, LeaseAgreement> implements LeaseAgreementService {@Autowiredprivate LeaseAgreementMapper leaseAgreementMapper;@Autowiredprivate ApartmentInfoMapper apartmentInfoMapper;@Autowiredprivate RoomInfoMapper roomInfoMapper;@Autowiredprivate GraphInfoMapper graphInfoMapper;@Autowiredprivate PaymentTypeMapper paymentTypeMapper;@Autowiredprivate LeaseTermMapper leaseTermMapper;@Overridepublic AgreementDetailVo getDetailById(Long id) {LeaseAgreement leaseAgreement = leaseAgreementMapper.selectById(id);if (leaseAgreement == null) {return null;}// 查询公寓信息ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(leaseAgreement.getApartmentId());// 查询房间信息RoomInfo roomInfo = roomInfoMapper.selectById(leaseAgreement.getRoomId());// 查询图片信息List<GraphVo> roomGraphVoList = graphInfoMapper.selectListByItemTypeAndId(ItemType.ROOM, leaseAgreement.getRoomId());List<GraphVo> apartmentGraphVoList = graphInfoMapper.selectListByItemTypeAndId(ItemType.APARTMENT, leaseAgreement.getApartmentId());// 支付方式PaymentType paymentType = paymentTypeMapper.selectById(leaseAgreement.getPaymentTypeId());// 租期LeaseTerm leaseTerm = leaseTermMapper.selectById(leaseAgreement.getLeaseTermId());AgreementDetailVo agreementDetailVo = new AgreementDetailVo();BeanUtils.copyProperties(leaseAgreement, agreementDetailVo);agreementDetailVo.setApartmentGraphVoList(apartmentGraphVoList);agreementDetailVo.setRoomGraphVoList(roomGraphVoList);agreementDetailVo.setApartmentName(apartmentInfo.getName());agreementDetailVo.setRoomNumber(roomInfo.getRoomNumber());agreementDetailVo.setPaymentTypeName(paymentType.getName());agreementDetailVo.setLeaseTermMonthCount(leaseTerm.getMonthCount());return agreementDetailVo;}
}

根据ID更新租约状态

package com.atguigu.lease.web.app.controller.agreement;@RestController
@RequestMapping("/app/agreement")
@Tag(name = "租约信息")
public class LeaseAgreementController {@Autowiredprivate LeaseAgreementService leaseAgreementService;@Operation(summary = "根据id更新租约状态", description = "用于确认租约和提前退租")@PostMapping("updateStatusById")public Result updateStatusById(@RequestParam Long id, @RequestParam LeaseStatus leaseStatus) {LambdaUpdateWrapper<LeaseAgreement> warp = new LambdaUpdateWrapper<LeaseAgreement>().eq(LeaseAgreement::getId, id).set(LeaseAgreement::getStatus, leaseStatus);leaseAgreementService.update(warp);return Result.ok();}}

保存或更新租约

package com.atguigu.lease.web.app.controller.agreement;@RestController
@RequestMapping("/app/agreement")
@Tag(name = "租约信息")
public class LeaseAgreementController {@Autowiredprivate LeaseAgreementService leaseAgreementService;@Operation(summary = "保存或更新租约", description = "用于续约")@PostMapping("saveOrUpdate")public Result saveOrUpdate(@RequestBody LeaseAgreement leaseAgreement) {leaseAgreementService.saveOrUpdate(leaseAgreement);return Result.ok();}}

根据房间ID获取可选支付方式

package com.atguigu.lease.web.app.controller.payment;@Tag(name = "支付方式接口")
@RestController
@RequestMapping("/app/payment")
public class PaymentTypeController {@Autowiredprivate PaymentTypeService paymentTypeService;@Operation(summary = "根据房间id获取可选支付方式列表")@GetMapping("listByRoomId")public Result<List<PaymentType>> list(@RequestParam Long id) {List<PaymentType> list = paymentTypeService.listByRoomId(id);return Result.ok(list);}}
package com.atguigu.lease.web.app.service.impl;/**
* @author liubo
* @description 针对表【payment_type(支付方式表)】的数据库操作Service实现
* @createDate 2023-07-26 11:12:39
*/
@Service
public class PaymentTypeServiceImpl extends ServiceImpl<PaymentTypeMapper, PaymentType>implements PaymentTypeService{@Autowiredprivate PaymentTypeMapper paymentTypeMapper;@Overridepublic List<PaymentType> listByRoomId(Long id) {List<PaymentType> paymentTypes = paymentTypeMapper.selectListByRoomId(id);return paymentTypes;}
}

根据房间ID获取可选租期

package com.atguigu.lease.web.app.controller.leasaterm;@RestController
@RequestMapping("/app/term/")
@Tag(name = "租期信息")
public class LeaseTermController {@Autowiredprivate LeaseTermService leaseTermService;@GetMapping("listByRoomId")@Operation(summary = "根据房间id获取可选获取租期列表")public Result<List<LeaseTerm>> list(@RequestParam Long id) {List<LeaseTerm> list = leaseTermService.listByRoomId(id);return Result.ok(list);}
}
package com.atguigu.lease.web.app.service.impl;/*** @author liubo* @description 针对表【lease_term(租期)】的数据库操作Service实现* @createDate 2023-07-26 11:12:39*/
@Service
public class LeaseTermServiceImpl extends ServiceImpl<LeaseTermMapper, LeaseTerm>implements LeaseTermService {@Autowiredprivate LeaseTermMapper leaseTermMapper;@Overridepublic List<LeaseTerm> listByRoomId(Long id) {return leaseTermMapper.selectListByRoomId(id);}
}

前后端联调

启动后端项目

启动后端项目,供前端调用接口。

启动前端项目

导入前端项目

将移动端的前端项目(**rentHouseH5**)导入`vscode`或者`WebStorm`,打开终端,在项目根目录执行以下命令,安装所需依赖

npm install

配置后端接口地址

修改项目根目录下的`.env.development`文件中的`VITE_APP_BASE_URL`变量的值为后端接口的地址,此处改为`http://localhost:8081`即可,如下

 VITE_APP_BASE_URL='http://localhost:8081'

注意:上述主机名和端口号需要根据实际情况进行修改。

启动前端项目

上述配置完成之后,便可执行以下命令启动前端项目了

npm run dev

访问前端项目

在浏览器中访问前端项目,并逐个测试每个页面的相关功能。

http://www.dtcms.com/a/303049.html

相关文章:

  • 力扣-22.括号生成
  • C++初学者4——标准数据类型
  • JavaScript对象与Math对象完全指南
  • 力扣7:整数反转
  • 利用DataStream和TrafficPeak实现大数据可观察性
  • jQuery 最新语法大全详解(2025版)
  • 下载k8s官方组件chart和容器镜像
  • JavaScript中的Promise.all方法详解
  • 坚鹏:AI智能体培训是知行学成为AI智能体创新应用引领者的基础
  • 【归并排序】排序数组(medium)
  • 阿里云【免费试用】Elasticsearch 智能运维 AI 助手
  • 应用信息更新至1.18.0
  • 加法器 以及ALU(逻辑算术单元)
  • 深入解析 Spring 获取 XML 验证模式的过程
  • redis数据库的四种取得 shell方法
  • C++模板进阶:从基础到实战的深度探索
  • python生成 requirement.txt 文件
  • 一个高效的阿里云漏洞库爬虫工具,用于自动化爬取和处理CVE数据
  • ROS2入门之开发环境搭建
  • AI-调查研究-40-多模态大模型量化 格局重塑:五大开源模型横评与技术对比
  • Navicat 17 教程:Windows 和 Mac 系统适用
  • 【运维】Smartctl安装及使用指南
  • Python爬虫实战:快速采集教育政策数据(附官网工具库API)
  • 设计模式实战:自定义SpringIOC(亲手实践)
  • 常见依赖于TCP/IP的应用层协议
  • Taro 网络请求相关 API 全面解析
  • 初识opencv05——图像预处理4
  • 【Linux系统】Ext2文件系统 | 软硬链接
  • 接口测试核心概念与实践指南
  • 分享一个脚本,从mysql导出数据csv到hdfs临时目录