ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java
@@ -1,37 +1,52 @@ package com.ruoyi.web.controller.api; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.WebUtils; import com.ruoyi.system.dto.TContractDTO; import com.ruoyi.system.dto.THouseDTO; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.TContractRentType; import com.ruoyi.system.model.THouse; import com.ruoyi.system.dto.TerminateContractDTO; import com.ruoyi.system.export.ContractExport; import com.ruoyi.system.export.OpticalInspectionExport; import com.ruoyi.system.model.*; import com.ruoyi.system.query.TContractBillQuery; import com.ruoyi.system.query.TContractQuery; import com.ruoyi.system.query.THouseQuery; import com.ruoyi.system.query.TUserHistoryQuery; import com.ruoyi.system.service.TContractRentTypeService; import com.ruoyi.system.service.TContractService; import com.ruoyi.system.service.THouseService; import com.ruoyi.system.service.*; import com.ruoyi.system.vo.BillVO; import com.ruoyi.system.vo.CheckAcceptRecordVO; import com.ruoyi.system.vo.HouseVO; import com.ruoyi.web.controller.tool.NumberToChineseUtils; import com.ruoyi.web.controller.tool.WordUtil; import io.swagger.annotations.Api; import com.ruoyi.system.vo.TContractVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.math.BigDecimal; import java.net.URLEncoder; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import java.util.*; /** * <p> @@ -51,6 +66,10 @@ private TContractRentTypeService contractRentTypeService; @Autowired private THouseService houseService; @Autowired private TBillService billService; @Autowired private TCheckAcceptRecordService checkAcceptRecordService; @ApiOperation(value = "获取合同分页列表") @PostMapping(value = "/contractList") public R<PageInfo<TContract>> contractList(@RequestBody TContractQuery query) { @@ -61,7 +80,7 @@ @PostMapping(value = "/addContract") public R<Boolean> addContract(@Validated @RequestBody TContractDTO dto) { contractService.save(dto); if (dto.getIsIncreasing()==1){ if (dto.getIsIncreasing()){ TContractRentType tContractRentType = new TContractRentType(); tContractRentType.setContractId(dto.getId()); tContractRentType.setIncreasingDecreasing(dto.getIncreasingDecreasing()); @@ -79,7 +98,7 @@ contractService.updateById(dto); contractRentTypeService.remove(new LambdaQueryWrapper<TContractRentType>() .eq(TContractRentType::getContractId,dto.getId())); if (dto.getIsIncreasing()==1){ if (dto.getIsIncreasing()){ TContractRentType tContractRentType = new TContractRentType(); tContractRentType.setContractId(dto.getId()); tContractRentType.setIncreasingDecreasing(dto.getIncreasingDecreasing()); @@ -93,7 +112,7 @@ @Log(title = "合同管理-批量删除合同", businessType = BusinessType.DELETE) @ApiOperation(value = "批量删除合同") @DeleteMapping(value = "/deleteContractByIds") public R<Boolean> deleteContractByIds3 public R<Boolean> deleteContractByIds (@RequestParam String ids) { if (StringUtils.isNotEmpty(ids)){ contractService.removeBatchByIds(Arrays.asList(ids.split(","))); @@ -107,6 +126,8 @@ 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); @@ -121,8 +142,126 @@ 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(tCheckAcceptRecord.getCheckResult()); res.setPayMoney(payMoney); return R.ok(res); } @Log(title = "合同管理-撤销审批", businessType = BusinessType.UPDATE) @ApiOperation(value = "撤销审批") @GetMapping(value = "/updateContractStatus") public R<Boolean> updateContractStatus(String id) { TContract contract = contractService.getById(id); contract.setStatus("1"); return R.ok(); } @ApiOperation(value = "终止合同剩余未缴费账单列表") @PostMapping(value = "/contractBillList") public R<PageInfo<BillVO>> contractBillList(@RequestBody TContractBillQuery query) { return R.ok(contractService.contractBillList(query)); } @ApiOperation(value = "终止合同") @PostMapping(value = "/terminateContract") public R terminateContract(@RequestBody TerminateContractDTO dto) { contractService.terminateContract(dto); return R.ok(); } @ApiOperation(value = "根据合同id查看验收记录") @GetMapping(value = "/getCheckByContractId") public R<CheckAcceptRecordVO> getCheckByContractId(String id) { return R.ok(contractService.getCheckByContractId(id)); } @Autowired private WordUtil wordUtil; @ApiOperation(value = "生成合同附件") @PostMapping("/set") public R set(Integer id, HttpServletResponse response){ TContract contract = contractService.getById(id); THouse tHouse = houseService.getById(contract.getHouseId()); Map<String, Object> templateParam = new HashMap<>(5); templateParam.put("partyOneName", contract.getPartyOneName()); templateParam.put("partyTwoName", contract.getPartyTwoName()); templateParam.put("houseAddress", tHouse.getHouseAddress()); templateParam.put("houseArea", tHouse.getHouseArea()+"m²"); templateParam.put("startTime", DateUtils.localDateTimeToStringYear(contract.getStartTime())); templateParam.put("endTime", DateUtils.localDateTimeToStringYear(contract.getEndTime())); templateParam.put("monthRent", "¥¥"+contract.getMonthRent()+"元"); templateParam.put("monthRentString", "人民币"+NumberToChineseUtils.numberToChinese(contract.getMonthRent().setScale(2, BigDecimal.ROUND_DOWN).doubleValue())); templateParam.put("totalYear", "¥¥"+contract.getTotalYear()+"元"); templateParam.put("totalYearString", "人民币"+NumberToChineseUtils.numberToChinese(contract.getTotalYear().setScale(2, BigDecimal.ROUND_DOWN).doubleValue())); templateParam.put("payType", contract.getPayType().equals("1")?"月":contract.getPayType().equals("2")?"季":"年"); templateParam.put("firstRent", "¥"+(contract.getPayType().equals("1")?contract.getMonthRent():contract.getPayType().equals("2")?contract.getMonthRent().multiply(new BigDecimal("3")):contract.getMonthRent().multiply(new BigDecimal("12"))).setScale(2,BigDecimal.ROUND_DOWN)+"元"); templateParam.put("firstRentString", "人民币"+NumberToChineseUtils.numberToChinese((contract.getPayType().equals("1")?contract.getMonthRent():contract.getPayType().equals("2")?contract.getMonthRent().multiply(new BigDecimal("3")):contract.getMonthRent().multiply(new BigDecimal("12")).setScale(2,BigDecimal.ROUND_DOWN)).doubleValue())); templateParam.put("nextPayTime", contract.getPayType().equals("1")?"月":contract.getPayType().equals("2")?"季":"年"); templateParam.put("deposit", "¥"+contract.getDeposit()+"元"); templateParam.put("depositString", NumberToChineseUtils.numberToChinese(contract.getDeposit().setScale(2, BigDecimal.ROUND_DOWN).doubleValue())); templateParam.put("partyOnePerson", contract.getPartyOnePerson()); templateParam.put("partyOnePhone", contract.getPartyOnePhone()); templateParam.put("partyTwoPerson", contract.getPartyTwoPerson()); templateParam.put("partyTwoPhone", contract.getPartyTwoPhone()); String url = wordUtil.generatePdf("/templates", "1_yzj_租赁合同.xml", templateParam, "租赁合同", "E:\\"); return R.ok(url); } @ApiOperation(value = "导出") @PostMapping("/export") public void export(@RequestBody TContractQuery query){ contractService.export(query); } /** * 光缆巡检列表导出 */ @ApiOperation(value = "光缆巡检列表导出") @Log(title = "现场作业-光缆巡检列表导出", businessType = BusinessType.EXPORT) @PostMapping("/exportOpticalInspection") public void exportOpticalInspection(@RequestBody TContractQuery query) { List<ContractExport> contractExports = new ArrayList<>(); List<TContract> exportList = contractService.contractExportList(query); for (TContract contract : exportList) { ContractExport contractExport = new ContractExport(); contractExport.setContractNumber(contract.getContractNumber()); contractExport.setContractName(contract.getContractName()); contractExport.setPartyOneName(contract.getPartyOneName()); contractExport.setPartyTwoName(contract.getPartyTwoName()); contractExport.setCreate_time(contract.getCreateTime()); contractExport.setStartTime(contract.getStartTime()); contractExport.setEndTime(contract.getEndTime()); contractExport.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,contract.getPayType())); contractExport.setDeposit(contract.getDeposit()+""); contractExport.setStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS,contract.getStatus())); } Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), ContractExport.class, contractExports); HttpServletResponse response = WebUtils.response(); response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); ServletOutputStream outputStream = null; try { String fileName = URLEncoder.encode("合同列表.xls", "utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName); response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache"); outputStream = response.getOutputStream(); workbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); System.err.println("合同列表信息导出失败"); } finally { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/THouseController.java
@@ -3,23 +3,30 @@ 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.R; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.system.dto.THouseDTO; import com.ruoyi.system.dto.TTenantDTO; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.THouse; import com.ruoyi.system.model.TTenant; import com.ruoyi.system.query.THouseQuery; import com.ruoyi.system.query.TTenantQuery; import com.ruoyi.system.query.TUserHistoryQuery; import com.ruoyi.system.service.TContractService; import com.ruoyi.system.service.THouseService; import com.ruoyi.system.vo.HouseVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; /** * <p> @@ -51,7 +58,10 @@ @ApiOperation(value = "查询房屋信息") @GetMapping(value = "/getHouseById") public R<THouse> getHouseById(@RequestParam String id) { return R.ok(tHouseService.getById(id)); THouse tHouse = tHouseService.getById(id); tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus())); tHouse.setBusinessAttributes(DictUtils.getDictLabel(DictConstants.DICT_TYPE_BUSINESS_ATTRIBUTES,tHouse.getBusinessAttributes())); return R.ok(tHouse); } @Log(title = "房屋基础信息管理-删除房屋", businessType = BusinessType.DELETE) @ApiOperation(value = "删除房屋") ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTenantController.java
@@ -3,8 +3,10 @@ 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.enums.BusinessType; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.dto.TTenantDTO; @@ -85,7 +87,10 @@ @ApiOperation(value = "查看租户详情") @GetMapping(value = "/getDetailById") public R<TTenant> getDetailById(@RequestParam String id) { return R.ok(tenantService.getById(id)); TTenant tenant = tenantService.getById(id); tenant.setTenantAttributes(DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_ATTRIBUTE,tenant.getTenantAttributes())); tenant.setTenantType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_TYPE,tenant.getTenantType())); return R.ok(tenant); } /** ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/NumberToChineseUtils.java
New file @@ -0,0 +1,129 @@ package com.ruoyi.web.controller.tool; public class NumberToChineseUtils { // 中文数字字符 private static final char[] CHINESE_NUMBERS = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'}; // 单位字符 private static final String[] UNITS = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"}; /** * 数字转大写中文 * * @param num 需要转换的数字 * @return 转换后的大写中文字符串 */ public static String numberToChinese(long num) { if (num == 0) { return "零"; } StringBuilder result = new StringBuilder(); String numStr = String.valueOf(num); int unitIndex = 0; // 单位索引 boolean zeroFlag = false; // 标记上一个字符是否为0 for (int i = numStr.length() - 1; i >= 0; i--) { int digit = numStr.charAt(i) - '0'; String part = toChinesePart(digit, unitIndex, zeroFlag); result.insert(0, part); // 更新上一个字符是否为零的标记 zeroFlag = digit == 0; // 更新单位索引 if (unitIndex == 4 || unitIndex == 8) { unitIndex = 1; // 万和亿后单位重置 } else { unitIndex++; } } // 去除结果字符串末尾的'零' while (result.length() > 1 && result.charAt(result.length() - 1) == '零') { result.deleteCharAt(result.length() - 1); } return result.toString(); } /** * 转换数字部分并添加单位 * * @param digit 当前数字 * @param unitIndex 单位索引 * @param zeroFlag 上一个字符是否为零 * @return 转换后的字符串 */ private static String toChinesePart(int digit, int unitIndex, boolean zeroFlag) { if (digit == 0) { return zeroFlag ? "" : "零"; } String part = CHINESE_NUMBERS[digit] + UNITS[unitIndex]; // 连续两个'零'只保留一个 if (part.equals("零零") || part.equals("零拾")) { return "零"; } // 去除'零拾'、'零佰'、'零仟' if (part.startsWith("零")) { part = part.substring(1); } return part; } /** * 数字转大写中文(支持小数) * * @param number 需要转换的数字 * @return 转换后的大写中文字符串 */ public static String numberToChinese(double number) { if (number == 0) { return "零"; } StringBuilder result = new StringBuilder(); String numStr = String.format("%.2f", number); // 保留两位小数 String[] parts = numStr.split("\\."); // 整数部分 if (!parts[0].equals("0")) { result.append(numberToChinese(Long.parseLong(parts[0]))); } // 小数部分 if (parts.length > 1) { String decimalPart = parts[1]; if (!decimalPart.equals("00")) { result.append("元"); if (decimalPart.charAt(0) != '0') { result.append(CHINESE_NUMBERS[decimalPart.charAt(0) - '0']).append("角"); } if (decimalPart.charAt(1) != '0') { result.append(CHINESE_NUMBERS[decimalPart.charAt(1) - '0']).append("分"); } } else { result.append("元整"); } } else { result.append("元整"); } return result.toString(); } public static void main(String[] args) { System.out.println(numberToChinese(123456)); // 输出: 壹拾贰万叁仟肆佰伍拾陆元整 System.out.println(numberToChinese(10010)); // 输出: 壹万零壹拾元整 System.out.println(numberToChinese(100000001)); // 输出: 壹亿零壹元整 System.out.println(numberToChinese(68435)); // 输出: 陆万捌仟肆佰叁拾伍元整 System.out.println(numberToChinese(24000)); // 输出: 捌仟伍佰肆拾叁元整 System.out.println(numberToChinese(123.45)); // 输出: 壹佰贰拾叁元肆角伍分 System.out.println(numberToChinese(0.67)); // 输出: 零元陆角柒分 System.out.println(numberToChinese(100.00)); // 输出: 壹佰元整 } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java
New file @@ -0,0 +1,227 @@ package com.ruoyi.web.controller.tool; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.documents4j.api.DocumentType; import com.documents4j.api.IConverter; import com.documents4j.job.LocalConverter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.*; import java.net.URL; import java.nio.file.Files; import java.util.HashMap; @Slf4j @Component public class PdfUtils { @Autowired private TencentCosUtil tencentCosUtil; /** * word 转 pdf * * @param url */ public String wordToPdf(String url,String filePath, String fileName) { try { DocumentType documentType = DocumentType.DOC; if(url.contains(".docx")){ documentType = DocumentType.DOCX; } if(url.contains(".doc")){ documentType = DocumentType.DOC; } if(url.contains(".xlsx")){ documentType = DocumentType.XLSX; }else { if(url.contains(".xls")){ documentType = DocumentType.XLS; } } InputStream inputStream = new URL(url).openStream(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); IConverter converter = LocalConverter.builder().build(); converter.convert(inputStream) .as(documentType) .to(stream) .as(DocumentType.PDF).execute(); //上传图片 byte2File(stream.toByteArray(),filePath + "/pdf",fileName.substring(0,fileName.lastIndexOf(".")) + ".pdf"); MultipartFile multipartFile = convertToMultipartFile(stream,fileName.substring(0,fileName.lastIndexOf(".")) ); String s = tencentCosUtil.upLoadFile(multipartFile); stream.close(); inputStream.close(); return s; } catch (Exception e) { e.printStackTrace(); } return null; } public static MultipartFile convertToMultipartFile(ByteArrayOutputStream baos, String fileName) throws IOException { // 创建一个临时文件 File tempFile = File.createTempFile(fileName, ".pdf"); // 将ByteArrayOutputStream中的数据写入临时文件 try (FileOutputStream fos = new FileOutputStream(tempFile)) { baos.writeTo(fos); } catch (IOException e) { e.printStackTrace(); } // 创建一个MultipartFile对象 return new MockMultipartFile( fileName + ".pdf", // 参数名称 fileName + ".pdf", // 文件名 "application/pdf", // 内容类型 Files.readAllBytes(tempFile.toPath()) // 文件内容 ); } /** * file转byte */ public static byte[] file2byte(File file){ byte[] buffer = null; try{ FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int n; while ((n = fis.read(b)) != -1) { bos.write(b, 0, n); } fis.close(); bos.close(); buffer = bos.toByteArray(); }catch (FileNotFoundException e){ e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } return buffer; } /** * byte 转file */ public static File byte2File(byte[] buf, String filePath, String fileName){ BufferedOutputStream bos = null; FileOutputStream fos = null; OutputStreamWriter osw = null; File file = null; try{ File dir = new File(filePath+"/"); if (!dir.exists()){ dir.mkdirs(); } file = new File(filePath +File.separator + fileName); fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos); // osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8); bos.write(buf); }catch (Exception e){ e.printStackTrace(); } finally{ if (bos != null){ try{ bos.close(); }catch (IOException e){ e.printStackTrace(); } } if (fos != null){ try{ fos.close(); }catch (IOException e){ e.printStackTrace(); } } } return file; } /** * multipartFile转File **/ public static File multipartFile2File(MultipartFile multipartFile){ File file = null; if (multipartFile != null){ try { file= File.createTempFile("tmp", null); multipartFile.transferTo(file); System.gc(); file.deleteOnExit(); }catch (Exception e){ e.printStackTrace(); log.warn("multipartFile转File发生异常:"+e); } } return file; } public static void main(String[] args) { // String url = "file:///E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09\\专业技术工作总结.docx"; // String filePath = "E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09"; // String fileName = "专业技术工作总结.docx"; // String s = wordToPdf(url, filePath, fileName); // System.err.println(s); // String url = "file:///F:\\测试动态列表Word.doc"; //// String filePath = "E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09"; //// String fileName = "专业技术工作总结.docx";4 // String filePath = "F:\\"; // // String s = wordToPdf(url, filePath, "测试动态列表Word.doc"); // System.err.println(s); // TODO Auto-generated method stub // HashMap<String, Object> paramMap = new HashMap<>(); // paramMap.put("CorpID", "SCZT006959"); // paramMap.put("Pwd", "123456"); // paramMap.put("Mobile", "19522115070"); // paramMap.put("Cell", ""); // paramMap.put("SendTime", ""); // paramMap.put("Content", java.net.URLEncoder.encode("你好,这是测试短信发送。【职评网】")); // String result3 = HttpUtil.post("http://sdk2.028lk.com/sdk2/BatchSend2.aspx", paramMap); // if (result3 == null) { // result3 = ""; // } // result3 = StrUtil.trim(result3); // log.info("返回结果:" + result3); // // if (result3.matches("^\\d+$") && !result3.equals("0")) { // return; // } } public String test(String fileName){ String url = "file:///D:\\"+fileName; // String filePath = "E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09"; // String fileName = "专业技术工作总结.docx";4 String filePath = "E:\\"; String s = wordToPdf(url, filePath, fileName); System.err.println(s); return s; } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java
New file @@ -0,0 +1,168 @@ package com.ruoyi.web.controller.tool; import freemarker.cache.ClassTemplateLoader; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Map; @Slf4j @Component public class WordUtil { /** * 基于模板生成 Word 文档 * * @param basePackagePath resources 目录下模板所在包路径 * @param templateFileName 模板文件名 * @param templateParam 模板参数 * @param fileName 文件名 */ // public void generate(HttpServletResponse response, String basePackagePath, String templateFileName, Object templateParam, String fileName) { // try { // // 设置 HTTP 响应的内容类型为 Microsoft Word 文档 // response.setContentType("application/msword"); // // 设置响应字符编码为 UTF-8 // response.setCharacterEncoding("utf-8"); // // 使用 URLEncoder 对文件名进行编码,以防止中文文件名在不同浏览器和操作系统下出现乱码问题 // String filename = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8"); // // 设置响应头,指定文档将以附件的形式下载,并定义文件名 // response.setHeader("Content-disposition", "attachment;filename=" + filename + ".doc"); // // 创建 Freemarker 的 Configuration 对象,设置默认的不兼容改进选项 // Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); // configuration.setDefaultEncoding("utf-8"); // // 设置模板加载器,加载模板文件 // configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath)); // Template t = configuration.getTemplate(templateFileName, "utf-8"); // // 创建 Writer 对象,用于将生成的文档写到输出流中,缓存区大小设为 10KB // Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8), 10240); // // 将模型数据与模板结合生成 Word 文档,写入到 Writer 对象中 // t.process(templateParam, out); // out.close(); // } catch (Exception e) { // log.info("基于模板{}生成Word文档异常,异常原因:{}", templateFileName, e.getMessage(), e); // throw new RuntimeException("生成Word文档异常,异常原因:" + e.getMessage()); // } // } @Resource private TencentCosUtil tencentCosUtil; @Resource private PdfUtils pdfUtils; public String generate(String basePackagePath, String templateFileName, Object templateParam, String fileName, String saveDirectory) { try { // 创建 Freemarker 的 Configuration 对象,设置默认的不兼容改进选项 Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); configuration.setDefaultEncoding("utf-8"); // 设置模板加载器,加载模板文件 configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath)); Template t = configuration.getTemplate(templateFileName, "utf-8"); // 使用 URLEncoder 对文件名进行编码,以防止中文文件名在不同浏览器和操作系统下出现乱码问题 // String encodedFileName = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8"); String encodedFileName =fileName ; // 定义保存文件的路径 File saveDir = new File(saveDirectory); if (!saveDir.exists()) { saveDir.mkdirs(); } // 定义文件名 String filePath = saveDir.getAbsolutePath() + File.separator + encodedFileName + ".doc"; // 创建 Writer 对象,用于将生成的文档写到文件中,缓存区大小设为 10KB Writer out = new BufferedWriter(new FileWriter(filePath), 10240); // 将模型数据与模板结合生成 Word 文档,写入到 Writer 对象中 t.process(templateParam, out); out.close(); File file = new File(filePath); // 检查文件是否存在 if (!file.exists()) { throw new FileNotFoundException("文件不存在: " + filePath); } // 读取文件内容 byte[] fileContent = new byte[(int) file.length()]; try (FileInputStream fis = new FileInputStream(file)) { fis.read(fileContent); } MultipartFile mockMultipartFile = new MockMultipartFile(encodedFileName+".doc", fileContent); String s = tencentCosUtil.upLoadFile(mockMultipartFile); return s; } catch (IOException | TemplateException e) { log.error("生成Word文档异常,异常原因:{}", e.getMessage(), e); throw new RuntimeException("生成Word文档异常,异常原因:" + e.getMessage()); } } public String generatePdf(String basePackagePath, String templateFileName, Object templateParam, String fileName, String saveDirectory) { try { // 创建 Freemarker 的 Configuration 对象,设置默认的不兼容改进选项 Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); configuration.setDefaultEncoding("utf-8"); // 设置模板加载器,加载模板文件 configuration.setTemplateLoader(new ClassTemplateLoader(getClass(), basePackagePath)); Template t = configuration.getTemplate(templateFileName, "utf-8"); // 使用 URLEncoder 对文件名进行编码,以防止中文文件名在不同浏览器和操作系统下出现乱码问题 // String encodedFileName = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "utf-8"); String encodedFileName =fileName ; // 定义保存文件的路径 File saveDir = new File(saveDirectory); if (!saveDir.exists()) { saveDir.mkdirs(); } // 定义文件名 String filePath = saveDir.getAbsolutePath() + File.separator + encodedFileName + ".doc"; // 创建 Writer 对象,用于将生成的文档写到文件中,缓存区大小设为 10KB Writer out = new BufferedWriter(new FileWriter(filePath), 10240); // 将模型数据与模板结合生成 Word 文档,写入到 Writer 对象中 t.process(templateParam, out); out.close(); File file = new File(filePath); // 检查文件是否存在 if (!file.exists()) { throw new FileNotFoundException("文件不存在: " + filePath); } // 读取文件内容 byte[] fileContent = new byte[(int) file.length()]; try (FileInputStream fis = new FileInputStream(file)) { fis.read(fileContent); } String test = pdfUtils.test(encodedFileName + ".doc"); // MultipartFile mockMultipartFile = new MockMultipartFile(encodedFileName+".doc", fileContent); // String s = ObsUploadUtil.obsUpload(mockMultipartFile); return test; } catch (IOException | TemplateException e) { log.error("生成pdf异常,异常原因:{}", e.getMessage(), e); throw new RuntimeException("生成pdf异常,异常原因:" + e.getMessage()); } } } ruoyi-admin/src/main/resources/template/1_yzj_租赁合同.xml
New file Diff too large ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TContractController.java
@@ -1,22 +1,30 @@ package com.ruoyi.web.controller.api; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.dto.SignContractDTO; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.TContractRentType; import com.ruoyi.system.model.THouse; import com.ruoyi.system.query.TContractAppletQuery; import com.ruoyi.system.query.TContractQuery; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TContractRentTypeService; import com.ruoyi.system.service.TContractService; import com.ruoyi.system.service.THouseService; import com.ruoyi.system.vo.TContractVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; /** * <p> @@ -27,6 +35,8 @@ * @since 2025-01-17 */ @RestController @Api(tags = "我的合同") @RequestMapping("/t-contract") public class TContractController { @Autowired @@ -37,21 +47,42 @@ private THouseService houseService; @Autowired private TBillService billService; @Autowired private TokenService tokenService; @ApiOperation(value = "签订合同") @PostMapping(value = "/signContract") public R signContract(@RequestBody SignContractDTO dto) { TContract contract = contractService.getById(dto.getId()); if (contract==null)return R.fail("合同不存在"); if (contract.getStatus()==4)return R.fail("该合同已签订"); contract.setSignature(dto.getSignature()); contract.setStatus(2); contractService.updateById(contract); return R.ok(); return contractService.signContract(dto); } @ApiOperation(value = "我的合同") @ApiOperation(value = "我的合同分页列表") @PostMapping(value = "/contractList") public R<PageInfo<TContract>> contractList(@RequestBody TContractQuery query) { return R.ok(contractService.contractList(query)); public R<PageInfo<TContract>> contractList(@RequestBody TContractAppletQuery query) { // todo 获取登陆人id return R.ok(contractService.contractAppletList(query)); } @ApiOperation(value = "查询合同信息信息") @GetMapping(value = "/getContractById") public R<TContractVO> getContractById(@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); return R.ok(res); } } ruoyi-common/pom.xml
@@ -19,8 +19,22 @@ <swagger.core.version>1.6.2</swagger.core.version> </properties> <dependencies> <dependency> <groupId>com.documents4j</groupId> <artifactId>documents4j-local</artifactId> <version>1.0.3</version> </dependency> <dependency> <groupId>com.documents4j</groupId> <artifactId>documents4j-transformer-msoffice-word</artifactId> <version>1.0.3</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.33</version> </dependency> <!-- Spring框架基本的核心工具 --> <dependency> <groupId>org.springframework</groupId> ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java
@@ -15,4 +15,28 @@ * 租户类型 */ public static final String DICT_TYPE_TENANT_TYPE = "t_tenant_type"; /** * 租赁状态 1=待出租 2=已出租 3=维修中 */ public static final String DICT_TYPE_LEASE_STATUS = "t_lease_status"; /** * 租金支付方式 1=月付 季付 年付 */ public static final String DICT_TYPE_CONTRACT_PAY_TYPE = "t_contract_pay_type"; /** * 业务属性 1住宅2商业3工业4车位5办公6仓储 */ public static final String DICT_TYPE_BUSINESS_ATTRIBUTES = "t_business_attributes"; /** * 合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算 */ public static final String DICT_TYPE_CONTRACT_STATUS = "t_contract_status"; /** * 验收状态 1=待验收 2=已验收 */ public static final String DICT_TYPE_CHECK_STATUS = "t_check_status"; /** * 缴费状态 1=未缴费 2=待确认 3=已缴费 4=已逾期 5=已失效 */ public static final String DICT_TYPE_PAY_FEES_STATUS = "t_pay_fees_status"; } ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
@@ -340,6 +340,16 @@ DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); return df.format(time); } /** * localdatetime转为字符串 * * @param time localdatetime * @return 字符串 */ public static String localDateTimeToStringYear(LocalDateTime time) { DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); return df.format(time); } /** * Date转为LocalDateTime ruoyi-system/src/main/java/com/ruoyi/system/dto/TerminateContractDTO.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.system.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @Data @ApiModel(value = "终止合同DTO") public class TerminateContractDTO implements Serializable { @ApiModelProperty(value = "合同id") private String id; @ApiModelProperty(value = "备注说明") private String terminateRemark; } ruoyi-system/src/main/java/com/ruoyi/system/export/ContractExport.java
New file @@ -0,0 +1,51 @@ package com.ruoyi.system.export; import cn.afterturn.easypoi.excel.annotation.Excel; import io.swagger.annotations.ApiModel; import lombok.Data; import java.io.Serializable; import java.time.LocalDateTime; import java.util.Date; @Data @ApiModel(value = "光缆巡检导出excel") public class ContractExport implements Serializable { @Excel(name = "合同编号",width = 30) private String contractNumber; @Excel(name = "合同名称",width = 30) private String contractName; @Excel(name = "甲方名称",width = 30) private String partyOneName; @Excel(name = "乙方名称",width = 30) private String partyTwoName; @Excel(name = "创建时间",width = 30,exportFormat = "yyyy-MM-dd") private LocalDateTime create_time; @Excel(name = "生效日期",width = 30,exportFormat = "yyyy-MM-dd") private LocalDateTime startTime; @Excel(name = "终止日期",width = 30,exportFormat = "yyyy-MM-dd") private LocalDateTime endTime; @Excel(name = "租金支付方式",width = 30) private String payType; @Excel(name = "押金",width = 30) private String deposit; @Excel(name = "状态",width = 30) private String status; // @Excel(name = "计划周期",width = 30,replace = {"周计划_1","月计划_2"}) // private Integer planCycle; } ruoyi-system/src/main/java/com/ruoyi/system/mapper/TContractMapper.java
@@ -3,7 +3,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TContract; import com.ruoyi.system.query.TContractAppletQuery; import com.ruoyi.system.query.TContractBillQuery; import com.ruoyi.system.query.TContractQuery; import com.ruoyi.system.vo.BillVO; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -19,4 +22,10 @@ public interface TContractMapper extends BaseMapper<TContract> { List<TContract> contractList(@Param("query") TContractQuery query, @Param("pageInfo") PageInfo<TContract> pageInfo); List<TContract> contractAppletList(@Param("query")TContractAppletQuery query, @Param("pageInfo") PageInfo<TContract> pageInfo); List<BillVO> contractBillList(@Param("query") TContractBillQuery query, @Param("pageInfo") PageInfo<BillVO> pageInfo); List<TContract> contractExportList(@Param("query")TContractQuery query); } ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java
@@ -49,13 +49,13 @@ private BigDecimal payableFeesMoney; @ApiModelProperty(value = "应缴费日期") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") @TableField("payable_fees_time") private LocalDateTime payableFeesTime; @ApiModelProperty(value = "缴费状态 1=未缴费 2=待确认 3=已缴费 4=已逾期") @ApiModelProperty(value = "缴费状态 1=未缴费 2=待确认 3=已缴费 4=已逾期 5= 已失效") @TableField("pay_fees_status") private Integer payFeesStatus; private String payFeesStatus; @ApiModelProperty(value = "缴费金额") @TableField("pay_fees_money") @@ -72,7 +72,7 @@ @ApiModelProperty(value = "账单类型 1=租金 2=押金 3=生活费用") @TableField("bill_type") private Integer billType; private String billType; @ApiModelProperty(value = "逾期天数") @TableField("over_days") ruoyi-system/src/main/java/com/ruoyi/system/model/TCheckAcceptRecord.java
@@ -86,10 +86,13 @@ @ApiModelProperty(value = "验收结果 1=合格 2=不合格") @TableField("check_result") private Integer checkResult; private Boolean checkResult; @ApiModelProperty(value = "验收结算金额") @TableField("check_money") private BigDecimal checkMoney; @ApiModelProperty(value = "验收状态 待验收 已验收") @TableField("status") private String status; } ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java
@@ -53,30 +53,30 @@ @TableField("end_time") private LocalDateTime endTime; @ApiModelProperty(value = "合计租金") @TableField("total_rent") private BigDecimal totalRent; @ApiModelProperty(value = "每月租金") @TableField("month_rent") private BigDecimal monthRent; @ApiModelProperty(value = "押金") @TableField("deposit") private BigDecimal deposit; @ApiModelProperty(value = "租金支付方式 1=月付 2=季付 3=年付") @ApiModelProperty(value = "租金支付方式 月付 季付 年付") @TableField("pay_type") private Integer payType; private String payType; @ApiModelProperty(value = "第一次支付日期") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @TableField("first_pay_time") private LocalDateTime firstPayTime; @ApiModelProperty(value = "是否递增递减 1=是 0=否") @ApiModelProperty(value = "是否递增递减 true=是 false=否") @TableField("isIncreasing") private Integer isIncreasing; private Boolean isIncreasing; @ApiModelProperty(value = "押金是否随租金递增递减 1=是 0=否") @ApiModelProperty(value = "押金是否随租金递增递减 true=是 false=否") @TableField("isIncreasing_deposit") private Integer isincreasingDeposit; private Boolean isincreasingDeposit; @ApiModelProperty(value = "违约金比例") @TableField("proportion") @@ -122,9 +122,9 @@ @TableField("remark") private String remark; @ApiModelProperty(value = "状态 1=待提交 2=待审批 3=未签订 4=已签订") @ApiModelProperty(value = "状态 待提交 待审批 未签订 已签订....") @TableField("status") private Integer status; private String status; @ApiModelProperty(value = "内存大小多个文件逗号拼接") @TableField("memory") private String memory; @@ -134,5 +134,11 @@ @ApiModelProperty(value = "租户确认合同电子签名") @TableField("signature") private String signature; @ApiModelProperty(value = "终止合同备注说明") @TableField("terminate_remark") private String terminateRemark; @ApiModelProperty(value = "合计年租金") @TableField("total_year") private BigDecimal totalYear; } ruoyi-system/src/main/java/com/ruoyi/system/model/THouse.java
@@ -80,7 +80,7 @@ @ApiModelProperty(value = "租赁状态 1=待出租 2=已出租 3=维修中") @TableField("lease_status") private Integer leaseStatus; private String leaseStatus; @ApiModelProperty(value = "楼栋") @TableField("building") private String building; @@ -90,5 +90,5 @@ @ApiModelProperty(value = "住户类型 1月租 2季租 3年租") @TableField(exist = false) private Integer tenantType; private String tenantType; } ruoyi-system/src/main/java/com/ruoyi/system/query/TContractAppletQuery.java
@@ -11,4 +11,6 @@ @ApiModelProperty(value = "全部不传 3=待签订 4=已签订") private Integer status; @ApiModelProperty(value = "租户id 前端忽略") private String tenantId; } ruoyi-system/src/main/java/com/ruoyi/system/query/TContractBillQuery.java
New file @@ -0,0 +1,14 @@ package com.ruoyi.system.query; import com.ruoyi.common.core.domain.BasePage; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "终止合同分页列表查询Query") public class TContractBillQuery extends BasePage { @ApiModelProperty(value = "合同id") private String id; } ruoyi-system/src/main/java/com/ruoyi/system/service/TContractService.java
@@ -2,8 +2,17 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.R; import com.ruoyi.system.dto.SignContractDTO; import com.ruoyi.system.dto.TerminateContractDTO; import com.ruoyi.system.model.TContract; import com.ruoyi.system.query.TContractAppletQuery; import com.ruoyi.system.query.TContractBillQuery; import com.ruoyi.system.query.TContractQuery; import com.ruoyi.system.vo.BillVO; import com.ruoyi.system.vo.CheckAcceptRecordVO; import java.util.List; /** * <p> @@ -16,4 +25,19 @@ public interface TContractService extends IService<TContract> { PageInfo<TContract> contractList(TContractQuery query); PageInfo<TContract> contractAppletList(TContractAppletQuery query); PageInfo<BillVO> contractBillList(TContractBillQuery query); void terminateContract(TerminateContractDTO dto); CheckAcceptRecordVO getCheckByContractId(String id); R signContract(SignContractDTO dto); void export(TContractQuery query); List<TContract> contractExportList(TContractQuery query); } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java
@@ -1,14 +1,33 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.system.dto.SignContractDTO; import com.ruoyi.system.dto.TerminateContractDTO; import com.ruoyi.system.mapper.TBillMapper; import com.ruoyi.system.mapper.TCheckAcceptRecordMapper; import com.ruoyi.system.mapper.TContractMapper; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.TTenant; import com.ruoyi.system.mapper.THouseMapper; import com.ruoyi.system.model.*; import com.ruoyi.system.query.TContractAppletQuery; import com.ruoyi.system.query.TContractBillQuery; import com.ruoyi.system.query.TContractQuery; import com.ruoyi.system.service.TBillService; import com.ruoyi.system.service.TContractService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.system.vo.BillVO; import com.ruoyi.system.vo.CheckAcceptRecordVO; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.List; /** @@ -21,13 +40,148 @@ */ @Service public class TContractServiceImpl extends ServiceImpl<TContractMapper, TContract> implements TContractService { @Resource private TCheckAcceptRecordMapper checkAcceptRecordMapper; @Resource private THouseMapper houseMapper; @Resource private TBillMapper billMapper; @Resource private TBillService billService; @Resource private TContractMapper contractMapper; @Override public PageInfo<TContract> contractList(TContractQuery query) { PageInfo<TContract> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TContract> list = this.baseMapper.contractList(query,pageInfo); for (TContract tContract : list) { tContract.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,tContract.getPayType())); tContract.setStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS,tContract.getStatus())); } pageInfo.setRecords(list); return pageInfo; } @Override public PageInfo<TContract> contractAppletList(TContractAppletQuery query) { PageInfo<TContract> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TContract> list = this.baseMapper.contractAppletList(query,pageInfo); for (TContract tContract : list) { tContract.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,tContract.getPayType())); tContract.setStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_STATUS,tContract.getStatus())); } pageInfo.setRecords(list); return pageInfo; } @Override public PageInfo<BillVO> contractBillList(TContractBillQuery query) { PageInfo<BillVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<BillVO> list = this.baseMapper.contractBillList(query,pageInfo); for (BillVO billVO : list) { if (billVO.getPayFeesStatus().equals("4")){ billVO.setPayFeesMoneyString((billVO.getPayFeesMoney().add(billVO.getPayableFeesPenalty()))+"【"+billVO.getPayFeesMoney()+"+"+billVO.getPayableFeesPenalty()+"】"); } billVO.setPayFeesStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_PAY_FEES_STATUS,billVO.getPayFeesStatus())); } pageInfo.setRecords(list); return pageInfo; } @Override public void terminateContract(TerminateContractDTO dto) { TContract contract = this.baseMapper.selectById(dto.getId()); contract.setTerminateRemark(dto.getTerminateRemark()); contract.setStatus("4"); this.baseMapper.updateById(contract); // 生成验收记录 TCheckAcceptRecord tCheckAcceptRecord = new TCheckAcceptRecord(); tCheckAcceptRecord.setContractId(dto.getId()); tCheckAcceptRecord.setHouseId(contract.getHouseId()); tCheckAcceptRecord.setLeaseReason("后台终止"); tCheckAcceptRecord.setStatus("1"); checkAcceptRecordMapper.insert(tCheckAcceptRecord); // 将所有未缴费账单设置未已失效 List<TBill> tBills = billMapper.selectList(new LambdaQueryWrapper<TBill>() .in(TBill::getPayFeesStatus, Arrays.asList("1,4")) .eq(TBill::getContractId, dto.getId())); for (TBill tBill : tBills) { tBill.setPayFeesStatus("5"); } billService.updateBatchById(tBills); } @Override public CheckAcceptRecordVO getCheckByContractId(String id) { CheckAcceptRecordVO checkAcceptRecordVO = new CheckAcceptRecordVO(); TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordMapper.selectOne(new LambdaQueryWrapper<TCheckAcceptRecord>() .eq(TCheckAcceptRecord::getContractId, id)); BeanUtils.copyProperties(tCheckAcceptRecord,checkAcceptRecordVO); THouse tHouse = houseMapper.selectById(tCheckAcceptRecord.getHouseId()); tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus())); tHouse.setBusinessAttributes(DictUtils.getDictLabel(DictConstants.DICT_TYPE_BUSINESS_ATTRIBUTES,tHouse.getBusinessAttributes())); checkAcceptRecordVO.setHouse(tHouse); return checkAcceptRecordVO; } @Override public R signContract(SignContractDTO dto) { TContract contract = contractMapper.selectById(dto.getId()); if (contract==null)return R.fail("合同不存在"); if (contract.getStatus().equals("4"))return R.fail("该合同已签订"); contract.setSignature(dto.getSignature()); contract.setStatus("2"); contractMapper.updateById(contract); // 用户签订合同后 生成第一批账单包含租金账单和押金账单 后续账单通过定时任务生成 TBill rent = new TBill(); rent.setContractId(contract.getId()); // 应缴费租金 BigDecimal payableFeesMoney = new BigDecimal("0"); LocalDateTime startTime = contract.getStartTime(); LocalDateTime endTime = contract.getEndTime(); // // 计算相差多少天 // long days = ChronoUnit.DAYS.between(startTime, endTime); // // 计算相差多少个月 // long months = ChronoUnit.MONTHS.between(startTime, endTime); // if (months<=31){ // // 小于等于一个月 合计租金就是首笔账单金额 // payableFeesMoney = contract.getTotalRent(); // }else{ // switch (contract.getPayType()){ // case "1": // break; // case "2": // break; // case "3": // break; // } // } // // rent.setPayableFeesMoney(payableFeesMoney); // rent.setPayableFeesTime(contract.getFirstPayTime()); // rent.setPayFeesStatus("1"); // rent.setBillType("1"); // // TBill deposit = new TBill(); // deposit.setContractId(contract.getId()); // deposit.setPayableFeesMoney(contract.getDeposit()); // deposit.setPayableFeesTime(contract.getFirstPayTime()); // deposit.setPayFeesStatus("1"); // deposit.setBillType("2"); return R.ok(); } @Override public void export(TContractQuery query) { } @Override public List<TContract> contractExportList(TContractQuery query) { List<TContract> list = this.baseMapper.contractExportList(query); return list; } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java
@@ -2,6 +2,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.system.mapper.TContractMapper; import com.ruoyi.system.mapper.THouseMapper; import com.ruoyi.system.model.TContract; @@ -38,9 +40,11 @@ .le(TContract::getStartTime, LocalDateTime.now()) .ge(TContract::getEndTime, LocalDateTime.now())); for (THouse tHouse : list) { tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus())); tHouse.setBusinessAttributes(DictUtils.getDictLabel(DictConstants.DICT_TYPE_BUSINESS_ATTRIBUTES,tHouse.getBusinessAttributes())); TContract tContract = tContracts.stream().filter(e -> e.getHouseId().equals(tHouse.getId())).findFirst().orElse(null); if (tContract!=null){ tHouse.setTenantType(tContract.getPayType()); tHouse.setTenantType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,tContract.getPayType())); } } pageInfo.setRecords(list); @@ -51,6 +55,9 @@ public PageInfo<HouseVO> userHistoryList(TUserHistoryQuery query) { PageInfo<HouseVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<HouseVO> list = this.baseMapper.userHistoryList(query,pageInfo); for (HouseVO houseVO : list) { houseVO.setBusinessAttributes(DictUtils.getDictLabel(DictConstants.DICT_TYPE_BUSINESS_ATTRIBUTES,houseVO.getBusinessAttributes())); } pageInfo.setRecords(list); return pageInfo; } ruoyi-system/src/main/java/com/ruoyi/system/vo/BillVO.java
New file @@ -0,0 +1,28 @@ package com.ruoyi.system.vo; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.system.model.TBill; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.time.LocalDateTime; @Data @ApiModel(value = "终止合同-未缴费帐单列表VO") public class BillVO extends TBill { @ApiModelProperty(value = "合同编号") private String contractNumber; @ApiModelProperty(value = "租户姓名") private String residentName; @ApiModelProperty(value = "联系电话") private String phone; @ApiModelProperty(value = "当缴费状态为已逾期 使用该字段作为应缴费金额") private String payFeesMoneyString; } ruoyi-system/src/main/java/com/ruoyi/system/vo/CheckAcceptRecordVO.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.system.vo; import com.ruoyi.system.model.TBill; import com.ruoyi.system.model.TCheckAcceptRecord; import com.ruoyi.system.model.THouse; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "房屋验收记录VO") public class CheckAcceptRecordVO extends TCheckAcceptRecord { @ApiModelProperty(value = "房屋信息") private THouse house; } ruoyi-system/src/main/java/com/ruoyi/system/vo/TContractVO.java
@@ -1,10 +1,8 @@ package com.ruoyi.system.vo; import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.system.model.TContract; import com.ruoyi.system.model.THouse; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -32,4 +30,8 @@ @ApiModelProperty(value = "房屋信息") private THouse house; @ApiModelProperty(value = "当前未缴费账单金额") private BigDecimal payMoney; @ApiModelProperty(value = "房屋验收结果") private Boolean checkResult; } ruoyi-system/src/main/resources/mapper/system/TContractMapper.xml
@@ -9,7 +9,7 @@ <result column="contract_name" property="contractName" /> <result column="start_time" property="startTime" /> <result column="end_time" property="endTime" /> <result column="total_rent" property="totalRent" /> <result column="month_rent" property="monthRent" /> <result column="deposit" property="deposit" /> <result column="pay_type" property="payType" /> <result column="first_pay_time" property="firstPayTime" /> @@ -32,13 +32,18 @@ <result column="create_by" property="createBy" /> <result column="update_by" property="updateBy" /> <result column="disabled" property="disabled" /> <result column="memory" property="memory" /> <result column="contract_file_name" property="contractFileName" /> <result column="signature" property="signature" /> <result column="terminate_remark" property="terminateRemark" /> <result column="total_year" property="totalYear" /> </resultMap> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> id, contract_number, contract_name, start_time, end_time, total_rent, deposit, pay_type, first_pay_time, isIncreasing, isIncreasing_deposit, proportion, house_id, party_one_name, party_one_person, party_one_phone, tenant_id, party_two_name, party_two_person, party_two_phone, contract_file, remark, status, create_time, update_time, create_by, update_by, disabled memory, contract_file_name, signature, terminate_remark, total_year </sql> <select id="contractList" resultType="com.ruoyi.system.model.TContract"> select t1.* from t_contract t1 @@ -59,5 +64,39 @@ </where> </select> <select id="contractAppletList" resultType="com.ruoyi.system.model.TContract"> select t1.* from t_contract t1 <where> <if test="query.status != null"> and t1.status = #{query.status} </if> <if test="query.tenantId != null"> and t1.tenant_id = #{query.tenantId} </if> AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} </where> </select> <select id="contractBillList" resultType="com.ruoyi.system.vo.BillVO"> select t1.*,t2.contract_number as contractNumber,t3.resident_name as residentName,t3.phone as phone from t_bill t1 left join t_contract t2 on t1.contract_id = t2.id left join t_resident t3 on t2.tenant_id = t3.id where t2.id = #{query.id} and (t1.pay_fees_status = 1 or t1.pay_fees_status = 4) AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} AND t2.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} AND t3.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} </select> <select id="contractExportList" resultType="com.ruoyi.system.model.TContract"> select t1.*,t2.contract_number as contractNumber,t3.resident_name as residentName,t3.phone as phone from t_bill t1 left join t_contract t2 on t1.contract_id = t2.id left join t_resident t3 on t2.tenant_id = t3.id where t2.id = #{query.id} and (t1.pay_fees_status = 1 or t1.pay_fees_status = 4) AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} AND t2.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} AND t3.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} </select> </mapper>