• 【尚庭公寓SpringBoot + Vue 项目实战】租约管理(十四)


    【尚庭公寓SpringBoot + Vue 项目实战】租约管理(十四)


    1、业务介绍

    租约管理共有五个接口需要实现,除此之外,还需实现一个定时任务,用于检查租约是否到期以及修改到期状态。

    1. 保存或更新租约信息
    2. 根据条件分页查询租约列表
    3. 根据ID查询租约信息
    4. 根据ID删除租约信息
    5. 根据ID更新租约状态
    6. 定时检查租约状态
    2、逻辑介绍

    接口定义-后台-租约管理-租约列表

    image-20240617115436657

    3、接口开发
    3.1、保存或更新租约信息

    查看接口

    image-20240617115535417

    代码开发

    LeaseAgreementController中增加如下内容

    @Tag(name = "租约管理")
    @RestController
    @RequestMapping("/admin/agreement")
    public class LeaseAgreementController {
    
        @Autowired
        private LeaseAgreementService agreementService;
    
        @Operation(summary = "保存或修改租约信息")
        @PostMapping("saveOrUpdate")
        public Result saveOrUpdate(@RequestBody LeaseAgreement leaseAgreement) {
            agreementService.saveOrUpdate(leaseAgreement);
            return Result.ok();
        }
    
    }
    
    3.2、根据条件分页查询租约列表

    查看接口

    image-20240617121945789

    • 查看请求和响应的数据结构

      • 请求数据结构

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

        • AgreementQueryVo为公寓的查询条件,详细结构如下:

          @Data
          @Schema(description = "租约查询实体")
          public class AgreementQueryVo {
          
              @Schema(description = "公寓所处省份id")
              private Long provinceId;
          
              @Schema(description = "公寓所处城市id")
              private Long cityId;
          
              @Schema(description = "公寓所处区域id")
              private Long districtId;
          
              @Schema(description = "公寓id")
              private Long apartmentId;
          
              @Schema(description = "房间号")
              private String roomNumber;
          
              @Schema(description = "用户姓名")
              private String name;
          
              @Schema(description = "用户手机号码")
              private String phone;
          }
          
      • 响应数据结构

        单个租约信息的结构可查看com.atguigu.lease.web.admin.vo.agreement.AgreementVo,内容如下:

        @Data
        @Schema(description = "租约信息")
        public class AgreementVo extends LeaseAgreement {
        
            @Schema(description = "签约公寓信息")
            private ApartmentInfo apartmentInfo;
        
            @Schema(description = "签约房间信息")
            private RoomInfo roomInfo;
        
            @Schema(description = "支付方式")
            private PaymentType paymentType;
        
            @Schema(description = "租期")
            private LeaseTerm leaseTerm;
        }
        

    代码开发

    LeaseAgreementController中增加如下内容

    @Operation(summary = "根据条件分页查询租约列表")
    @GetMapping("page")
    public Result<IPage<AgreementVo>> page(@RequestParam long current, @RequestParam long size, AgreementQueryVo queryVo) {
    
        Page<AgreementVo> page = new Page<>(current, size);
        IPage<AgreementVo> result = agreementService.pageAgreement(page,queryVo);
        return Result.ok(result);
    }
    

    LeaseAgreementService中增加如下内容

    IPage<AgreementVo> pageAgreementByQuery(IPage<AgreementVo> page, AgreementQueryVo queryVo);
    

    LeaseAgreementServiceImpl中增加如下内容

    @Autowired
    private LeaseAgreementMapper leaseAgreementMapper;
    
    /**
         * 分页查询
         *
         * @param page
         * @param queryVo
         * @return
         */
    @Override
    public IPage<AgreementVo> pageAgreement(Page<AgreementVo> page, AgreementQueryVo queryVo) {
    
        IPage<AgreementVo> agreementVoIPage = leaseAgreementMapper.pageAgreement(page,queryVo);
    
        return agreementVoIPage;
    }
    

    LeaseAgreementMapper中增加如下内容

    IPage<AgreementVo> pageAgreementByQuery(IPage<AgreementVo> page, AgreementQueryVo queryVo);
    

    LeaseAgreementMapper.xml中增加如下内容

    <resultMap id="agreementVoMap" type="com.atguigu.lease.web.admin.vo.agreement.AgreementVo" autoMapping="true">
        <id property="id" column="id"/>
        <association property="apartmentInfo" javaType="com.atguigu.lease.model.entity.ApartmentInfo" autoMapping="true">
            <id property="id" column="apartment_id"/>
            <result property="name" column="apartment_name"/>
        </association>
        <association property="roomInfo" javaType="com.atguigu.lease.model.entity.RoomInfo" autoMapping="true">
            <id property="id" column="room_id"/>
        </association>
        <association property="paymentType" javaType="com.atguigu.lease.model.entity.PaymentType" autoMapping="true">
            <id property="id" column="payment_type_id"/>
            <result property="name" column="payment_type_name"/>
        </association>
        <association property="leaseTerm" javaType="com.atguigu.lease.model.entity.LeaseTerm" autoMapping="true">
            <id property="id" column="lease_term_id"/>
        </association>
    </resultMap>
    
    <select id="pageAgreementByQuery" resultMap="agreementVoMap">
        select la.id,
               la.phone,
               la.name,
               la.identification_number,
               la.lease_start_date,
               la.lease_end_date,
               la.rent,
               la.deposit,
               la.status,
               la.source_type,
               la.additional_info,
               ai.id   apartment_id,
               ai.name apartment_name,
               ai.district_id,
               ai.district_name,
               ai.city_id,
               ai.city_name,
               ai.province_id,
               ai.province_name,
               ri.id   room_id,
               ri.room_number,
               pt.id   payment_type_id,
               pt.name payment_type_name,
               pt.pay_month_count,
               lt.id   lease_term_id,
               lt.month_count,
               lt.unit
        from  lease_agreement la
                 left join
              apartment_info ai
             on la.apartment_id = ai.id and ai.is_deleted=0
                 left join
              room_info ri
             on la.room_id = ri.id and ri.is_deleted=0
                 left join
              payment_type pt
             on la.payment_type_id = pt.id and pt.is_deleted=0
                 left join
              lease_term lt
             on la.lease_term_id = lt.id and lt.is_deleted=0
            <where>
                la.is_deleted = 0
                <if test="queryVo.provinceId != null">
                    and ai.province_id = #{queryVo.provinceId}
                </if>
                <if test="queryVo.cityId != null">
                    and ai.city_id = #{queryVo.cityId}
                </if>
                <if test="queryVo.districtId != null">
                    and ai.district_id = #{queryVo.districtId}
                </if>
                <if test="queryVo.apartmentId != null">
                    and la.apartment_id = #{queryVo.apartmentId}
                </if>
                <if test="queryVo.roomNumber != null and queryVo.roomNumber != ''">
                    and ri.room_number like concat('%',#{queryVo.roomNumber},'%')
                </if>
                <if test="queryVo.name != null and queryVo.name != ''">
                    and la.name like concat('%',#{queryVo.name},'%')
                </if>
                <if test="queryVo.phone != null and queryVo.phone != ''">
                    and la.phone like concat('%',#{queryVo.phone},'%')
                </if>
            </where>
    </select>
    
    3.3、根据ID查询租约信息

    查看接口

    image-20240617122500927

    代码开发

    LeaseAgreementController中增加如下内容

    @Operation(summary = "根据id查询租约信息")
    @GetMapping(name = "getById")
    public Result<AgreementVo> getById(@RequestParam Long id) {
        AgreementVo apartment = service.getAgreementById(id);
        return Result.ok(apartment);
    }
    

    LeaseAgreementService中增加如下内容

    AgreementVo getAgreementById(Long id);
    

    LeaseAgreementServiceImpl中增加如下内容

        @Autowired
        private ApartmentInfoMapper apartmentInfoMapper;
    
        @Autowired
        private RoomInfoMapper roomInfoMapper;
    
        @Autowired
        private PaymentTypeMapper paymentTypeMapper;
    
        @Autowired
        private LeaseTermMapper leaseTermMapper;
    
        /**
         * 根据id查询租约信息
         *
         * @param id
         * @return
         */
        @Override
        public AgreementVo getLeaseAgreementById(Long id) {
            //查询租约信息
            LeaseAgreement leaseAgreement = this.getById(id);
    
            //查询签约公寓信息
            ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(leaseAgreement.getApartmentId());
    
            //查询签约信息房间
            RoomInfo roomInfo = roomInfoMapper.selectById(leaseAgreement.getRoomId());
    
            //查询支付方式
            PaymentType paymentType = paymentTypeMapper.selectById(leaseAgreement.getPaymentTypeId());
    
            //查询租期
            LeaseTerm leaseTerm = leaseTermMapper.selectById(leaseAgreement.getLeaseTermId());
    
            AgreementVo agreementVo = new AgreementVo();
            BeanUtils.copyProperties(leaseAgreement,agreementVo);
            agreementVo.setApartmentInfo(apartmentInfo);
            agreementVo.setRoomInfo(roomInfo);
            agreementVo.setPaymentType(paymentType);
            agreementVo.setLeaseTerm(leaseTerm);
    
            return agreementVo;
        }
    
    3.4、根据ID删除租约信息

    查看接口

    image-20240617122845574

    代码开发

    LeaseAgreementController中增加如下内容

    @Operation(summary = "根据id删除租约信息")
    @DeleteMapping("removeById")
    public Result removeById(@RequestParam Long id) {
        agreementService.removeById(id);
        return Result.ok();
    }
    
    3.5、根据ID更新租约状态

    查看接口

    image-20240617123014998

    代码开发

    后台管理系统需要多个修改租约状态的接口,例如修改租约状态为已取消修改租约状态为已退租等等。为省去重复编码,此处将多个接口合并为一个如下,注意,在生产中应避免这样的写法。

    LeaseAgreementController中增加如下内容

    @Operation(summary = "根据id更新租约状态")
    @PostMapping("updateStatusById")
    public Result updateStatusById(@RequestParam Long id, @RequestParam LeaseStatus status) {
        LambdaUpdateWrapper<LeaseAgreement> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(LeaseAgreement::getId,id);
        updateWrapper.set(LeaseAgreement::getStatus,status);
        agreementService.update(updateWrapper);
        return Result.ok();
    }
    
    3.6、定时检查租约状态

    通过定时任务定时检查租约是否到期。SpringBoot内置了定时任务,具体实现如下。

    • 启用Spring Boot定时任务

      在SpringBoot启动类上增加@EnableScheduling注解,如下

      @SpringBootApplication
      @EnableScheduling
      public class AdminWebApplication {
          public static void main(String[] args) {
              SpringApplication.run(AdminWebApplication.class, args);
          }
      }
      
    • 编写定时逻辑

      web-admin模块下创建com.atguigu.lease.web.admin.schedule.ScheduledTasks类,内容如下

      @Component
      public class ScheduledTasks {
      
          @Autowired
          private LeaseAgreementService leaseAgreementService;
      
          @Scheduled(cron = "0 0 0 * * *")
          public void checkLeaseStatus() {
      
              LambdaUpdateWrapper<LeaseAgreement> updateWrapper = new LambdaUpdateWrapper<>();
              Date now = new Date();
              updateWrapper.le(LeaseAgreement::getLeaseEndDate, now);
              updateWrapper.eq(LeaseAgreement::getStatus, LeaseStatus.SIGNED);
              updateWrapper.in(LeaseAgreement::getStatus, LeaseStatus.SIGNED, LeaseStatus.WITHDRAWING);
      
              leaseAgreementService.update(updateWrapper);
          }
      }
      

      知识点:

      SpringBoot中的cron表达式语法如下

        ┌───────────── second (0-59)
        │ ┌───────────── minute (0 - 59)
        │ │ ┌───────────── hour (0 - 23)
        │ │ │ ┌───────────── day of the month (1 - 31)
        │ │ │ │ ┌───────────── month (1 - 12) (or JAN-DEC)
        │ │ │ │ │ ┌───────────── day of the week (0 - 7)
        │ │ │ │ │ │          (0 or 7 is Sunday, or MON-SUN)
        │ │ │ │ │ │
        * * * * * *
      
  • 相关阅读:
    数据加密的常见方法
    文件上传 切片与断点续传 持续更新
    Anaconda安装和配置
    BLE协议栈1-物理层PHY
    IdeaVim插件使用记录
    1624. 两个相同字符之间的最长子字符串
    一篇学会JUC、JVM 吊打面试官!
    《C++新经典》第18章 内存高级话题
    Spring JdbcTemplate Junit 测试 - ResultSetExtractor/RowMapper
    2022 全球 AI 模型周报
  • 原文地址:https://blog.csdn.net/weixin_53961667/article/details/139740563