| | |
| | | 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.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.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 org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.Arrays; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | 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) { |
| | |
| | | @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()); |
| | |
| | | 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()); |
| | |
| | | @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(","))); |
| | |
| | | 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); |
| | |
| | | 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); |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | 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> |
| | |
| | | @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 = "删除房屋") |
| | |
| | | |
| | | 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; |
| | |
| | | @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); |
| | | } |
| | | |
| | | /** |
New file |
| | |
| | | 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)); // 输出: 壹佰元整 |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | 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> |
| | |
| | | * @since 2025-01-17 |
| | | */ |
| | | @RestController |
| | | @Api(tags = "我的合同") |
| | | |
| | | @RequestMapping("/t-contract") |
| | | public class TContractController { |
| | | @Autowired |
| | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | |
| | | <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> |
| | |
| | | * 租户类型 |
| | | */ |
| | | 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"; |
| | | } |
| | |
| | | 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 |
New file |
| | |
| | | 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; |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | 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); |
| | | |
| | | } |
| | |
| | | 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") |
| | |
| | | |
| | | @ApiModelProperty(value = "账单类型 1=租金 2=押金 3=生活费用") |
| | | @TableField("bill_type") |
| | | private Integer billType; |
| | | private String billType; |
| | | |
| | | @ApiModelProperty(value = "逾期天数") |
| | | @TableField("over_days") |
| | |
| | | |
| | | @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; |
| | | |
| | | } |
| | |
| | | @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") |
| | |
| | | @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; |
| | |
| | | @ApiModelProperty(value = "租户确认合同电子签名") |
| | | @TableField("signature") |
| | | private String signature; |
| | | @ApiModelProperty(value = "终止合同备注说明") |
| | | @TableField("terminate_remark") |
| | | private String terminateRemark; |
| | | @ApiModelProperty(value = "合计年租金") |
| | | @TableField("total_year") |
| | | private BigDecimal totalYear; |
| | | |
| | | } |
| | |
| | | |
| | | @ApiModelProperty(value = "租赁状态 1=待出租 2=已出租 3=维修中") |
| | | @TableField("lease_status") |
| | | private Integer leaseStatus; |
| | | private String leaseStatus; |
| | | @ApiModelProperty(value = "楼栋") |
| | | @TableField("building") |
| | | private String building; |
| | |
| | | |
| | | @ApiModelProperty(value = "住户类型 1月租 2季租 3年租") |
| | | @TableField(exist = false) |
| | | private Integer tenantType; |
| | | private String tenantType; |
| | | } |
| | |
| | | |
| | | @ApiModelProperty(value = "全部不传 3=待签订 4=已签订") |
| | | private Integer status; |
| | | @ApiModelProperty(value = "租户id 前端忽略") |
| | | private String tenantId; |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | |
| | | |
| | | 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; |
| | | |
| | | /** |
| | | * <p> |
| | |
| | | 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); |
| | | |
| | | } |
| | |
| | | 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; |
| | | |
| | | /** |
| | |
| | | */ |
| | | @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(); |
| | | } |
| | | } |
| | |
| | | |
| | | 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; |
| | |
| | | .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); |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | |
| | | @ApiModelProperty(value = "房屋信息") |
| | | private THouse house; |
| | | @ApiModelProperty(value = "当前未缴费账单金额") |
| | | private BigDecimal payMoney; |
| | | @ApiModelProperty(value = "房屋验收结果") |
| | | private Boolean checkResult; |
| | | } |
| | |
| | | <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" /> |
| | |
| | | <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 |
| | | id, contract_number, contract_name, start_time, end_time, month_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 |
| | |
| | | |
| | | </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> |
| | | |
| | | </mapper> |