From 0ab9dfd8f122195e4e9f09bd50c59e0a47450bec Mon Sep 17 00:00:00 2001
From: mitao <2763622819@qq.com>
Date: 星期三, 19 三月 2025 15:50:03 +0800
Subject: [PATCH] fix: resolve merge conflicts in .gitignore

---
 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java |  315 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 281 insertions(+), 34 deletions(-)

diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java
index d81c565..989234b 100644
--- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java
+++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java
@@ -3,22 +3,25 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.basic.PageInfo;
 import com.ruoyi.common.constant.DictConstants;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.domain.model.LoginUserApplet;
+import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.DictUtils;
 import com.ruoyi.framework.web.service.TokenService;
+import com.ruoyi.system.bo.ProcessTaskListBO;
 import com.ruoyi.system.dto.TBillDto;
 import com.ruoyi.system.dto.TInvoiceDTO;
 import com.ruoyi.system.model.*;
-import com.ruoyi.system.query.TBannerQuery;
-import com.ruoyi.system.query.TBillQuery;
-import com.ruoyi.system.query.TCheckAcceptRecordAppletQuery;
-import com.ruoyi.system.query.TCheckAcceptRecordQuery;
+import com.ruoyi.system.query.*;
 import com.ruoyi.system.service.*;
 import com.ruoyi.system.vo.*;
+import com.ruoyi.web.controller.tool.MyFileUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import jdk.nashorn.internal.parser.Token;
@@ -26,11 +29,20 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
+import java.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 /**
@@ -56,9 +68,23 @@
     private TBillService billService;
     @Autowired
     private THouseService houseService;
-
     @Autowired
-    private  TCheckAcceptRecordService checkAcceptRecordService;
+    private TFaultRepairMessageService tFaultRepairMessageService;
+    @Autowired
+    private TCheckAcceptRecordService checkAcceptRecordService;
+    @Autowired
+    private TTenantService tenantService;
+    @Autowired
+    private ISysUserService sysUserService;
+    @Autowired
+    private TContractRentTypeService contractRentTypeService;
+    @Autowired
+    private StateProcessTemplateService processTemplateService;
+
+    public static void main(String[] args) throws IOException {
+        File file = new File("D:\\wechatFiles\\WeChat Files\\wxid_25nztsudcon722\\FileStorage\\File\\2025-03\\2.mp3");
+        MultipartFile multipartFile = MyFileUtil.fileToMultipartFile(file, "3333");
+    }
     /**
      * 获取轮播图管理列表
      */
@@ -66,7 +92,9 @@
     @PostMapping(value = "/list")
     public R<List<TBanner>> list(@RequestBody TBannerQuery query) {
         return R.ok(bannerService.list(query));
-    }    /**
+    }
+
+    /**
      * 获取轮播图管理列表
      */
     @ApiOperation(value = "租户-我的待办")
@@ -74,48 +102,52 @@
     public R<MyToDoVO> tenantMyToDo() {
         MyToDoVO myToDoVO = new MyToDoVO();
         LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet();
-        if (loginUserApplet!=null){
+        if (loginUserApplet != null) {
             long contractCount = contractService.count(new LambdaQueryWrapper<TContract>()
                     .eq(TContract::getStatus, 3).eq(TContract::getTenantId, loginUserApplet.getUserId()));
             myToDoVO.setContractCount((int) contractCount);
             List<String> contractIds = contractService.lambdaQuery().eq(TContract::getTenantId, loginUserApplet.getUserId()).list()
                     .stream().map(TContract::getId).collect(Collectors.toList());
-            if (CollectionUtils.isEmpty(contractIds)){
+            if (CollectionUtils.isEmpty(contractIds)) {
                 myToDoVO.setBillCount(0);
                 myToDoVO.setContractCount(0);
                 return R.ok(myToDoVO);
             }
             int billCount = billService.lambdaQuery().in(TBill::getContractId, contractIds).eq(TBill::getPayFeesStatus, 1).list().size();
             myToDoVO.setBillCount(billCount);
-        }else {
+        } else {
             myToDoVO.setBillCount(0);
             myToDoVO.setContractCount(0);
         }
         return R.ok(myToDoVO);
     }
+
+
+
     @ApiOperation(value = "租户-当前在租房源")
     @PostMapping(value = "/tenant/myHouse")
     public R<List<MyHouseVO>> myHouse() {
         List<MyHouseVO> myHouseVOS = new ArrayList<>();
         LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet();
 
-        if (loginUserApplet!=null){
+        if (loginUserApplet != null) {
             List<TContract> contractList = contractService.lambdaQuery().eq(TContract::getTenantId, loginUserApplet.getUserId())
                     .eq(TContract::getStatus, 4).list();
             List<THouse> houseList = houseService.list();
             List<TBill> bills = billService.lambdaQuery().orderByDesc(TBill::getPayableFeesTime).list();
             for (TContract contract : contractList) {
                 THouse tHouse = houseList.stream().filter(e -> e.getId().equals(contract.getHouseId())).findFirst().orElse(null);
-                TBill bill = bills.stream().filter(e -> e.getContractId().equals(contract.getId())&&e.getPayFeesStatus().equals("3")).findFirst().orElse(null);
-                if (bill==null){
+                TBill bill = bills.stream().filter(e -> e.getContractId().equals(contract.getId()) && e.getPayFeesStatus().equals("3")).findFirst().orElse(null);
+                if (bill == null) {
                     bill = bills.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
                 }
-                if (tHouse!=null&& bill!=null){
+                if (tHouse != null && bill != null) {
                     MyHouseVO myToDoVO = new MyHouseVO();
+                    myToDoVO.setId(contract.getId());
                     myToDoVO.setHouseAddress(tHouse.getHouseAddress());
                     myToDoVO.setMonthRent(contract.getMonthRent());
-                    myToDoVO.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,contract.getPayType()));
-                    myToDoVO.setMonth(bill.getPayFeesTime()==null?bill.getPayableFeesTime().getMonth()+"月":bill.getPayFeesTime().getMonth()+"月");
+                    myToDoVO.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE, contract.getPayType()));
+                    myToDoVO.setMonth(bill.getPayFeesTime() == null ? bill.getPayableFeesTime().getMonth().getValue() + "月" : bill.getPayFeesTime().getMonth().getValue() + "月");
                     myToDoVO.setHouseArea(tHouse.getHouseArea());
                     myToDoVO.setHouseType(tHouse.getHouseType());
                     myToDoVO.setEndTime(DateUtils.localDateTimeToStringYear(contract.getEndTime()));
@@ -130,7 +162,7 @@
                         }
                         PayListVO payListVO = new PayListVO();
                         payListVO.setPayFeesTime(DateUtils.localDateTimeToStringYear(tBill.getPayFeesTime()));
-                        payListVO.setPayFeesMoney("-"+tBill.getPayFeesMoney()+"元");
+                        payListVO.setPayFeesMoney("-" + tBill.getPayFeesMoney() + "元");
                         payList.add(payListVO);
                     }
                     myToDoVO.setPayList(payList);
@@ -139,25 +171,80 @@
 
             }
             return R.ok(myHouseVOS);
-        }else {
+        } else {
             return R.ok(myHouseVOS);
         }
     }
+
+    @ApiOperation(value = "租户-当前在租房源-租赁详情")
+    @GetMapping(value = "/tenant/myHouseDetail")
+    public R<MyHouseVO> myHouseDetail(String id) {
+        LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet();
+
+        if (loginUserApplet != null) {
+            MyHouseVO myToDoVO = new MyHouseVO();
+            TContract contract = contractService.getById(id);
+            List<TBill> bills = billService.lambdaQuery().orderByDesc(TBill::getPayableFeesTime).list();
+            THouse tHouse = houseService.getById(contract.getHouseId());
+            TBill bill = bills.stream().filter(e -> e.getContractId().equals(contract.getId()) && e.getPayFeesStatus().equals("3")).findFirst().orElse(null);
+            if (bill == null) {
+                bill = bills.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null);
+            }
+            if (tHouse != null && bill != null) {
+                myToDoVO.setId(contract.getId());
+                myToDoVO.setHouseAddress(tHouse.getHouseAddress());
+                myToDoVO.setMonthRent(contract.getMonthRent());
+                myToDoVO.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE, contract.getPayType()));
+                myToDoVO.setMonth(bill.getPayFeesTime() == null ? bill.getPayableFeesTime().getMonth().getValue() + "月" : bill.getPayFeesTime().getMonth().getValue() + "月");
+                myToDoVO.setHouseArea(tHouse.getHouseArea());
+                myToDoVO.setHouseType(tHouse.getHouseType());
+                myToDoVO.setEndTime(DateUtils.localDateTimeToStringYear(contract.getEndTime()));
+                myToDoVO.setStartTime(DateUtils.localDateTimeToStringYear(contract.getStartTime()));
+                myToDoVO.setPropertyRightPerson(tHouse.getPropertyRightPerson());
+                myToDoVO.setPhone(tHouse.getPhone());
+                List<TBill> billList = bills.stream().filter(e -> e.getContractId().equals(contract.getId())).collect(Collectors.toList());
+                List<PayListVO> payList = new ArrayList<>();
+                for (TBill tBill : billList) {
+                    if (tBill.getPayFeesTime()==null){
+                        continue;
+                    }
+                    PayListVO payListVO = new PayListVO();
+                    payListVO.setPayFeesTime(DateUtils.localDateTimeToStringYear(tBill.getPayFeesTime()));
+                    payListVO.setPayFeesMoney("-" + tBill.getPayFeesMoney() + "元");
+                    payList.add(payListVO);
+                }
+                myToDoVO.setPayList(payList);
+            }
+
+            return R.ok(myToDoVO);
+        } else {
+            return R.ok(new MyHouseVO());
+        }
+    }
+
     @ApiOperation(value = "管理员-我的待办")
     @PostMapping(value = "/admin/myToDo")
     public R<MyToDoVO> adminMyToDo() {
         MyToDoVO myToDoVO = new MyToDoVO();
-        LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet();
-        if (loginUserApplet!=null){
-            long examineCount = contractService.count(new LambdaQueryWrapper<TContract>()
-                    .eq(TContract::getStatus, 2));
-            myToDoVO.setExamineCount((int) examineCount);
+        LoginUser loginUser = tokenService.getLoginUser();
+        if (loginUser != null) {
+//            long examineCount = contractService.count(new LambdaQueryWrapper<TContract>()
+//                    .eq(TContract::getStatus, 2));
+            ProcessTaskListBO processTaskListBO = new ProcessTaskListBO();
+            PageInfo<ProcessTaskListVO> processTaskListVOPageInfo = processTemplateService.waitTaskPage(processTaskListBO);
+            myToDoVO.setExamineCount((int) processTaskListVOPageInfo.getTotal());
             List<String> contractIds = billService.lambdaQuery().eq(TBill::getPayFeesStatus, 4).list()
                     .stream().map(TBill::getContractId).collect(Collectors.toList());
-            int overdueCount = contractService.lambdaQuery().in(TContract::getId, contractIds).list()
-                    .stream().map(TContract::getTenantId).distinct().collect(Collectors.toList()).size();
-            myToDoVO.setOverdueCount(overdueCount);
-        }else {
+            if(contractIds.isEmpty()){
+                myToDoVO.setOverdueCount(0);
+
+            }else{
+                int overdueCount = contractService.lambdaQuery().in(TContract::getId, contractIds).list()
+                        .stream().map(TContract::getTenantId).distinct().collect(Collectors.toList()).size();
+                myToDoVO.setOverdueCount(overdueCount);
+            }
+
+        } else {
             myToDoVO.setExamineCount(0);
             myToDoVO.setOverdueCount(0);
         }
@@ -172,6 +259,7 @@
     public R<PageInfo<TCheckAcceptRecordVO>> houseCheck(@RequestBody TCheckAcceptRecordAppletQuery query) {
         return R.ok(checkAcceptRecordService.pageListApplet(query));
     }
+
     /**
      * 查看验收记录详情
      */
@@ -179,10 +267,11 @@
     @GetMapping(value = "/getDetailById")
     public R<TCheckAcceptRecordVO> getDetailById(@RequestParam String id) {
         TCheckAcceptRecord checkAcceptRecord = checkAcceptRecordService.getById(id);
-        checkAcceptRecord.setCleanSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getCleanSituation()));
-        checkAcceptRecord.setOverallSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getOverallSituation()));
-        checkAcceptRecord.setDeviceSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getDeviceSituation()));
-        checkAcceptRecord.setFurnitureSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getFurnitureSituation()));
+//        checkAcceptRecord.setCleanSituation(checkAcceptRecord.getCleanSituation());
+//        checkAcceptRecord.setOverallSituation(StringUtils.hasLength(checkAcceptRecord.getOverallSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getOverallSituation())):"");
+//        checkAcceptRecord.setDeviceSituation(StringUtils.hasLength(checkAcceptRecord.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getDeviceSituation())):"");
+//        checkAcceptRecord.setFurnitureSituation(StringUtils.hasLength(checkAcceptRecord.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getFurnitureSituation())):"");
+
         TCheckAcceptRecordVO checkAcceptRecordVO = new TCheckAcceptRecordVO();
         BeanUtils.copyProperties(checkAcceptRecord, checkAcceptRecordVO);
         // 查询合同信息
@@ -191,12 +280,170 @@
         checkAcceptRecordVO.setHouse(houseService.getById(checkAcceptRecord.getHouseId()));
         return R.ok(checkAcceptRecordVO);
     }
-    @ApiOperation(value = "管理员-新增验收")
-    @GetMapping(value = "/addRecord")
-    public R<TCheckAcceptRecordVO> getDetailById(@Validated @RequestBody TCheckAcceptRecord dto) {
 
+    @ApiOperation(value = "管理员-新增验收")
+    @PostMapping(value = "/addRecord")
+    public R<TCheckAcceptRecordVO> addRecord(@Validated @RequestBody TCheckAcceptRecord dto) {
+        dto.setAcceptanceTime(LocalDateTime.now());
+        dto.setCheckTime(LocalDateTime.now());
+        LocalDate now = LocalDate.now();
+        String replace = (now + "").replace("-", "");
+        int size = checkAcceptRecordService.list(new LambdaQueryWrapper<TCheckAcceptRecord>()
+                .likeRight(TCheckAcceptRecord::getAcceptanceTime, LocalDate.now())).size();
+        dto.setCode(replace.substring(2)+String.format("%03d", size+1));
+        dto.setStatus(true);
+        // 添加验收记录
+        dto.setCheckPerson(tokenService.getLoginUser().getUser().getNickName());
+        checkAcceptRecordService.updateById(dto);
         return R.ok();
     }
+    /**
+     * 获取报修管理列表
+     */
+    @ApiOperation(value = "管理员-房屋维修分页列表")
+    @PostMapping(value = "/housePageList")
+    public R<PageInfo<TFaultRepairMessageVO>> pageList(@RequestBody TFaultRepairMessageAppletQuery query) {
+        return R.ok(tFaultRepairMessageService.pageListApplet(query));
+    }
+    /**
+     * 查看报修详情
+     */
+    @ApiOperation(value = "管理员-房屋维修查看详情")
+    @GetMapping(value = "/getDetailByIdRepair")
+    public R<TFaultRepairMessageVO> getDetailByIdRepair(@RequestParam String id) {
+        TFaultRepairMessageVO faultRepairMessageVO = tFaultRepairMessageService.getDetailById(id);
+        return R.ok(faultRepairMessageVO);
+    }
+
+    /**
+     * 处理维修
+     */
+    @Log(title = "报修信息-处理维修", businessType = BusinessType.UPDATE)
+    @ApiOperation(value = "管理员-维修处理")
+    @PostMapping(value = "/handle")
+    public R<Boolean> handle(@Validated @RequestBody TFaultRepairMessage faultRepairMessage) {
+        faultRepairMessage.setStatus(2);
+        return R.ok(tFaultRepairMessageService.updateById(faultRepairMessage));
+    }
+
+    /**
+     * 获取租户管理列表
+     */
+    @ApiOperation(value = "获取租户分页列表")
+    @PostMapping(value = "/pageList")
+    public R<PageInfo<TenantVO>> pageList(@RequestBody TTenantAppletQuery query) {
+        return R.ok(tenantService.pageListApplet(query));
+    }
+    /**
+     * 获取租户管理列表
+     */
+    @ApiOperation(value = "获取租户详情")
+    @GetMapping(value = "/getTenantDetailById")
+    public R<TTenant> getTenantDetailById(@RequestParam String id) {
+        return R.ok(tenantService.getById(id));
+    }
+    /**
+     * 租户详情-租房信息
+     */
+    @ApiOperation(value = "租户详情-租房信息列表")
+    @GetMapping(value = "/listHouse")
+    public R<List<THouse>> listHouse(@RequestParam String id) {
+        List<THouse> res = tenantService.listHouse(id);
+        return R.ok(res);
+    }
+    /**
+     * 租户详情-租房信息
+     */
+    @ApiOperation(value = "租户详情-合同列表")
+    @GetMapping(value = "/listContract")
+    public R<List<TContract>> listContract(@RequestParam String id) {
+        List<TContract> res = tenantService.listContract(id);
+        return R.ok(res);
+    }
+    @ApiOperation(value = "租户详情-缴费账单列表")
+    @PostMapping("/listBill")
+    public R<PageInfo<TBillVO>> listBill(@RequestBody TBillAppletQuery query){
+        PageInfo<TBillVO> pageInfo = tenantService.listBill(query);
+        return R.ok(pageInfo);
+    }
+    @ApiOperation(value = "租户详情-缴费账单-账单详情")
+    @PostMapping("/billDetail")
+    public R<TBillVO> billDetail(String id){
+        TBillVO res = new TBillVO();
+        TBill bill = billService.getById(id);
+        BeanUtils.copyProperties(bill, res);
+        TContract contract = contractService.getById(bill.getContractId());
+        THouse tHouse = houseService.getById(contract.getHouseId());
+        res.setHouse(tHouse);
+        res.setConcatStartTime(contract.getStartTime());
+        res.setConcatEndTime(contract.getEndTime());
+        res.setPartyOnePhone(contract.getPartyOnePhone());
+        res.setPartyOnePerson(contract.getPartyTwoPerson());
+        res.setMonthRent(bill.getPayableFeesMoney());
+        res.setPayType(contract.getPayType());
+        return R.ok(res);
+    }
+    @ApiOperation(value = "管理员-我的审批分页列表")
+    @PostMapping("/listExamine")
+    public R<PageInfo<ExamineVO>> examineList(@RequestBody TExamineAppletQuery dto){
+        LoginUser loginUser = tokenService.getLoginUser();
+        if (loginUser==null){
+            return R.fail(401,"登录失效");
+        }
+        SysUser sysUser = sysUserService.selectUserById(loginUser.getUserId());
+        dto.setUserName(sysUser.getUserName());
+        PageInfo<ExamineVO> pageInfo = tenantService.examineList(dto);
+        return R.ok(pageInfo);
+    }
+    @ApiOperation(value = "管理员-审批详情")
+    @GetMapping("/examineDetail")
+    public R<TContractVO> examineDetail(@RequestParam String id){
+        TContractVO res = new TContractVO();
+        TContract contract = contractService.getById(id);
+        BeanUtils.copyProperties(contract,res);
+        res.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,res.getPayType()));
+        res.setStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS,res.getStatus()));
+        TContractRentType contractRentType = contractRentTypeService.lambdaQuery().eq(TContractRentType::getContractId, id).one();
+        if (contractRentType!=null){
+            BeanUtils.copyProperties(contractRentType,res);
+        }
+        TContract oldContract = contractService.getOne(new LambdaQueryWrapper<TContract>()
+                .eq(TContract::getHouseId,contract.getHouseId())
+                .eq(TContract::getStatus, 4)
+                .le(TContract::getStartTime, LocalDateTime.now())
+                .ge(TContract::getEndTime, LocalDateTime.now()));
+        THouse house = houseService.getById(contract.getHouseId());
+        if (oldContract!=null){
+            house.setTenantType(oldContract.getPayType());
+        }
+        res.setHouse(house);
+        List<TBill> list = billService.lambdaQuery()
+                .eq(TBill::getContractId, id)
+                .in(TBill::getPayFeesStatus, Arrays.asList("1,4"))
+                .list();
+        BigDecimal payMoney = new BigDecimal("0");
+        for (TBill tBill : list) {
+            payMoney = payMoney.add(tBill.getPayFeesMoney()).add(tBill.getPayableFeesPenalty());
+        }
+        TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery().eq(TCheckAcceptRecord::getContractId, id).one();
+        res.setCheckResult(Objects.nonNull(tCheckAcceptRecord)?tCheckAcceptRecord.getCheckResult():false);
+        res.setPayMoney(payMoney);
+
+        return R.ok(res);
+    }
+    @ApiOperation(value = "管理员-我的审批-撤销")
+    @GetMapping("/cancel")
+    public R cancel(@RequestParam String id){
+        return R.ok();
+    }
+    @ApiOperation(value = "管理员-我的审批-审批")
+    @GetMapping("/examine")
+    public R examine(@RequestParam String id){
+        return R.ok();
+    }
+
+
+
 }
 
 

--
Gitblit v1.7.1