From 96a7015065775e5c3bc3d6458b86b28ad7bfb46b Mon Sep 17 00:00:00 2001 From: yupeng <roc__yu@163.com> Date: 星期四, 13 三月 2025 17:53:32 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' into xizang-changyun --- ruoyi-admin/src/main/resources/application-test.yml | 2 ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseVO.java | 2 ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java | 2 ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java | 41 ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessTaskListVO.java | 5 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java | 22 ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml | 24 ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java | 2 ruoyi-system/src/main/java/com/ruoyi/system/task/jobs/StateProcessJob.java | 2 ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java | 13 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java | 247 ++++ ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml | 7 ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java | 5 ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java | 92 ++ ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java | 47 + ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java | 25 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java | 7 ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java | 187 +-- ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java | 3 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java | 2 ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java | 4 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java | 10 ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java | 4 ruoyi-system/src/main/resources/mapper/system/StateTaskCenterMapper.xml | 2 ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml | 21 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java | 5 ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml | 3 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java | 4 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordPdfGenerator.java | 106 ++ ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java | 59 + ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/MyFileUtil.java | 128 ++ ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java | 114 + ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java | 461 ++++++++++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java | 498 ----------- ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java | 87 + ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java | 2 ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java | 4 ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java | 18 ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java | 313 ++++++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java | 18 40 files changed, 1,838 insertions(+), 760 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java index 5a0e81a..8a363c6 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TContractController.java @@ -92,11 +92,13 @@ @PostMapping(value = "/addContract") @PreAuthorize("@ss.hasPermi('contract:list:add')") public R<Boolean> addContract(@Validated @RequestBody TContractDTO dto) { + LocalDateTime changeTime = dto.getChangeTime(); long count = contractService.count(new LambdaQueryWrapper<TContract>().eq(TContract::getContractNumber, dto.getContractNumber())); if (count!=0){ return R.fail("合同编号不可重复"); } dto.setChangeRent(dto.getMonthRent()); + dto.setChangeTime(null); contractService.save(dto); if (dto.getStatus().equals("2")){ //发起合同新增审批 @@ -134,7 +136,7 @@ tContractRentType.setIncreasingDecreasing(dto.getIncreasingDecreasing()); tContractRentType.setIncreasingDecreasingType(dto.getIncreasingDecreasingType()); tContractRentType.setNumericalValue(dto.getNumericalValue()); - tContractRentType.setChangeTime(dto.getChangeTime()); + tContractRentType.setChangeTime(changeTime); tContractRentType.setCycleTime(dto.getCycleTime()); contractRentTypeService.save(tContractRentType); } @@ -145,6 +147,7 @@ @PostMapping(value = "/updateContract") @PreAuthorize("@ss.hasPermi('contract:list:edit')") public R<Boolean> updateContract(@Validated @RequestBody TContractDTO dto) { + dto.setChangeTime(null); contractService.updateById(dto); contractRentTypeService.remove(new LambdaQueryWrapper<TContractRentType>() .eq(TContractRentType::getContractId,dto.getId())); @@ -157,6 +160,36 @@ tContractRentType.setChangeTime(dto.getChangeTime()); tContractRentType.setCycleTime(dto.getCycleTime()); contractRentTypeService.save(tContractRentType); + } + if (dto.getStatus().equals("2")){ + //发起合同新增审批 + ProcessStartBO processStartBO = new ProcessStartBO(); + processStartBO.setCategory(ProcessCategoryEnum.CATEGORY1.getValue().toString()); + processStartBO.setModuleName("合同新增审批"); + processStartBO.setName(dto.getContractName()); + //需要显示发起申请人所在单位 +// String cedName = SecurityUtils.getLoginUser().getUser().getDept().getDeptName(); +// String remark = String.format("【镇/街】:%s,【征收实施单位】:%s,【申请金额】:%s万元", stateProject.getStreet(), cedName, stateApplyRecord.getAmount()); + processStartBO.setRemark(""); + Map<String, Object> variable = new HashMap<>(); + variable.put("projectId", dto.getId()); + processStartBO.setVariable(variable); + //开启工作流程 + Boolean start = stateProcessTemplateService.start(processStartBO); + if(start){ + FlwTask flwTask = flwTaskMapper.selectOne(Wrappers.lambdaQuery(FlwTask.class) + .like(FlwTask::getVariable, dto.getId()) + .orderByDesc(FlwTask::getCreateTime) + .last("LIMIT 1")); + if(Objects.nonNull(flwTask)){ + // 添加定时任务 + Map<String, ? extends Object> maps = + new ImmutableMap.Builder<String, Long>(). + put("id", flwTask.getId()) + .build(); + QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name+flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT,new Date(new Date().getTime()+48*60*60*1000L), maps); + } + } } return R.ok(); } @@ -178,8 +211,6 @@ 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); @@ -194,14 +225,14 @@ res.setHouse(house); List<TBill> list = billService.lambdaQuery() .eq(TBill::getContractId, id) - .in(TBill::getPayFeesStatus, Arrays.asList("1,4")) + .ne(TBill::getPayFeesStatus, 3) .list(); BigDecimal payMoney = new BigDecimal("0"); for (TBill tBill : list) { - payMoney = payMoney.add(tBill.getPayFeesMoney()).add(tBill.getPayableFeesPenalty()); + payMoney = payMoney.add(tBill.getOutstandingMoney()).add(tBill.getPayableFeesPenalty()); } TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery().eq(TCheckAcceptRecord::getContractId, id).one(); - res.setCheckResult(Objects.nonNull(tCheckAcceptRecord)?tCheckAcceptRecord.getCheckResult():false); + res.setCheckResult(Objects.nonNull(tCheckAcceptRecord)&&Objects.nonNull(tCheckAcceptRecord.getCheckResult())?tCheckAcceptRecord.getCheckResult():null); res.setPayMoney(payMoney); return R.ok(res); @@ -228,7 +259,14 @@ TContract contract = contractService.getById(id); contract.setStatus("8"); contractService.updateById(contract); - return R.ok(); + // 将所有未缴费账单设置未已失效 + List<TBill> tBills = billService.list(new LambdaQueryWrapper<TBill>() + .ne(TBill::getPayFeesStatus, 3) + .eq(TBill::getContractId, contract.getId())); + for (TBill tBill : tBills) { + tBill.setPayFeesStatus("5"); + } + billService.updateBatchById(tBills); return R.ok(); } @ApiOperation(value = "终止合同剩余未缴费账单列表") @PostMapping(value = "/contractBillList") @@ -257,31 +295,51 @@ List<TContract> list = contractService.lambdaQuery().in(TContract::getId, dto.getIds()).list(); List<String> res = new ArrayList<>(); for (TContract contract : list) { + TBill firstBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()) + .orderByDesc(TBill::getStartTime).last("limit 1").one(); + 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("${partyOneName}", contract.getPartyOneName()); + templateParam.put("${partyTwoName}", contract.getPartyTwoName()); + templateParam.put("${houseAddress}", tHouse.getHouseAddress()); + templateParam.put("${houseArea}", tHouse.getHouseArea()+"m²"); + long between = ChronoUnit.DAYS.between(contract.getStartTime(), contract.getStartPayTime())+1; + templateParam.put("${day}", between); + templateParam.put("${endTimeFree}", DateUtils.localDateTimeToStringYear(contract.getStartPayTime().plusDays(1))); + templateParam.put("${startPayTime}", DateUtils.localDateTimeToStringYear(contract.getStartPayTime())); + 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())); String totalYear = Objects.nonNull(contract.getTotalYear())?contract.getTotalYear().toString():""; - templateParam.put("totalYear", "¥¥"+totalYear+"元"); + templateParam.put("${totalYear}", "¥"+totalYear+"元"); String totalYearString = StringUtils.isNotEmpty(totalYear)?NumberToChineseUtils.numberToChinese(contract.getTotalYear().setScale(2, BigDecimal.ROUND_DOWN).doubleValue()):""; - templateParam.put("totalYearString", "人民币"+totalYearString); - 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("/template", "1_yzj_租赁合同.xml", templateParam, "租赁合同", "E:\\"); + templateParam.put("${totalYearString}", "人民币"+totalYearString); + templateParam.put("${payType}", contract.getPayType().equals("1")?"月":contract.getPayType().equals("2")?"季":"年"); + if(firstBill!=null){ + templateParam.put("${firstRent}", "¥"+(firstBill.getPayableFeesMoney())+"元"); + }else{ + templateParam.put("${firstRent}", ""); + + } + 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()); + // 验收时间 + TCheckAcceptRecord tCheckAcceptRecord = checkAcceptRecordService.lambdaQuery().eq(TCheckAcceptRecord::getContractId, contract.getId()).last("limit 1").one(); + if (tCheckAcceptRecord!=null &&tCheckAcceptRecord.getCheckTime()!=null ){ + templateParam.put("${checkTime}", DateUtils.localDateTimeToStringYear(tCheckAcceptRecord.getCheckTime())); + }else{ + templateParam.put("${checkTime}", ""); + + } + String url = wordUtil.generatePdf("/usr/local/project/file/", "1_yzj_租赁合同.docx", templateParam, "租赁合同", "/usr/local/project/file/"); res.add(url); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java index fa0e4a9..772f34c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TDeptController.java @@ -61,12 +61,20 @@ /** * 获取部门管理管理列表 */ - @ApiOperation(value = "获取部门管理列表") + @ApiOperation(value = "获取部门管理列表-启用状态") @PostMapping(value = "/list") public R<List<TDept>> list() { return R.ok(deptService.list(Wrappers.lambdaQuery(TDept.class) .eq(TDept::getStatus, 1))); } + /** + * 获取部门管理管理列表 + */ + @ApiOperation(value = "获取部门管理列表-所有状态") + @PostMapping(value = "/listAll") + public R<List<TDept>> listAll() { + return R.ok(deptService.list(Wrappers.lambdaQuery(TDept.class))); + } /** * 添加部门管理管理 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java index ddd4270..d3530a7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFaultDescribeDicController.java @@ -16,6 +16,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.time.LocalDateTime; import java.util.List; /** @@ -67,6 +68,7 @@ @ApiOperation(value = "修改故障描述") @PostMapping(value = "/update") public R<Boolean> update(@Validated @RequestBody TFaultDescribeDic dto) { + dto.setUpdateTime(LocalDateTime.now()); return R.ok(faultDescribeDicService.updateById(dto)); } @@ -101,6 +103,6 @@ public R<Boolean> deleteByIds(@RequestBody List<String> ids) { return R.ok(faultDescribeDicService.removeByIds(ids)); } - + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java index e4755e8..b44867f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -156,7 +156,7 @@ @PostMapping("/add") public AjaxResult add(@Validated @RequestBody SysUser user) { - user.setUserName(user.getPhonenumber()); + user.setUserName(user.getUserName()); if (!userService.checkUserNameUnique(user)) { return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java index 6db2c4f..2fc75ee 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java @@ -1,110 +1,83 @@ -package com.ruoyi.web.controller.task; - - -import com.ruoyi.system.model.TBill; -import com.ruoyi.system.model.TContract; -import com.ruoyi.system.model.TContractRentType; -import com.ruoyi.system.service.TBillService; -import com.ruoyi.system.service.TContractRentTypeService; -import com.ruoyi.system.service.TContractService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; -import java.math.BigDecimal; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAdjusters; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; - -/** - * @author zhibing.pu - * @date 2023/7/11 8:39 - */ -@Component -public class TaskUtil { - @Autowired - private TContractService contractService; - @Autowired - private TBillService billService; - @Autowired - private TContractRentTypeService contractRentTypeService; - - // 每天凌晨00点执行的定时任务 用于生成违约金 - @Scheduled(cron = "0 0 0 * * ?") - public void dayOfProportionBill() { - try { - // 查询所有未缴费账单 - List<TBill> list = billService.lambdaQuery().eq(TBill::getPayFeesStatus, 1).list(); - for (TBill tBill : list) { - TContract contract = contractService.getById(tBill.getContractId()); - LocalDate payableFeesTime = tBill.getPayableFeesTime(); - LocalDateTime now = LocalDateTime.now(); - // 计算两个时间相差多少个小时 - long hours = ChronoUnit.HOURS.between(payableFeesTime, now); - long l = hours / 72; - if (l>0){ - // 违约金比例 - BigDecimal proportion = contract.getProportion(); - // 应缴违约金 - BigDecimal money = tBill.getOutstandingMoney().multiply(proportion); - TBill changeBill = new TBill(); - changeBill.setId(tBill.getId()); - changeBill.setPayableFeesPenalty(money); - billService.lockAndUpdateInfo(changeBill,2); - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - - - // 每天凌晨00点执行的定时任务 根据应缴费日期修改账单状态 - @Scheduled(cron = "0 0 0 * * ?") - public void dayOfEndBill() { - try { - List<TBill> list = billService.lambdaQuery().eq(TBill::getPayFeesStatus, "2").list(); - for (TBill tBill : list) { - if (tBill.getPayableFeesTime().equals(LocalDate.now())){ - tBill.setPayFeesStatus("1"); - } - } - billService.updateBatchById(list); - } catch (Exception e) { - e.printStackTrace(); - } - } - - - - - public static void main(String[] args) { - -// LocalDateTime now = LocalDateTime.now().minusMonths(1).withDayOfMonth(31); -// System.err.println(now); -// LocalDateTime now2 = now.plusMonths(1); -// System.err.println(now2); +//package com.ruoyi.web.controller.task; // -// LocalDateTime now1 = LocalDateTime.now(); -// long days = ChronoUnit.DAYS.between(now, now1); -// long days2 = ChronoUnit.DAYS.between(now.plusDays(1), now1); // -// System.err.println(days); -// System.err.println(days2); -// LocalDateTime endTime = now.with(TemporalAdjusters.lastDayOfMonth()).withSecond(59).withHour(23).withMinute(59); +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.ruoyi.common.utils.SmsUtil; +//import com.ruoyi.system.mapper.TBillMapper; +//import com.ruoyi.system.model.TBill; +//import com.ruoyi.system.model.TContract; +//import com.ruoyi.system.model.TContractRentType; +//import com.ruoyi.system.service.TBillService; +//import com.ruoyi.system.service.TContractRentTypeService; +//import com.ruoyi.system.service.TContractService; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.scheduling.annotation.Scheduled; +//import org.springframework.stereotype.Component; // -// System.err.println(endTime); - - } - -} +//import javax.annotation.Resource; +//import java.math.BigDecimal; +//import java.time.LocalDate; +//import java.time.LocalDateTime; +//import java.time.LocalTime; +//import java.time.ZoneId; +//import java.time.temporal.ChronoUnit; +//import java.time.temporal.TemporalAdjusters; +//import java.util.ArrayList; +//import java.util.Date; +//import java.util.List; +//import java.util.Random; +//import java.util.stream.Collectors; +// +///** +// * @author zhibing.pu +// * @date 2023/7/11 8:39 +// */ +//@Component +//public class TaskUtil { +// @Autowired +// private TContractService contractService; +// @Autowired +// private TBillMapper billMapper; +// // 用于更新违约金账单 +// // 每分钟执行一次的定时任务 +// +// @Scheduled(cron = "0 * * * * ?") +// public void dayOfProportionBill() { +// try { +// // 查询所有未缴费账单 +// List<TBill> list = billMapper.selectList(new LambdaQueryWrapper<TBill>().eq(TBill::getPayFeesStatus, 1) +// .le(TBill::getPayableFeesTime,LocalDate.now())); +// for (TBill tBill : list) { +// tBill.setPayFeesStatus("4"); +// TContract contract = contractService.getById(tBill.getContractId()); +// LocalDate payableFeesTime = tBill.getPayableFeesTime(); +// // 将LocalDate转化为LocalDateTime +// LocalDateTime payableFeesTime1 = LocalDateTime.of(payableFeesTime, LocalTime.of(0, 0, 0)); +// LocalDateTime now = LocalDateTime.now(); +// // 计算两个时间相差多少个小时 +// long hours = ChronoUnit.HOURS.between(payableFeesTime1, now); +// long l = hours / 24; +// if (l>=3){ +// // 违约金比例 +// BigDecimal proportion = contract.getProportion(); +// // 按每天 待缴费金额 * XX% 增加违约金费用 +// if (tBill.getOutstandingMoney().compareTo(new BigDecimal("0"))==0){ +// tBill.setPayFeesStatus("3"); +// billMapper.updateById(tBill); +// continue; +// } +// BigDecimal money = tBill.getOutstandingMoney().multiply(new BigDecimal(100).add(proportion)).divide(new BigDecimal(100),2, BigDecimal.ROUND_DOWN); +// tBill.setOverDays((int) l); +// tBill.setPayableFeesPenalty((tBill.getPayableFeesPenalty()!=null?tBill.getPayableFeesPenalty():BigDecimal.ZERO).add(money)); +// tBill.setOutstandingMoney(money); +// billMapper.updateById(tBill); +// +// } +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// +//} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java index c786d9b..ba43f3f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/PdfUtils.java @@ -4,6 +4,7 @@ import com.documents4j.api.IConverter; import com.documents4j.job.LocalConverter; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.xwpf.usermodel.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Component; @@ -11,7 +12,13 @@ import java.io.*; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; @Slf4j @Component @@ -21,47 +28,223 @@ /** * word 转 pdf * - * @param url */ - public String wordToPdf(String url,String filePath, String fileName) { +// 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,"/wordToPdf"); +// +// stream.close(); +// inputStream.close(); +// return s; +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return null; +// } + + public String wordToPdf(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; + // 确保路径正确性 + String inputFile = new File(filePath, fileName).getAbsolutePath(); + String outputDir = new File(filePath, "pdf").getAbsolutePath(); + + // 创建输出目录 + new File(outputDir).mkdirs(); + + // 使用完整的转换参数 + List<String> command = Arrays.asList( + "/usr/bin/libreoffice", // 使用完整路径 + "--headless", + "--norestore", + "--convert-to", + "pdf:writer_pdf_Export:PDFExport{" + + "EmbedStandardFonts=1;" + + "EmbedFonts=1;" + + "EmbedOnlyUsedFonts=0;" + + "UseTaggedPDF=1" + + "}", + "--outdir", + outputDir, + inputFile + ); + + // 创建进程构建器 + ProcessBuilder pb = new ProcessBuilder(command); + + // 设置环境变量 + Map<String, String> env = pb.environment(); + env.put("LC_ALL", "zh_CN.UTF-8"); + env.put("LANG", "zh_CN.UTF-8"); + env.put("LANGUAGE", "zh_CN.UTF-8"); + + // 重定向错误流到标准输出 + pb.redirectErrorStream(true); + + // 启动进程 + Process process = pb.start(); + + // 读取输出 + StringBuilder output = new StringBuilder(); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + output.append(line).append("\n"); + System.out.println(line); } } - 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(".")) ); + // 等待进程完成,设置超时 + if (!process.waitFor(120, TimeUnit.SECONDS)) { + process.destroyForcibly(); + throw new RuntimeException("转换超时"); + } + + int exitCode = process.exitValue(); + if (exitCode != 0) { + throw new RuntimeException("转换失败,退出码:" + exitCode + "\n输出:" + output); + } + + // 检查生成的PDF文件 + String pdfFileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf"; + File pdfFile = new File(outputDir, pdfFileName); + + if (!pdfFile.exists() || pdfFile.length() == 0) { + throw new RuntimeException("PDF文件未生成或为空"); + } + String absolutePath = pdfFile.getAbsolutePath(); + + MultipartFile multipartFile = convertFileToMultipartFile(pdfFile); String s = tencentCosUtil.upLoadFile(multipartFile,"/wordToPdf"); - - stream.close(); - inputStream.close(); return s; + } catch (Exception e) { - e.printStackTrace(); + throw new RuntimeException("PDF转换失败: " + e.getMessage(), e); } - return null; } + public MultipartFile convertFileToMultipartFile(File file) throws IOException { + // 读取文件内容到字节数组 + byte[] fileContent = Files.readAllBytes(file.toPath()); + // 创建 MultipartFile 对象 + MultipartFile multipartFile = new MockMultipartFile( + file.getName(), // 文件名 + file.getName(), // 原始文件名 + "application/pdf", // 内容类型,根据实际情况调整 + fileContent // 文件内容 + ); + + return multipartFile; + } + + // 在使用前检查和配置环境 + public static void setupEnvironment() { + try { + // 1. 检查LibreOffice安装 + checkLibreOffice(); + + // 2. 检查和安装字体 + installFonts(); + + // 3. 配置字体 + configureFonts(); + + // 4. 验证环境变量 + checkEnvironment(); + + } catch (Exception e) { + throw new RuntimeException("环境设置失败: " + e.getMessage(), e); + } + } + + private static void checkLibreOffice() throws IOException, InterruptedException { + Process process = Runtime.getRuntime().exec("which libreoffice"); + if (process.waitFor() != 0) { + throw new RuntimeException("LibreOffice未安装"); + } + } + + private static void installFonts() throws IOException, InterruptedException { + // 创建字体安装脚本 + String scriptContent = + "#!/bin/bash\n" + + "apt-get update\n" + + "apt-get install -y fonts-wqy-zenhei fonts-wqy-microhei fonts-arphic-ukai fonts-arphic-uming\n" + + "fc-cache -fv\n"; + + File script = new File("/tmp/install_fonts.sh"); + Files.write(script.toPath(), scriptContent.getBytes()); + script.setExecutable(true); + + // 执行脚本 + Process process = Runtime.getRuntime().exec("sudo /tmp/install_fonts.sh"); + process.waitFor(); + + // 清理脚本 + script.delete(); + } + + private static void configureFonts() throws IOException { + // 创建字体配置文件 + String fontConfig = + "<?xml version=\"1.0\"?>\n" + + "<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n" + + "<fontconfig>\n" + + " <match target=\"pattern\">\n" + + " <test name=\"family\"><string>serif</string></test>\n" + + " <edit name=\"family\" mode=\"prepend\">\n" + + " <string>WenQuanYi Zen Hei</string>\n" + + " </edit>\n" + + " </match>\n" + + " <match target=\"pattern\">\n" + + " <test name=\"family\"><string>sans-serif</string></test>\n" + + " <edit name=\"family\" mode=\"prepend\">\n" + + " <string>WenQuanYi Zen Hei</string>\n" + + " </edit>\n" + + " </match>\n" + + "</fontconfig>"; + + // 写入配置文件 + File configFile = new File(System.getProperty("user.home") + "/.fonts.conf"); + Files.write(configFile.toPath(), fontConfig.getBytes()); + } + + private static void checkEnvironment() { + // 检查环境变量 + String[] requiredVars = {"LANG", "LC_ALL", "LANGUAGE"}; + for (String var : requiredVars) { + String value = System.getenv(var); + if (value == null || !value.contains("zh_CN")) { + System.err.println("警告: " + var + " 环境变量未正确设置"); + } + } + } public static MultipartFile convertToMultipartFile(ByteArrayOutputStream baos, String fileName) throws IOException { // 创建一个临时文件 @@ -209,12 +392,12 @@ } public String test(String fileName){ - String url = "file:///E:\\"+fileName; +// String url = "file:///usr/local/project/file/"+fileName; // String filePath = "E:\\qiyeweixin\\WXWork\\1688855207501340\\Cache\\File\\2024-09"; // String fileName = "专业技术工作总结.docx";4 - String filePath = "E:\\"; + String filePath = "/usr/local/project/file/"; - String s = wordToPdf(url, filePath, fileName); + String s = wordToPdf(filePath, fileName); System.err.println(s); return s; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordPdfGenerator.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordPdfGenerator.java new file mode 100644 index 0000000..990e621 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordPdfGenerator.java @@ -0,0 +1,106 @@ +//package com.ruoyi.web.controller.tool; +// +//import org.apache.poi.xwpf.usermodel.*; +//import java.io.*; +//import java.time.LocalDateTime; +//import java.time.format.DateTimeFormatter; +// +//public class WordPdfGenerator { +// +// // 示例数据类 +// public static class UserData { +// private String name; +// private String id; +// private String department; +// private LocalDateTime createTime; +// +// public UserData(String name, String id, String department) { +// this.name = name; +// this.id = id; +// this.department = department; +// this.createTime = LocalDateTime.now(); +// } +// +// // getter方法省略 +// } +// +// public static void generateDocument(UserData userData, String outputPath) { +// try (XWPFDocument document = new XWPFDocument()) { +// // 创建标题 +// XWPFParagraph title = document.createParagraph(); +// title.setAlignment(ParagraphAlignment.CENTER); +// XWPFRun titleRun = title.createRun(); +// titleRun.setText("用户信息表"); +// titleRun.setBold(true); +// titleRun.setFontSize(20); +// titleRun.setFontFamily("宋体"); +// +// // 添加空行 +// document.createParagraph(); +// +// // 创建表格 +// XWPFTable table = document.createTable(5, 2); +// table.setWidth("100%"); +// +// // 设置表格数据 +// setCellText(table, 0, "姓名", userData.name); +// setCellText(table, 1, "ID", userData.id); +// setCellText(table, 2, "部门", userData.department); +// setCellText(table, 3, "创建时间", +// userData.createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); +// +// // 保存Word文档 +// String wordFile = outputPath + ".docx"; +// try (FileOutputStream out = new FileOutputStream(wordFile)) { +// document.write(out); +// } +// +// // 转换为PDF +// convertToPdf(wordFile, outputPath + ".pdf"); +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// private static void setCellText(XWPFTable table, int row, String label, String value) { +// XWPFTableRow tableRow = table.getRow(row); +// tableRow.getCell(0).setText(label); +// tableRow.getCell(1).setText(value); +// } +// +// private static void convertToPdf(String wordPath, String pdfPath) { +// try { +// // 使用LibreOffice进行转换 +// ProcessBuilder pb = new ProcessBuilder( +// "soffice", +// "--headless", +// "--convert-to", "pdf", +// "--outdir", new File(pdfPath).getParent(), +// wordPath +// ); +// Process process = pb.start(); +// +// // 等待转换完成 +// int exitCode = process.waitFor(); +// if (exitCode == 0) { +// System.out.println("PDF转换成功!"); +// } else { +// System.out.println("PDF转换失败!"); +// } +// +// // 删除临时Word文件 +// new File(wordPath).delete(); +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// public static void main(String[] args) { +// // 示例使用 +// UserData userData = new UserData("张三", "EMP001", "技术部"); +// String outputPath = "E:\\"; +// generateDocument(userData, outputPath); +// } +//} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java new file mode 100644 index 0000000..6b32fe3 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordTemplateProcessor.java @@ -0,0 +1,87 @@ +package com.ruoyi.web.controller.tool; + +import org.apache.poi.xwpf.usermodel.*; +import java.io.*; +import java.util.*; + +public class WordTemplateProcessor { + + public static void fillTemplate(String templatePath, String outputPath,Map<String, String> dataMap) { + try { + // 读取模板文件 + FileInputStream fis = new FileInputStream(templatePath); + XWPFDocument document = new XWPFDocument(fis); + + // 替换段落中的标记 + for (XWPFParagraph paragraph : document.getParagraphs()) { + replaceParagraph(paragraph, dataMap); + } + + // 替换表格中的标记 + for (XWPFTable table : document.getTables()) { + for (XWPFTableRow row : table.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + for (XWPFParagraph paragraph : cell.getParagraphs()) { + replaceParagraph(paragraph, dataMap); + } + } + } + } + + // 保存文件 + FileOutputStream fos = new FileOutputStream(outputPath); + document.write(fos); + + // 关闭资源 + fos.close(); + fis.close(); + document.close(); + + System.out.println("模板填充完成!文件保存在: " + outputPath); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void replaceParagraph(XWPFParagraph paragraph, Map<String, String> dataMap) { + String paragraphText = paragraph.getText(); + for (Map.Entry<String, String> entry : dataMap.entrySet()) { + if (paragraphText.contains(entry.getKey())) { + List<XWPFRun> runs = paragraph.getRuns(); + TextSegment found = paragraph.searchText(entry.getKey(), new PositionInParagraph()); + if (found != null) { + // 替换文本 + int beginRun = found.getBeginRun(); + int endRun = found.getEndRun(); + + if (beginRun >= 0 && endRun >= 0) { + // 删除原有runs + for (int runPos = beginRun; runPos <= endRun; runPos++) { + paragraph.removeRun(runPos); + } + // 创建新run + XWPFRun newRun = paragraph.insertNewRun(beginRun); + newRun.setText(entry.getValue()); + // 复制原有格式 + if (runs.size() > 0 && runs.get(0) != null) { + XWPFRun styleRun = runs.get(0); + newRun.setFontFamily(styleRun.getFontFamily()); + newRun.setFontSize(styleRun.getFontSize()); + newRun.setBold(styleRun.isBold()); + newRun.setItalic(styleRun.isItalic()); + } + } + } + } + } + } + + public static void main(String[] args) { + + String templatePath = "/path/to/template.docx"; + String outputPath = "/path/to/output.docx"; + +// fillTemplate(templatePath, outputPath, user); + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java index ce14b96..60d821a 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/WordUtil.java @@ -6,6 +6,7 @@ import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.xwpf.usermodel.*; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -15,7 +16,9 @@ import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.Map; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Slf4j @Component @@ -110,35 +113,38 @@ } - public String generatePdf(String basePackagePath, String templateFileName, Object templateParam, String fileName, String saveDirectory) { + public String generatePdf(String basePackagePath, String templateFileName, Map<String,Object> templateParam, String fileName, String saveDirectory) { try { + + fillTemplate(basePackagePath+templateFileName, saveDirectory+fileName+".docx", templateParam); + // 创建 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(); - +// 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(); + String filePath = saveDirectory + File.separator + fileName + ".docx"; File file = new File(filePath); // 检查文件是否存在 @@ -152,16 +158,263 @@ fis.read(fileContent); } - String test = pdfUtils.test(encodedFileName + ".doc"); + String test = pdfUtils.test(fileName + ".docx"); // MultipartFile mockMultipartFile = new MockMultipartFile(encodedFileName+".doc", fileContent); // String s = ObsUploadUtil.obsUpload(mockMultipartFile); return test; - } catch (IOException | TemplateException e) { + } catch (IOException e) { log.error("生成pdf异常,异常原因:{}", e.getMessage(), e); throw new RuntimeException("生成pdf异常,异常原因:" + e.getMessage()); } } + public static void fillTemplate(String templatePath, String outputPath,Map<String, Object> dataMap) { + try (FileInputStream fis = new FileInputStream(templatePath)) { + // 设置默认编码为UTF-8 + System.setProperty("file.encoding", "UTF-8"); + + XWPFDocument document = new XWPFDocument(fis); + + // 处理段落 + for (XWPFParagraph paragraph : document.getParagraphs()) { + replaceParagraph(paragraph, dataMap); + } + + // 处理表格 + for (XWPFTable table : document.getTables()) { + for (XWPFTableRow row : table.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + for (XWPFParagraph paragraph : cell.getParagraphs()) { + replaceParagraph(paragraph, dataMap); + } + } + } + } + + // 使用UTF-8编码保存文件 + try (FileOutputStream fos = new FileOutputStream(outputPath)) { + document.write(fos); + } + + System.out.println("模板填充完成!文件保存在: " + outputPath); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static void replaceParagraph(XWPFParagraph paragraph, Map<String, Object> dataMap) { + // 获取段落中所有runs + List<XWPFRun> runs = paragraph.getRuns(); + if (runs == null || runs.isEmpty()) return; + + // 首先合并所有runs的文本,以便正确识别占位符 + StringBuilder fullText = new StringBuilder(); + for (XWPFRun run : runs) { + String text = run.getText(0); + if (text != null) { + fullText.append(text); + } + } + + String paragraphText = fullText.toString(); + + // 使用正则表达式查找所有占位符,包括括号内的 + Pattern pattern = Pattern.compile("\\$\\{[^}]+\\}|\\([^)]*\\$\\{[^}]+\\}[^)]*\\)"); + Matcher matcher = pattern.matcher(paragraphText); + + List<ReplacementInfo> replacements = new ArrayList<>(); + + // 收集所有需要替换的信息 + while (matcher.find()) { + String matched = matcher.group(); + int start = matcher.start(); + int end = matcher.end(); + + // 找出涉及到的runs + int startRun = -1; + int endRun = -1; + int currentPos = 0; + + for (int i = 0; i < runs.size(); i++) { + XWPFRun run = runs.get(i); + String runText = run.getText(0); + if (runText == null) continue; + + int runLength = runText.length(); + if (startRun == -1 && currentPos + runLength > start) { + startRun = i; + } + if (currentPos + runLength >= end) { + endRun = i; + break; + } + currentPos += runLength; + } + + if (startRun != -1 && endRun != -1) { + // 处理括号内的占位符 + String replacement = processPlaceholder(matched, dataMap); + replacements.add(new ReplacementInfo(startRun, endRun, matched, replacement)); + } + } + + // 从后向前替换,避免位置变化影响 + Collections.sort(replacements, (a, b) -> b.startRun - a.startRun); + + for (ReplacementInfo info : replacements) { + replaceRunRange(paragraph, info); + } + } + + private static String processPlaceholder(String text, Map<String, Object> dataMap) { + // 处理括号内的占位符 + Pattern placeholderPattern = Pattern.compile("\\$\\{([^}]+)\\}"); + Matcher matcher = placeholderPattern.matcher(text); + + StringBuffer result = new StringBuffer(); + while (matcher.find()) { + String placeholder = matcher.group(0); // 完整的占位符 + String key = matcher.group(1); // 占位符中的键 + String replacement = Objects.nonNull(dataMap.get("${" + key + "}"))?String.valueOf(dataMap.get("${" + key + "}")):""; + + if (replacement != null) { + // 如果在括号内,保留括号 + if (text.startsWith("(") && text.endsWith(")")) { + matcher.appendReplacement(result, replacement); + } else { + matcher.appendReplacement(result, Matcher.quoteReplacement(replacement)); + } + } + } + matcher.appendTail(result); + + return result.toString(); + } + + private static class ReplacementInfo { + int startRun; + int endRun; + String originalText; + String replacementText; + + ReplacementInfo(int startRun, int endRun, String originalText, String replacementText) { + this.startRun = startRun; + this.endRun = endRun; + this.originalText = originalText; + this.replacementText = replacementText; + } + } + + private static void replaceRunRange(XWPFParagraph paragraph, ReplacementInfo info) { + List<XWPFRun> runs = paragraph.getRuns(); + + // 保存第一个run的样式 + XWPFRun styleRun = runs.get(info.startRun); + RunStyle style = new RunStyle(styleRun); + + // 删除范围内的所有runs + for (int i = info.endRun; i >= info.startRun; i--) { + paragraph.removeRun(i); + } + + // 创建新的run并设置文本 + XWPFRun newRun = paragraph.insertNewRun(info.startRun); + newRun.setText(info.replacementText); + + // 应用样式 + style.applyStyle(newRun); + } + + // 用于保存和恢复运行样式的辅助类 + private static class RunStyle { + String fontFamily; + int fontSize; + boolean bold; + boolean italic; + String color; + UnderlinePatterns underline; + + RunStyle(XWPFRun run) { + this.fontFamily = run.getFontFamily(); + this.fontSize = run.getFontSize(); + this.bold = run.isBold(); + this.italic = run.isItalic(); + this.color = run.getColor(); + this.underline = run.getUnderline(); + } + + void applyStyle(XWPFRun run) { + if (fontFamily != null) { + run.setFontFamily(fontFamily); + run.setFontFamily(fontFamily, XWPFRun.FontCharRange.eastAsia); + } + if (fontSize != -1) { + run.setFontSize(fontSize); + } + run.setBold(bold); + run.setItalic(italic); + if (color != null) { + run.setColor(color); + } + if (underline != null) { + run.setUnderline(underline); + } + } + } + +// 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()); +// } +// } + diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml index e23f3d5..14887f4 100644 --- a/ruoyi-admin/src/main/resources/application-test.yml +++ b/ruoyi-admin/src/main/resources/application-test.yml @@ -17,7 +17,7 @@ # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 - port: 8080 + port: 8081 servlet: # 应用的访问路径 context-path: / diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java index fdc926c..989234b 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/IndexController.java @@ -14,12 +14,14 @@ import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.bo.ProcessTaskListBO; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TInvoiceDTO; import com.ruoyi.system.model.*; import com.ruoyi.system.query.*; import com.ruoyi.system.service.*; import com.ruoyi.system.vo.*; +import com.ruoyi.web.controller.tool.MyFileUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import jdk.nashorn.internal.parser.Token; @@ -27,9 +29,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; @@ -72,6 +78,13 @@ private ISysUserService sysUserService; @Autowired private TContractRentTypeService contractRentTypeService; + @Autowired + private StateProcessTemplateService processTemplateService; + + public static void main(String[] args) throws IOException { + File file = new File("D:\\wechatFiles\\WeChat Files\\wxid_25nztsudcon722\\FileStorage\\File\\2025-03\\2.mp3"); + MultipartFile multipartFile = MyFileUtil.fileToMultipartFile(file, "3333"); + } /** * 获取轮播图管理列表 */ @@ -109,6 +122,8 @@ return R.ok(myToDoVO); } + + @ApiOperation(value = "租户-当前在租房源") @PostMapping(value = "/tenant/myHouse") public R<List<MyHouseVO>> myHouse() { @@ -132,7 +147,7 @@ myToDoVO.setHouseAddress(tHouse.getHouseAddress()); myToDoVO.setMonthRent(contract.getMonthRent()); myToDoVO.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE, contract.getPayType())); - myToDoVO.setMonth(bill.getPayFeesTime() == null ? bill.getPayableFeesTime().getMonth() + "月" : bill.getPayFeesTime().getMonth() + "月"); + myToDoVO.setMonth(bill.getPayFeesTime() == null ? bill.getPayableFeesTime().getMonth().getValue() + "月" : bill.getPayFeesTime().getMonth().getValue() + "月"); myToDoVO.setHouseArea(tHouse.getHouseArea()); myToDoVO.setHouseType(tHouse.getHouseType()); myToDoVO.setEndTime(DateUtils.localDateTimeToStringYear(contract.getEndTime())); @@ -180,7 +195,7 @@ myToDoVO.setHouseAddress(tHouse.getHouseAddress()); myToDoVO.setMonthRent(contract.getMonthRent()); myToDoVO.setPayType(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE, contract.getPayType())); - myToDoVO.setMonth(bill.getPayFeesTime() == null ? bill.getPayableFeesTime().getMonth() + "月" : bill.getPayFeesTime().getMonth() + "月"); + myToDoVO.setMonth(bill.getPayFeesTime() == null ? bill.getPayableFeesTime().getMonth().getValue() + "月" : bill.getPayFeesTime().getMonth().getValue() + "月"); myToDoVO.setHouseArea(tHouse.getHouseArea()); myToDoVO.setHouseType(tHouse.getHouseType()); myToDoVO.setEndTime(DateUtils.localDateTimeToStringYear(contract.getEndTime())); @@ -211,16 +226,24 @@ @PostMapping(value = "/admin/myToDo") public R<MyToDoVO> adminMyToDo() { MyToDoVO myToDoVO = new MyToDoVO(); - LoginUserApplet loginUserApplet = tokenService.getLoginUserApplet(); - if (loginUserApplet != null) { - long examineCount = contractService.count(new LambdaQueryWrapper<TContract>() - .eq(TContract::getStatus, 2)); - myToDoVO.setExamineCount((int) examineCount); + LoginUser loginUser = tokenService.getLoginUser(); + if (loginUser != null) { +// long examineCount = contractService.count(new LambdaQueryWrapper<TContract>() +// .eq(TContract::getStatus, 2)); + ProcessTaskListBO processTaskListBO = new ProcessTaskListBO(); + PageInfo<ProcessTaskListVO> processTaskListVOPageInfo = processTemplateService.waitTaskPage(processTaskListBO); + myToDoVO.setExamineCount((int) processTaskListVOPageInfo.getTotal()); List<String> contractIds = billService.lambdaQuery().eq(TBill::getPayFeesStatus, 4).list() .stream().map(TBill::getContractId).collect(Collectors.toList()); - int overdueCount = contractService.lambdaQuery().in(TContract::getId, contractIds).list() - .stream().map(TContract::getTenantId).distinct().collect(Collectors.toList()).size(); - myToDoVO.setOverdueCount(overdueCount); + if(contractIds.isEmpty()){ + myToDoVO.setOverdueCount(0); + + }else{ + int overdueCount = contractService.lambdaQuery().in(TContract::getId, contractIds).list() + .stream().map(TContract::getTenantId).distinct().collect(Collectors.toList()).size(); + myToDoVO.setOverdueCount(overdueCount); + } + } else { myToDoVO.setExamineCount(0); myToDoVO.setOverdueCount(0); @@ -244,10 +267,11 @@ @GetMapping(value = "/getDetailById") public R<TCheckAcceptRecordVO> getDetailById(@RequestParam String id) { TCheckAcceptRecord checkAcceptRecord = checkAcceptRecordService.getById(id); - checkAcceptRecord.setCleanSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION, checkAcceptRecord.getCleanSituation())); - checkAcceptRecord.setOverallSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION, checkAcceptRecord.getOverallSituation())); - checkAcceptRecord.setDeviceSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION, checkAcceptRecord.getDeviceSituation())); - checkAcceptRecord.setFurnitureSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION, checkAcceptRecord.getFurnitureSituation())); +// checkAcceptRecord.setCleanSituation(checkAcceptRecord.getCleanSituation()); +// checkAcceptRecord.setOverallSituation(StringUtils.hasLength(checkAcceptRecord.getOverallSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getOverallSituation())):""); +// checkAcceptRecord.setDeviceSituation(StringUtils.hasLength(checkAcceptRecord.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getDeviceSituation())):""); +// checkAcceptRecord.setFurnitureSituation(StringUtils.hasLength(checkAcceptRecord.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,checkAcceptRecord.getFurnitureSituation())):""); + TCheckAcceptRecordVO checkAcceptRecordVO = new TCheckAcceptRecordVO(); BeanUtils.copyProperties(checkAcceptRecord, checkAcceptRecordVO); // 查询合同信息 @@ -269,6 +293,7 @@ dto.setCode(replace.substring(2)+String.format("%03d", size+1)); dto.setStatus(true); // 添加验收记录 + dto.setCheckPerson(tokenService.getLoginUser().getUser().getNickName()); checkAcceptRecordService.updateById(dto); return R.ok(); } @@ -350,6 +375,12 @@ TContract contract = contractService.getById(bill.getContractId()); THouse tHouse = houseService.getById(contract.getHouseId()); res.setHouse(tHouse); + res.setConcatStartTime(contract.getStartTime()); + res.setConcatEndTime(contract.getEndTime()); + res.setPartyOnePhone(contract.getPartyOnePhone()); + res.setPartyOnePerson(contract.getPartyTwoPerson()); + res.setMonthRent(bill.getPayableFeesMoney()); + res.setPayType(contract.getPayType()); return R.ok(res); } @ApiOperation(value = "管理员-我的审批分页列表") diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java index b6d843e..2ab98bb 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TBillController.java @@ -1,14 +1,17 @@ package com.ruoyi.web.controller.api; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.constant.DictConstants; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.CodeGenerateUtils; import com.ruoyi.common.utils.DictUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.dto.BatchBillDTO; import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.dto.TInvoiceDTO; import com.ruoyi.system.model.*; @@ -53,6 +56,8 @@ TInvoiceToBillService invoiceToBillService; @Autowired TokenService tokenService; + @Autowired + TTenantService tenantService; @ApiOperation(value = "缴费账单查询分页列表") @PostMapping("list") @@ -68,7 +73,6 @@ LocalDateTime localDateTime2 = LocalDateTime.now().withYear(2025).withMonth(11).withDayOfMonth(28); long allDays = ChronoUnit.DAYS.between(localDateTime1, localDateTime2); System.err.println(allDays); - } @ApiOperation(value = "缴费账单查询列表") @@ -78,6 +82,18 @@ query.setUserId(userId); List<String> billIds = tBillService.getBillIds(query); return R.ok(billIds); + } + + @ApiOperation(value = "跳转批量缴费") + @PostMapping("/batchBill") + public R<String> batchBill(@RequestBody BatchBillDTO dto){ + String userId = tokenService.getLoginUserApplet().getUserId(); + List<String> billIds = dto.getBillIds(); + Integer count = tBillService.batchBillCount(userId, billIds); + if(count>0){ + return R.fail("请优先缴纳水电费"); + } + return R.ok(); } @ApiOperation(value = "查看缴费账单详情") @@ -112,6 +128,13 @@ @ApiOperation(value = "缴费账单开票") @PostMapping(value = "/invoice") public R<String> invoice(@RequestBody TInvoiceDTO dto) { + String userId = tokenService.getLoginUserApplet().getUserId(); + dto.setApplyName(tenantService.getById(userId).getResidentName()); + String code; + do { + code = CodeGenerateUtils.generateVolumeSn(); + } while (invoiceService.count(Wrappers.lambdaQuery(TInvoice.class).eq(TInvoice::getInvoiceNumber, code)) > 0); + dto.setInvoiceNumber(CodeGenerateUtils.generateVolumeSn()); // 添加开票信息 invoiceService.save(dto); diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java index cc86304..d53226b 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TFaultRepairMessageController.java @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.SmsUtil; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.dto.TFaultRepairMessageDTO; import com.ruoyi.system.model.*; @@ -14,6 +16,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import java.time.LocalDate; @@ -41,9 +44,13 @@ private final TokenService tokenService; private final TContractService contractService; private final THouseService houseService; + private final SmsUtil smsUtil; + private final ISysUserService sysUserService; + @Autowired - public TFaultRepairMessageController(TFaultRepairMessageService tFaultRepairMessageService, TItemService itemService, TItemTypeService itemTypeService, TFaultAreaDicService faultAreaDicService, TFaultDescribeDicService faultDescribeDicService, TokenService tokenService, TContractService contractService, THouseService houseService) { + public TFaultRepairMessageController(TFaultRepairMessageService tFaultRepairMessageService, TItemService itemService, TItemTypeService itemTypeService, TFaultAreaDicService faultAreaDicService, TFaultDescribeDicService faultDescribeDicService, TokenService tokenService, TContractService contractService, THouseService houseService,SmsUtil smsUtil + ,ISysUserService sysUserService) { this.tFaultRepairMessageService = tFaultRepairMessageService; this.itemService = itemService; this.itemTypeService = itemTypeService; @@ -52,6 +59,8 @@ this.tokenService = tokenService; this.contractService = contractService; this.houseService = houseService; + this.smsUtil = smsUtil; + this.sysUserService = sysUserService; } /** @@ -63,7 +72,7 @@ List<TItemTypeVO> itemTypes = itemTypeService.getItemList(itemName); List<TItem> items = itemService.list(); itemTypes.forEach(itemType -> { - itemType.setItemList(items.stream().filter(item -> itemType.getId().equals(item.getTypeId())).collect(Collectors.toList())); + itemType.setItemList(items.stream().filter(item -> itemType.getId().equals(item.getTypeId()) && item.getItemName().contains(itemName)).collect(Collectors.toList())); }); return R.ok(itemTypes); } @@ -120,6 +129,15 @@ .likeRight(TFaultRepairMessage::getCreateTime, LocalDate.now())).size(); dto.setCode(replace.substring(2)+String.format("%03d", size+1)); tFaultRepairMessageService.save(dto); + List<SysUser> sysUsers = sysUserService.selectList(); + if (dto.getRepairType()==2){ + for (SysUser sysUser : sysUsers) { + if (StringUtils.hasLength(sysUser.getPhonenumber())){ + System.err.println("发送短信"); + smsUtil.sendSms(sysUser.getPhonenumber(),"2375194",new String[]{}); + } + } + } return R.ok(); } diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java index a46014a..72980d2 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TInformationController.java @@ -51,7 +51,9 @@ public R<TInformation> getDetailById(@RequestParam String id) { // 处理查看次数 redisCache.increment(Constants.INFORMATION_VIEW + id); - return R.ok(informationService.getById(id)); + TInformation information = informationService.getById(id); + information.setViewCount(redisCache.getCacheObject(Constants.INFORMATION_VIEW + information.getId())); + return R.ok(information); } } diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index c32e796..eda9119 100644 --- a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -9,6 +9,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.LoginUserApplet; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.SmsUtil; import com.ruoyi.framework.web.service.TokenService; @@ -101,16 +102,8 @@ { AjaxResult ajax = AjaxResult.success(); // 生成令牌 - LoginUser loginUser = loginService.loginCode(loginBody.getUsername(), loginBody.getCode()); - ajax.put(Constants.TOKEN, tokenService.createToken(loginUser)); - List<SysRole> roles = loginUser.getUser().getRoles(); - if(CollectionUtils.isEmpty(roles)){ - return AjaxResult.error("请关联角色!"); - } - List<SysMenu> menus = roleService.roleInfoFromUserId(loginUser.getUserId()); - - ajax.put("menus",menus); - ajax.put("roleName",roles.get(0).getRoleName()); + LoginUserApplet loginUser = loginService.loginCodeApplet(loginBody.getUsername(), loginBody.getCode()); + ajax.put(Constants.TOKEN, tokenService.createTokenApplet(loginUser)); ajax.put("userInfo",loginUser); return ajax; } diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/MyFileUtil.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/MyFileUtil.java new file mode 100644 index 0000000..40af28a --- /dev/null +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/tool/MyFileUtil.java @@ -0,0 +1,128 @@ +package com.ruoyi.web.controller.tool; + +import org.springframework.web.multipart.MultipartFile; +import java.io.*; +import java.nio.file.Files; + + +/** + * @author RainbowCloud + */ +public class MyFileUtil { + + /** + * 将 File 转换为 MultipartFile。 + * + * @param file 要转换的文件 + * @param fieldName 字段名,通常用于表单中的文件字段名 + * @return 转换后的 MultipartFile + * @throws IOException 如果发生I/O错误 + */ + public static MultipartFile fileToMultipartFile(File file, String fieldName) throws IOException { + try { + if (file == null || !file.exists()) { + throw new FileNotFoundException("文件未找到:" + file); + } + byte[] content = Files.readAllBytes(file.toPath()); + return new ByteArrayMultipartFile(content, file.getName(), fieldName, Files.probeContentType(file.toPath())); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + // 删除临时文件 + file.delete(); + } + } + + /** + * 将 MultipartFile 转换为 File。 + * + * @param multipartFile 要转换的 MultipartFile + * @return 转换后的 File + * @throws IOException 如果发生I/O错误 + */ + public static File multipartFileToFile(MultipartFile multipartFile) throws IOException { + if (multipartFile.isEmpty()) { + throw new IOException("传入的MultipartFile为空"); + } + String originalFilename = multipartFile.getOriginalFilename(); + String tempFileSuffix = originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf('.')) : ".tmp"; + File tempFile = File.createTempFile("temp", tempFileSuffix); + try (InputStream ins = multipartFile.getInputStream(); + OutputStream os = new FileOutputStream(tempFile)) { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = ins.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + } + return tempFile; + } + + /** + * 内置一个简单的 MultipartFile 实现类,用于File转换 + */ + private static class ByteArrayMultipartFile implements MultipartFile { + private final byte[] content; + private final String name; + private final String originalFilename; + private final String contentType; + + /** + * 构造函数 + * + * @param content 文件内容 + * @param originalFilename 文件原始名字 + * @param name 字段名 + * @param contentType 文件类型 + */ + public ByteArrayMultipartFile(byte[] content, String originalFilename, String name, String contentType) { + this.content = content; + this.originalFilename = originalFilename; + this.name = name; + this.contentType = contentType; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getOriginalFilename() { + return this.originalFilename; + } + + @Override + public String getContentType() { + return this.contentType; + } + + @Override + public boolean isEmpty() { + return (this.content == null || this.content.length == 0); + } + + @Override + public long getSize() { + return this.content.length; + } + + @Override + public byte[] getBytes() { + return this.content; + } + + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(this.content); + } + + @Override + public void transferTo(File dest) throws IOException, IllegalStateException { + try (OutputStream os = new FileOutputStream(dest)) { + os.write(this.content); + } + } + } + +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java index 9c5491e..95169c0 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/DictConstants.java @@ -28,7 +28,7 @@ */ public static final String DICT_TYPE_BUSINESS_ATTRIBUTES = "t_business_attributes"; /** - * 合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算 + * 合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算 9合同已签订待审 */ public static final String DICT_TYPE_CONTRACT_STATUS = "t_contract_status"; /** diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java index eb27892..76492bc 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CodeGenerateUtils.java @@ -3,6 +3,8 @@ import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.Date; +import java.util.concurrent.atomic.AtomicInteger; /** * @Description @@ -67,7 +69,7 @@ dateTime = dateTime.substring(2); String timestampPart = "" + (Math.random() * 10000) * (System.currentTimeMillis() / 10000); timestampPart = timestampPart.replace(".", "").replace("E", ""); - timestampPart = timestampPart.substring(0, 5); + timestampPart = timestampPart.substring(0, 0); return dateTime + timestampPart; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index eadb4d3..e54ccc2 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -2,8 +2,14 @@ import javax.annotation.Resource; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.core.domain.entity.TTenantResp; +import com.ruoyi.common.core.domain.model.LoginUserApplet; import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.system.model.TTenant; +import com.ruoyi.system.service.TTenantService; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -52,6 +58,8 @@ @Autowired private ISysUserService userService; + @Autowired + private TTenantService tenantService; @Autowired private ISysConfigService configService; @@ -127,8 +135,6 @@ */ public LoginUser loginCode(String username,String code) { - - // 登录前置校验 if (StringUtils.isEmpty(username)){ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); @@ -163,6 +169,43 @@ return loginUser; } + /** + * 登录验证 + * + * @param username 用户名 + * @param code 验证码 + * @return 结果 + */ + public LoginUserApplet loginCodeApplet(String username, String code) + { + // 登录前置校验 + if (StringUtils.isEmpty(username)){ + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); + throw new UserNotExistsException(); + } + // 用户验证 + TTenant user = tenantService.getOne(Wrappers.<TTenant>lambdaQuery().eq(TTenant::getAccount,username)); + if (StringUtils.isNull(user)){ + log.info("登录用户:{} 不存在.", username); + throw new ServiceException(MessageUtils.message("user.not.exists")); + } else if (user.getDisabled()) { + log.info("登录用户:{} 已被删除.", username); + throw new ServiceException(MessageUtils.message("user.password.delete")); + } + // 校验验证码 + Object cacheObject = redisCache.getCacheObject(user.getAccount()); + if(!code.equals(String.valueOf(cacheObject))){ + log.info("登录用户:{} 短信验证码错误{}", username,code); + throw new ServiceException("短信验证码错误"); + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + TTenantResp tTenantResp = new TTenantResp(); + BeanUtils.copyProperties(user,tTenantResp); + LoginUserApplet loginUser = new LoginUserApplet(user.getId(), null, tTenantResp, null); + // 生成token + return loginUser; + } + /** * 校验验证码 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java new file mode 100644 index 0000000..4910ba6 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/BatchBillDTO.java @@ -0,0 +1,18 @@ +package com.ruoyi.system.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +@ApiModel(value = "批量缴费校验") +public class BatchBillDTO implements Serializable { + + @ApiModelProperty(value = "账单id集合") + private List<String> billIds; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java index 2ad934f..357d516 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java @@ -44,4 +44,6 @@ BigDecimal statisticsPayed(); BigDecimal statisticsOverdue(); + + Integer batchBillCount(@Param("userId")String userId, @Param("billIds")List<String> billIds); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java index 42b77b4..cee2df3 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBill.java @@ -1,18 +1,16 @@ package com.ruoyi.system.model; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.*; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; -import com.baomidou.mybatisplus.annotation.TableField; import java.io.Serializable; import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.ruoyi.common.core.domain.BaseModel; import com.ruoyi.common.core.domain.BasePage; import io.swagger.annotations.ApiModel; @@ -34,10 +32,43 @@ @EqualsAndHashCode(callSuper = false) @TableName("t_bill") @ApiModel(value="TBill对象", description="租金账单") -public class TBill extends BaseModel { +public class TBill implements Serializable { private static final long serialVersionUID = 1L; + /** + * 新增执行 + */ + @ApiModelProperty(value = "记录创建人,前端忽略") + @JsonIgnore + @TableField(value = "create_by", fill = FieldFill.INSERT) + private String createBy; + /** + * 新增和更新执行 + */ + @ApiModelProperty(value = "记录修改人,前端忽略") + @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE) + private String updateBy; + /** + * 删除 未删除 + */ + @JsonIgnore + @TableField("`disabled`") + @TableLogic + private Boolean disabled; + + @ApiModelProperty(value = "记录创建时间,前端忽略") + @TableField("create_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime createTime; + + /** + * 最后修改时间 + */ + @ApiModelProperty(value = "记录修改时间,前端忽略") + @TableField("update_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime updateTime; @TableId(value = "id", type = IdType.ASSIGN_ID) private String id; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java index c2c2834..14257ff 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TContract.java @@ -146,7 +146,7 @@ * 7 待结算 * 8 已结算 */ - @ApiModelProperty(value = "合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算") + @ApiModelProperty(value = "合同状态 1=待提交 2=待审批 3=未签订 4=已签订 5=已驳回 6=已终止 7=待结算 8=已结算 9 = 签订待审核") @TableField("status") private String status; @ApiModelProperty(value = "内存大小多个文件逗号拼接") @@ -172,6 +172,6 @@ private String houseAddress; @ApiModelProperty(value = "审批流实例id") @TableField(exist = false) - private Long instanceId; + private String instanceId; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java index e5a60cd..1d66290 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java @@ -22,6 +22,11 @@ */ @ApiModelProperty("租户ID") private String userId; + /** + * 账单类型 + */ + @ApiModelProperty("账单类型 1=租金 2=押金 3=生活费用 4=房屋验收") + private Integer billType; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java index 19b7f69..0015ee5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java @@ -85,4 +85,6 @@ Boolean cashPay(CachPayDto offlinePayDto); BillStatisticsDto statistics(); + + Integer batchBillCount(String userId, List<String> billIds); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java index 4926b6d..96320ad 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/FlowListenerService.java @@ -30,15 +30,22 @@ import com.ruoyi.common.enums.ProcessCategoryEnum; import com.ruoyi.common.enums.SubmitStatusEnum; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.system.service.ISysRoleService; -import com.ruoyi.system.service.TContractService; +import com.ruoyi.system.mapper.TCheckAcceptRecordMapper; +import com.ruoyi.system.model.*; +import com.ruoyi.system.service.*; import com.ruoyi.system.task.base.QuartzManager; import com.ruoyi.system.task.base.TimeJobType; import com.ruoyi.system.task.jobs.StateProcessJob; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -68,8 +75,20 @@ private final ISysRoleService sysRoleService; private final FlwTaskMapper flwTaskMapper; private final TContractService contractService; + private final TContractRentTypeService contractRentTypeService; + private final TBillService billService; + private final TCheckAcceptRecordMapper checkAcceptRecordMapper; + private final THouseService houseService; + public static void main(String[] args) { +// LocalDate localDate1 = LocalDate.now().withYear(2025).withMonth(4).withDayOfMonth(1); +// LocalDate localDate2 = LocalDate.now().withYear(2025).withMonth(4).withDayOfMonth(16); + LocalDateTime localDate1 = LocalDateTime.now().withYear(2025).withMonth(4).withDayOfMonth(16); + LocalDateTime localDate2 = LocalDateTime.now().withYear(2025).withMonth(10).withDayOfMonth(24); + long between = ChronoUnit.DAYS.between(localDate1, localDate2)+1; + System.err.println(between); + } @Override public boolean notify(EventType eventType, Supplier<FlwTask> supplier, NodeModel nodeModel, FlowCreator flowCreator) { FlwTask flwTask = supplier.get(); @@ -101,7 +120,7 @@ new ImmutableMap.Builder<String, Long>(). put("id", flwTask.getId()) .build(); - QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name+flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT,new Date(new Date().getTime()+48*60*60*1000L), maps); + QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name + flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT, new Date(new Date().getTime() + 48 * 60 * 60 * 1000L), maps); //对比发起人和节点审批人 @@ -124,9 +143,9 @@ List<String> roleIds = nodeAssigneeList.stream().map(NodeAssignee::getId).collect(Collectors.toList()); List<SysRole> actorList = sysRoleService.selectRoleByUserIds(roleIds); List<FlwTaskActor> flwTaskActors = new ArrayList<>(); - if(ObjectUtils.isNotEmpty(actorList)) { + if (ObjectUtils.isNotEmpty(actorList)) { for (SysRole sysRole : actorList) { - if(ObjectUtil.isEmpty(sysRole.getRoleName())) { + if (ObjectUtil.isEmpty(sysRole.getRoleName())) { continue; } NodeAssignee nodeAssignee = new NodeAssignee(); @@ -152,7 +171,7 @@ new ImmutableMap.Builder<String, Long>(). put("id", flwTask.getId()) .build(); - QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name+flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT,new Date(new Date().getTime()+48*60*60*1000L), maps); + QuartzManager.addJob(StateProcessJob.class, (StateProcessJob.name + flwTask.getId()).toUpperCase(), TimeJobType.AUTO_AUDIT, new Date(new Date().getTime() + 48 * 60 * 60 * 1000L), maps); //对比发起人和节点审批人 @@ -185,8 +204,8 @@ log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId()); return true; } - long count = flwTaskMapper.selectCount(new LambdaQueryWrapper<FlwTask>().eq(FlwTask::getInstanceId,flwTask.getInstanceId())); - if(count > 0){ + long count = flwTaskMapper.selectCount(new LambdaQueryWrapper<FlwTask>().eq(FlwTask::getInstanceId, flwTask.getInstanceId())); + if (count > 0) { return true; } //最后一个节点 @@ -209,7 +228,7 @@ System.out.println("流程完成:" + flwTask.getVariable()); handlerBusiness(flwTask.getVariable(), 1); } - } else if(eventType.eq(EventType.autoJump)){ + } else if (eventType.eq(EventType.autoJump)) { // 查询流程模型 自动跳转 FlwExtInstance flwExtInstance = flwExtInstanceMapper.selectById(flwTask.getInstanceId()); String modelContent = flwExtInstance.getModelContent(); @@ -219,8 +238,8 @@ log.error("节点不存在 TaskName:{} InstanceId:{}", flwTask.getTaskName(), flwTask.getInstanceId()); return true; } - long count = flwTaskMapper.selectCount(new LambdaQueryWrapper<FlwTask>().eq(FlwTask::getInstanceId,flwTask.getInstanceId())); - if(count > 0){ + long count = flwTaskMapper.selectCount(new LambdaQueryWrapper<FlwTask>().eq(FlwTask::getInstanceId, flwTask.getInstanceId())); + if (count > 0) { return true; } //最后一个节点 @@ -244,21 +263,435 @@ switch (categoryEnum) { case CATEGORY1: { // 合同新增审批 - int submitStatus = status==0?2:(status==1?3:5); + int submitStatus = status == 0 ? 2 : (status == 1 ? 3 : 1); contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus); // TODO 发短信 break; } case CATEGORY2: { // 合同签订审批 - int submitStatus = status==0?3:(status==1?4:5); + int submitStatus = status == 0 ? 3 : (status == 1 ? 4 : 1); contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus); + TContract contract = contractService.getById(processParameter.getString("projectId")); + if(contract.getStatus().equals("4")){ + + // 修改房屋状态 + THouse house = houseService.getById(contract.getHouseId()); + if(Objects.nonNull(house)){ + house.setLeaseStatus("2"); + houseService.updateById(house); + } + List<TContractRentType> contractRentTypes = contractRentTypeService.list(); + TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); + + // 生成第一笔账单 + // 第一次应缴费日期 + LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0); + TBill rentBill = new TBill(); + rentBill.setContractId(contract.getId()); + rentBill.setContractNumber(contract.getContractNumber()); + rentBill.setPayableFeesTime(firstPayTime.toLocalDate()); + rentBill.setPayFeesStatus("1"); + + rentBill.setBillType("1"); + rentBill.setStartTime(contract.getStartPayTime()); + if (rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth()).isAfter(contract.getEndTime())) { + if (rentBill.getStartTime().getDayOfMonth() != 1) { + rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())); + } else { + rentBill.setEndTime(rentBill.getStartTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth())); + } + } else { + rentBill.setEndTime(rentBill.getStartTime().with(TemporalAdjusters.lastDayOfMonth())); + } + if (tContractRentType != null && rentBill.getEndTime().isAfter(tContractRentType.getChangeTime())) { + long moneyDays = 0; + moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), rentBill.getEndTime())+1; + // 计算租金变动的天数 + contract.setChangeTime(tContractRentType.getChangeTime()); + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()) { + case 1: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + // 变动后的每月租金 + contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = Math.abs(ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime())); + originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); + } else { + // 不走递增递减 + long allDays = ChronoUnit.DAYS.between(contract.getStartPayTime(), rentBill.getEndTime())+1; + int dayOfMonth = rentBill.getStartTime().getDayOfMonth(); + if (dayOfMonth == 1) { + rentBill.setPayableFeesMoney(contract.getMonthRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); + } else { + rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); + } + rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); + } + // 押金账单 + TBill depositBill = new TBill(); + depositBill.setContractId(contract.getId()); + depositBill.setContractNumber(contract.getContractNumber()); + depositBill.setPayableFeesMoney(contract.getDeposit()); + depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney()); + depositBill.setStartTime(contract.getStartPayTime()); + depositBill.setEndTime(contract.getEndTime()); + depositBill.setPayableFeesTime(firstPayTime.toLocalDate()); + + depositBill.setPayFeesStatus("1"); + + + depositBill.setBillType("2"); + contractService.updateById(contract); + billService.save(rentBill); + billService.save(depositBill); + // 生成后续账单 + try { + TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime) + .last("limit 1").one(); + if (!beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) { + while (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).isBefore(contract.getEndTime())) { + System.err.println("生成后续账单"); + TBill tBill = new TBill(); + tBill.setContractId(contract.getId()); + tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); + tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth())); + tBill.setContractNumber(contract.getContractNumber()); + if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).getDayOfMonth() <= 15) { + tBill.setPayableFeesTime(contract.getEndTime().toLocalDate()); + } else { + tBill.setPayableFeesTime(beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15).toLocalDate()); + } + tBill.setContractId(contract.getId()); + if (contract.getIsIncreasing()) { + System.err.println("执行递增递减"); + if (tContractRentType != null) { + // 如果变过 并且时间在递增递减时间段内 + if (contract.getChangeTime() != null) { + // 下次递增递减时间 + LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime()); + // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 + if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) { + contract.setChangeTime(changeTime); + // 租金递增递减的时长 天 + long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1; + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()) { + case 1: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + // 变动后的每月租金 + contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime()); + if (originalDays > 0) { + originalMoney = originalMoney.add(contract.getChangeRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + } + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + contractService.updateById(contract); + } else { + // 不涨租金 用上次的 + tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1")?1:contract.getPayType().equals("2")?3:12))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + }else{ + if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) { + System.err.println("首次递增递减"); + contract.setChangeTime(tContractRentType.getChangeTime()); + // 租金递增递减的时长 天 + long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1; + // 递增递减的租金 + + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()) { + case 1: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + // 变动后的每月租金 + contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime()); + System.err.println("不需要长租金时长"+originalDays); + if (originalDays > 0) { + originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + } + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + contractService.updateById(contract); + }else{ + tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + } + } else { + tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + }else { + System.err.println("不执行递增递减"); + tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + tBill.setContractNumber(contract.getContractNumber()); + tBill.setPayFeesStatus("1"); + tBill.setBillType("1"); + + billService.save(tBill); + beforeBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12).with(TemporalAdjusters.lastDayOfMonth())); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime) + .last("limit 1").one(); + // 生成最后一笔账单 + if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) + && beforeBill.getEndTime().isBefore(contract.getEndTime()) + ) { + TBill tBill = new TBill(); + tBill.setContractId(contract.getId()); + tBill.setPayFeesStatus("1"); + tBill.setBillType("1"); + tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); + tBill.setEndTime(contract.getEndTime()); + tBill.setContractNumber(contract.getContractNumber()); + if (contract.getIsIncreasing()) { + if (tContractRentType != null) { + // 如果变过 并且时间在递增递减时间段内 + if (contract.getChangeTime() != null) { + // 下次递增递减时间 + LocalDateTime changeTime = contract.getChangeTime().plusYears(tContractRentType.getCycleTime()); + // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 + if (changeTime.isBefore(tBill.getEndTime()) && changeTime.isAfter(tBill.getStartTime())) { + contract.setChangeTime(changeTime); + // 租金递增递减的时长 天 + long moneyDays = Math.abs(ChronoUnit.DAYS.between(changeTime, tBill.getEndTime()))+1; + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()) { + case 1: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + // 变动后的每月租金 + contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), changeTime); + if (originalDays > 0) { + originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)); + } + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + contractService.updateById(contract); + } else { + long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); + tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + }else{ + if (tContractRentType.getChangeTime().isBefore(tBill.getEndTime()) && tContractRentType.getChangeTime().isAfter(tBill.getStartTime())) { + contract.setChangeTime(tContractRentType.getChangeTime()); + // 租金递增递减的时长 天 + long moneyDays = Math.abs(ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), tBill.getEndTime()))+1; + // 递增递减的租金 + BigDecimal contractRentTypeMoney = new BigDecimal("0"); + // 不递增递减的租金 + BigDecimal originalMoney = new BigDecimal("0"); + // 原租金 + switch (tContractRentType.getIncreasingDecreasingType()) { + case 1: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + // 变动后的每月租金 + contract.setChangeRent(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN)); + contract.setChangeRent(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)); + break; + } + break; + case 2: + switch (tContractRentType.getIncreasingDecreasing()) { + case 1: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().add(tContractRentType.getNumericalValue())); + break; + case 2: + contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).setScale(2, BigDecimal.ROUND_DOWN); + contract.setChangeRent(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())); + break; + } + break; + } + // 不需要涨租金的时间段 + long originalDays = ChronoUnit.DAYS.between(tBill.getStartTime(), tContractRentType.getChangeTime()); + if (originalDays > 0) { + originalMoney = originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) + .multiply(new BigDecimal(originalDays)).setScale(2,BigDecimal.ROUND_DOWN); + } + tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + contractService.updateById(contract); + + } + } + } else { + if (tBill.getStartTime().getDayOfMonth()==1 && tBill.getEndTime().toLocalDate().equals(tBill.getEndTime().with(TemporalAdjusters.lastDayOfMonth()).toLocalDate())){ + tBill.setPayableFeesMoney(contract.getChangeRent().multiply(new BigDecimal(contract.getPayType().equals("1") ? 1 : contract.getPayType().equals("2") ? 3 : 12))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + }else{ + // 最后一笔账单时间 + long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); + tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + } + }else{ + long finalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); + tBill.setPayableFeesMoney(contract.getChangeRent().divide(new BigDecimal("30"),2,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(finalDays))); + tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); + } + if (tBill.getEndTime().getDayOfMonth()>=15){ + tBill.setPayableFeesTime(tBill.getStartTime().withDayOfMonth(15).toLocalDate()); + }else if (tBill.getStartTime().getYear()==tBill.getEndTime().getYear()&& tBill.getStartTime().getMonthValue()==tBill.getEndTime().getMonthValue()){ + // 如果同年同月 且日小于15 缴费时间取合同 + tBill.setPayableFeesTime(tBill.getStartTime().toLocalDate()); + }else{ + tBill.setPayableFeesTime(tBill.getStartTime().withDayOfMonth(15).toLocalDate()); + } + billService.save(tBill); + } + } break; } case CATEGORY3: { // 合同提前终止审批 - int submitStatus = status==0?4:(status==1?6:5); + int submitStatus = status == 0 ? 4 : (status == 1 ? 7 : 5); contractService.updateContractAuditStatus(processParameter.getString("projectId"), submitStatus); + // 生成验收记录 + TContract contract = contractService.getById(processParameter.getString("projectId")); + TCheckAcceptRecord tCheckAcceptRecord = new TCheckAcceptRecord(); + tCheckAcceptRecord.setContractId(contract.getId()); + tCheckAcceptRecord.setHouseId(contract.getHouseId()); + tCheckAcceptRecord.setLeaseReason("后台终止合同"); + tCheckAcceptRecord.setAcceptanceTime(LocalDateTime.now()); + LocalDate now = LocalDate.now(); + String replace = (now + "").replace("-", ""); + int size = checkAcceptRecordMapper.selectList(new LambdaQueryWrapper<TCheckAcceptRecord>() + .likeRight(TCheckAcceptRecord::getAcceptanceTime, LocalDate.now())).size(); + tCheckAcceptRecord.setCode(replace.substring(2) + String.format("%03d", size + 1)); + + checkAcceptRecordMapper.insert(tCheckAcceptRecord); + break; } default: diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java index cbefcad..14e744d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/StateProcessTemplateServiceImpl.java @@ -1281,7 +1281,7 @@ // 查询历史任务 List<FlwHisTask> flwHisTasks = flwHisTaskMapper.selectList(Wrappers.<FlwHisTask>lambdaQuery().eq(FlwHisTask::getInstanceId, instanceId)); - + processDetailVO.setInstanceId(String.valueOf(instanceId)); processDetailVO.setFlwHisTasks(flwHisTasks); List<StateProcessInstanceAction> list = stateProcessInstanceActionService.list(Wrappers.<StateProcessInstanceAction>lambdaQuery().eq(StateProcessInstanceAction::getInstanceId, instanceId) @@ -1365,6 +1365,7 @@ sysUserMap = new HashMap<>(); } for (ProcessTaskListVO processTaskListVO : processTaskListVOS) { + processTaskListVO.setStatus(processTaskListVO.getTaskState() == 10 ? "2" : processTaskListVO.getTaskState().toString()); processTaskListVO.setTaskId(processTaskListVO.getId()); SysUser sysUser = sysUserMap.get(processTaskListVO.getCreateBy()); if (Objects.nonNull(sysUser)) { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java index b3911bb..0376220 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java @@ -547,5 +547,10 @@ return dto; } + @Override + public Integer batchBillCount(String userId, List<String> billIds) { + return this.baseMapper.batchBillCount(userId,billIds); + } + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java index d84a843..7006063 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TCheckAcceptRecordServiceImpl.java @@ -17,6 +17,7 @@ import com.ruoyi.system.vo.TCheckAcceptRecordVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import java.util.List; @@ -39,12 +40,11 @@ public PageInfo<TCheckAcceptRecordVO> pageList(TCheckAcceptRecordQuery query) { PageInfo<TCheckAcceptRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TCheckAcceptRecordVO> list = this.baseMapper.pageList(query,pageInfo); - list.forEach(item -> { - item.setCleanSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getCleanSituation())); - item.setOverallSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getOverallSituation())); - item.setDeviceSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getDeviceSituation())); - item.setFurnitureSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getFurnitureSituation())); + item.setCleanSituation(StringUtils.hasLength(item.getCleanSituation()) ?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getCleanSituation())):""); + item.setOverallSituation(StringUtils.hasLength(item.getOverallSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getOverallSituation())):""); + item.setDeviceSituation(StringUtils.hasLength(item.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getDeviceSituation())):""); + item.setFurnitureSituation(StringUtils.hasLength(item.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getFurnitureSituation())):""); }); pageInfo.setRecords(list); @@ -58,10 +58,10 @@ PageInfo<TCheckAcceptRecordVO> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); List<TCheckAcceptRecordVO> list = this.baseMapper.pageListApplet(query,pageInfo); list.forEach(item -> { - item.setCleanSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getCleanSituation())); - item.setOverallSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getOverallSituation())); - item.setDeviceSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getDeviceSituation())); - item.setFurnitureSituation(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getFurnitureSituation())); + item.setCleanSituation(StringUtils.hasLength(item.getCleanSituation()) ?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getCleanSituation())):""); + item.setOverallSituation(StringUtils.hasLength(item.getOverallSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getOverallSituation())):""); + item.setDeviceSituation(StringUtils.hasLength(item.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getDeviceSituation())):""); + item.setFurnitureSituation(StringUtils.hasLength(item.getDeviceSituation())?(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CHECK_SITUATION,item.getFurnitureSituation())):""); item.setContract(tContracts.stream().filter(contract -> contract.getId().equals(item.getContractId())).findFirst().orElse(null)); item.setHouse(tHouses.stream().filter(house -> house.getId().equals(item.getHouseId())).findFirst().orElse(null)); }); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java index 63040be..30368c2 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TContractServiceImpl.java @@ -73,6 +73,12 @@ 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())); + FlwHisTask flwHisTask = flwHisTaskMapper.selectOne(new LambdaQueryWrapper<FlwHisTask>() + .like(FlwHisTask::getVariable, tContract.getId()) + .last("LIMIT 1")); + if (Objects.nonNull(flwHisTask)){ + tContract.setInstanceId(Objects.nonNull(flwHisTask.getInstanceId())?String.valueOf(flwHisTask.getInstanceId()):""); + } } pageInfo.setRecords(list); return pageInfo; @@ -90,7 +96,7 @@ .like(FlwHisTask::getVariable, tContract.getId()) .last("LIMIT 1")); if (Objects.nonNull(flwHisTask)){ - tContract.setInstanceId(flwHisTask.getInstanceId()); + tContract.setInstanceId(Objects.nonNull(flwHisTask.getInstanceId())?String.valueOf(flwHisTask.getInstanceId()):""); } } pageInfo.setRecords(list); @@ -114,9 +120,7 @@ public void terminateContract(TerminateContractDTO dto) { TContract contract = this.baseMapper.selectById(dto.getId()); contract.setTerminateRemark(dto.getTerminateRemark()); - contract.setStatus("4"); this.baseMapper.updateById(contract); - // 进入合同提前终止审批流程 ProcessStartBO processStartBO = new ProcessStartBO(); processStartBO.setCategory(ProcessCategoryEnum.CATEGORY3.getValue().toString()); @@ -128,38 +132,11 @@ processStartBO.setVariable(variable); //开启工作流程 stateProcessTemplateService.start(processStartBO); - - // 生成验收记录 - TCheckAcceptRecord tCheckAcceptRecord = new TCheckAcceptRecord(); - tCheckAcceptRecord.setContractId(dto.getId()); - tCheckAcceptRecord.setHouseId(contract.getHouseId()); - tCheckAcceptRecord.setLeaseReason("后台终止合同"); - tCheckAcceptRecord.setStatus(false); - tCheckAcceptRecord.setAcceptanceTime(LocalDateTime.now()); - LocalDate now = LocalDate.now(); - String replace = (now + "").replace("-", ""); - int size = checkAcceptRecordMapper.selectList(new LambdaQueryWrapper<TCheckAcceptRecord>() - .likeRight(TCheckAcceptRecord::getAcceptanceTime, LocalDate.now())).size(); - tCheckAcceptRecord.setCode(replace.substring(2)+String.format("%03d", size+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); } public static void main(String[] args) { -// LocalDate now = LocalDate.now(); -// String replace = (now + "").replace("-", ""); -// System.err.println(replace.substring(2)); -// -// System.err.println(String.format("%03d",1)); + String t = "1000438"; + System.err.println("XN" + String.valueOf(t).substring(1)); } @Override public CheckAcceptRecordVO getCheckByContractId(String id) { @@ -182,8 +159,8 @@ if (contract==null)return R.fail("合同不存在"); if (contract.getStatus().equals("4"))return R.fail("该合同已签订"); contract.setSignature(dto.getSignature()); - contract.setStatus("4"); contract.setFirstPayTime(contract.getStartTime().plusDays(10)); + contract.setStatus("9"); contractMapper.updateById(contract); // 进入签订审批流程 @@ -198,462 +175,7 @@ //开启工作流程 stateProcessTemplateService.startApplet(processStartBO); - List<TContractRentType> contractRentTypes = contractRentTypeService.list(); - // 生成第一笔账单 - // 第一次应缴费日期 - LocalDateTime firstPayTime = contract.getStartTime().plusDays(10).withHour(0).withMinute(0).withSecond(0); - TBill rentBill = new TBill(); - rentBill.setContractId(contract.getId()); - rentBill.setContractNumber(contract.getContractNumber()); - rentBill.setPayableFeesTime(firstPayTime.toLocalDate()); - rentBill.setPayFeesStatus("1"); - rentBill.setBillType("1"); - rentBill.setStartTime(contract.getStartPayTime()); - TContractRentType tContractRentType = contractRentTypes.stream().filter(e -> e.getContractId().equals(contract.getId())).findFirst().orElse(null); - if (tContractRentType!=null && contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(tContractRentType.getChangeTime())){ - // 计算租金变动的天数 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getStartPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12))+1L; - contract.setChangeTime(LocalDateTime.now()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); - contract.setChangeRent(contractRentTypeMoney); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(contract.getFirstPayTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - rentBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); - if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ - rentBill.setEndTime(contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12)); - }else{ - rentBill.setEndTime(contract.getEndTime()); - } - }else{ - if (contract.getFirstPayTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isAfter(contract.getEndTime())){ - rentBill.setEndTime(contract.getEndTime()); - - }else{ - LocalDateTime firstPayTime1 = contract.getFirstPayTime(); - // 将firstPayTime1的日设置为当月最后一天 - rentBill.setEndTime(firstPayTime1.with(TemporalAdjusters.lastDayOfMonth())); - } - // 不走递增递减 - long allDays = ChronoUnit.DAYS.between(contract.getStartPayTime().minusDays(1), rentBill.getEndTime()); - rentBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); - rentBill.setOutstandingMoney(rentBill.getPayableFeesMoney()); - - } - // 押金账单 - TBill depositBill = new TBill(); - depositBill.setContractId(contract.getId()); - depositBill.setContractNumber(contract.getContractNumber()); - depositBill.setPayableFeesMoney(contract.getDeposit()); - depositBill.setOutstandingMoney(depositBill.getPayableFeesMoney()); - depositBill.setStartTime(contract.getStartPayTime()); - depositBill.setEndTime(contract.getEndTime()); - depositBill.setPayableFeesTime(firstPayTime.toLocalDate()); - - depositBill.setPayFeesStatus("1"); - - - depositBill.setBillType("2"); - this.updateById(contract); - billService.save(rentBill); - billService.save(depositBill); - // 生成后续账单 - try { - TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getCreateTime) - .last("limit 1").one(); - if (!beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())){ - - - while(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).isBefore(contract.getEndTime())){ - TBill tBill = new TBill(); - tBill.setContractId(contract.getId()); - tBill.setContractNumber(contract.getContractNumber()); - // 根据支付方式判断需不需要生成订单 - if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) - && - (contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1):contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3):beforeBill.getEndTime().plusMonths(12)) - .with(TemporalAdjusters.lastDayOfMonth()).isBefore(contract.getEndTime()) - && beforeBill.getEndTime().isBefore(contract.getEndTime()) - ){ - tBill.setContractId(contract.getId()); - if (contract.getIsIncreasing()){ - if (tContractRentType!=null - && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) - && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ - // 如果没变过 - if (contract.getChangeTime()==null){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); - contract.setChangeRent(contractRentTypeMoney); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - - }else{ - // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 - if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); - contract.setChangeRent(contractRentTypeMoney); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - - }else{ - // 不涨租金 用上次的 - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); - contract.setChangeRent(contractRentTypeMoney); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - - } - } - - } - }else{ - - tBill.setPayableFeesMoney(contract.getMonthRent()); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - - } - tBill.setContractNumber(contract.getContractNumber()); - if (beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).getDayOfMonth()<=15){ - tBill.setPayableFeesTime(contract.getEndTime().toLocalDate()); - }else{ - tBill.setPayableFeesTime((contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15).toLocalDate():contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15).toLocalDate():beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).toLocalDate())); - } - tBill.setPayFeesStatus("1"); - tBill.setBillType("1"); - tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); - tBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth())); - billMapper.insert(tBill); - } - beforeBill.setEndTime(beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth())); - } - } - - } catch (Exception e) { - e.printStackTrace(); - } - TBill beforeBill = billService.lambdaQuery().eq(TBill::getContractId, contract.getId()).eq(TBill::getBillType, 1).orderByDesc(TBill::getStartTime) - .last("limit 1").one(); - // 生成最后一笔账单 - if (!(beforeBill.getEndTime().toLocalDate().equals(contract.getEndTime().toLocalDate())) - && beforeBill.getEndTime().isBefore(contract.getEndTime()) - ){ - TBill tBill = new TBill(); - tBill.setContractId(contract.getId()); - - if (contract.getIsIncreasing()){ - if (tContractRentType!=null - && beforeBill.getEndTime().isBefore(tContractRentType.getChangeTime()) - && beforeBill.getEndTime().plusMonths(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12).with(TemporalAdjusters.lastDayOfMonth()).isAfter(tContractRentType.getChangeTime())){ - // 如果没变过 - if (contract.getChangeTime()==null){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); - contract.setChangeRent(contractRentTypeMoney); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - - // 不需要涨租金的时间段 - if (contract.getFirstPayTime().isBefore(tContractRentType.getChangeTime())){ - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - }else{ - tBill.setPayableFeesMoney(contractRentTypeMoney); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - } - - }else{ - // 之前已经涨、跌过租金了 需要判断周期是否还需要再涨、跌 - if ((LocalDateTime.now().getYear() - contract.getChangeTime().getYear())%tContractRentType.getCycleTime()==0){ - contract.setChangeTime(LocalDateTime.now()); - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); - contract.setChangeRent(contractRentTypeMoney); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - - }else{ - // 不涨租金 用上次的 - // 租金递增递减的时长 天 - long moneyDays = ChronoUnit.DAYS.between(tContractRentType.getChangeTime(), contract.getEndTime()); - // 递增递减的租金 - BigDecimal contractRentTypeMoney = new BigDecimal("0"); - // 不递增递减的租金 - BigDecimal originalMoney = new BigDecimal("0"); - // 原租金 - switch (tContractRentType.getIncreasingDecreasingType()){ - case 1: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().multiply(new BigDecimal(100).add(tContractRentType.getNumericalValue())).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays))); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().multiply((new BigDecimal(100).subtract(tContractRentType.getNumericalValue()))).divide(new BigDecimal(100),2,BigDecimal.ROUND_DOWN).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)).divide(new BigDecimal(contract.getPayType().equals("1")? 1:contract.getPayType().equals("2")? 3:12),2,BigDecimal.ROUND_DOWN)); - contract.setChangeRent(contractRentTypeMoney); - break; - } - break; - case 2: - switch (tContractRentType.getIncreasingDecreasing()){ - case 1: - contractRentTypeMoney =contractRentTypeMoney.add(contract.getChangeRent().add(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - break; - case 2: - contractRentTypeMoney = contractRentTypeMoney.add(contract.getChangeRent().subtract(tContractRentType.getNumericalValue())).divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(moneyDays)); - contract.setChangeRent(contractRentTypeMoney); - - break; - } - break; - } - // 不需要涨租金的时间段 - long originalDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), tContractRentType.getChangeTime()); - originalMoney=originalMoney.add(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN)) - .multiply(new BigDecimal(originalDays)); - tBill.setPayableFeesMoney(contractRentTypeMoney.add(originalMoney)); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - - } - } - - } - }else{ - long allDays = ChronoUnit.DAYS.between(beforeBill.getEndTime(), contract.getEndTime()); - tBill.setPayableFeesMoney(contract.getMonthRent().divide(new BigDecimal(30), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(allDays))); - tBill.setOutstandingMoney(tBill.getPayableFeesMoney()); - - } - tBill.setContractNumber(contract.getContractNumber()); - if (contract.getEndTime().getDayOfMonth()<=15){ - tBill.setPayableFeesTime(contract.getEndTime().withHour(0).withMinute(0).withSecond(0).toLocalDate()); - }else{ - tBill.setPayableFeesTime((contract.getPayType().equals("1")? - beforeBill.getEndTime().plusMonths(1).withDayOfMonth(15).toLocalDate():contract.getPayType().equals("2")? - beforeBill.getEndTime().plusMonths(3).withDayOfMonth(15).toLocalDate():beforeBill.getEndTime().withDayOfMonth(15).plusMonths(12).withHour(0).withMinute(0).withSecond(0).toLocalDate())); - } - tBill.setPayFeesStatus("1"); - tBill.setBillType("1"); - tBill.setStartTime(beforeBill.getEndTime().plusDays(1)); - tBill.setEndTime(contract.getEndTime()); - billService.save(tBill); - } return R.ok(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java index 9aa06f9..259962e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/THouseServiceImpl.java @@ -41,12 +41,16 @@ .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(DictUtils.getDictLabel(DictConstants.DICT_TYPE_CONTRACT_PAY_TYPE,tContract.getPayType())); +// tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,"2")); + }else{ +// tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus())); } + tHouse.setLeaseStatus(DictUtils.getDictLabel(DictConstants.DICT_TYPE_LEASE_STATUS,tHouse.getLeaseStatus())); + } pageInfo.setRecords(list); return pageInfo; @@ -58,6 +62,7 @@ List<HouseVO> list = this.baseMapper.userHistoryList(query,pageInfo); for (HouseVO houseVO : list) { houseVO.setTenantAttributes(StringUtils.isNotEmpty(houseVO.getTenantAttributes())?DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_ATTRIBUTE,houseVO.getTenantAttributes()):""); + houseVO.setProductType(StringUtils.isNotEmpty(houseVO.getTenantType())?DictUtils.getDictLabel(DictConstants.DICT_TYPE_TENANT_TYPE,houseVO.getTenantType()):""); } pageInfo.setRecords(list); return pageInfo; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/task/jobs/StateProcessJob.java b/ruoyi-system/src/main/java/com/ruoyi/system/task/jobs/StateProcessJob.java index 73e2ab2..0f2d909 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/task/jobs/StateProcessJob.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/task/jobs/StateProcessJob.java @@ -40,7 +40,7 @@ stateProcessTemplateService.agree(processAgreeBO); // 短信发送 SysUser sysUser = sysUserService.selectUserById(Long.valueOf(flwTaskActor.getActorId())); - smsUtil.sendSms(sysUser.getPhonenumber(), "2369951", new String[]{""}); + smsUtil.sendSms(sysUser.getPhonenumber(), "2369951", new String[]{}); }catch(Exception e){ e.printStackTrace(); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java b/ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java new file mode 100644 index 0000000..9766aa8 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/task/utils/TaskUtil.java @@ -0,0 +1,92 @@ +package com.ruoyi.system.task.utils; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.system.mapper.TBillMapper; +import com.ruoyi.system.model.TBill; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.service.TContractService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.ChronoUnit; +import java.util.List; + +/** + * @author zhibing.pu + * @date 2023/7/11 8:39 + */ +@Component +public class TaskUtil { + @Autowired + private TContractService contractService; + @Autowired + private TBillMapper billMapper; + // 用于更新违约金账单 + // 每分钟执行一次的定时任务 + + @Scheduled(cron = "0 0 0 * * ?") +// @Scheduled(cron = "0 * * * * ?") + public void dayOfProportionBill() { + try { + // 查询所有未缴费账单 + List<TBill> list = billMapper.selectList(new LambdaQueryWrapper<TBill>().eq(TBill::getPayFeesStatus, 1) + .le(TBill::getPayableFeesTime,LocalDate.now())); + for (TBill tBill : list) { + tBill.setPayFeesStatus("4"); + TContract contract = contractService.getById(tBill.getContractId()); + LocalDate payableFeesTime = tBill.getPayableFeesTime(); + // 将LocalDate转化为LocalDateTime + LocalDateTime payableFeesTime1 = LocalDateTime.of(payableFeesTime, LocalTime.of(0, 0, 0)); + LocalDateTime now = LocalDateTime.now(); + // 计算两个时间相差多少个小时 + long hours = ChronoUnit.HOURS.between(payableFeesTime1, now); + long l = hours / 24; + if (l>=3){ + // 违约金比例 + BigDecimal proportion = contract.getProportion(); + // 按每天 待缴费金额 * XX% 增加违约金费用 + if (tBill.getOutstandingMoney().compareTo(new BigDecimal("0"))==0){ + tBill.setPayFeesStatus("3"); + billMapper.updateById(tBill); + continue; + } + BigDecimal money = tBill.getOutstandingMoney().multiply(new BigDecimal(100).add(proportion)).divide(new BigDecimal(100),2, BigDecimal.ROUND_DOWN); + tBill.setOverDays((int) l); + BigDecimal bigDecimal = tBill.getOutstandingMoney().multiply(proportion).setScale(2, BigDecimal.ROUND_DOWN); + tBill.setPayableFeesPenalty(tBill.getPayableFeesPenalty()!=null?tBill.getPayableFeesPenalty():new BigDecimal("0").add(bigDecimal)); + tBill.setOutstandingMoney(money); + billMapper.updateById(tBill); + + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + +// LocalDateTime now = LocalDateTime.now().minusMonths(1).withDayOfMonth(31); +// System.err.println(now); +// LocalDateTime now2 = now.plusMonths(1); +// System.err.println(now2); +// +// LocalDateTime now1 = LocalDateTime.now(); +// long days = ChronoUnit.DAYS.between(now, now1); +// long days2 = ChronoUnit.DAYS.between(now.plusDays(1), now1); +// +// System.err.println(days); +// System.err.println(days2); +// LocalDateTime endTime = now.with(TemporalAdjusters.lastDayOfMonth()).withSecond(59).withHour(23).withMinute(59); +// +// System.err.println(endTime); + + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseVO.java index 4e74bbb..a12cadc 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/HouseVO.java @@ -30,6 +30,8 @@ private String tenantAttributes; @ApiModelProperty(value = "类型") private String productType; + @ApiModelProperty(value = "类型") + private String tenantType; @ApiModelProperty(value = "入住日期") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private LocalDateTime startTime; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessTaskListVO.java b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessTaskListVO.java index cada03f..097518b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessTaskListVO.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/vo/ProcessTaskListVO.java @@ -36,6 +36,7 @@ private Date createTime; private String status; + private Integer taskState; private String taskId; @@ -148,4 +149,8 @@ @ApiModelProperty(value = "合计年租金") private BigDecimal totalYear; + @ApiModelProperty(value = "合同时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime contractTime; + } diff --git a/ruoyi-system/src/main/resources/mapper/system/StateTaskCenterMapper.xml b/ruoyi-system/src/main/resources/mapper/system/StateTaskCenterMapper.xml index 6d4fd63..de92a68 100644 --- a/ruoyi-system/src/main/resources/mapper/system/StateTaskCenterMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/StateTaskCenterMapper.xml @@ -23,7 +23,7 @@ tc.id AS contractId, tc.contract_number, tc.contract_name, tc.start_time, tc.end_time,tc.deposit, tc.pay_type, tc.first_pay_time, tc.isIncreasing,tc.isIncreasing_deposit,tc.proportion, tc.house_id, tc.party_one_name, tc.party_one_person, tc.party_one_phone, tc.tenant_id, tc.party_two_name,tc.party_two_person, tc.party_two_phone,tc.memory, tc.contract_file_name, - tc.signature, tc.terminate_remark, tc.total_year,tc.status AS contractStatus + tc.signature, tc.terminate_remark, tc.total_year,tc.status AS contractStatus,tc.create_time AS contractTime from state_task_center stc LEFT JOIN t_contract tc ON stc.project_id = tc.id <where> diff --git a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml index 5415d26..81d281c 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml @@ -93,6 +93,9 @@ <if test="query.userId != null and query.userId !=''"> and t.id = #{query.userId} </if> + <if test="query.billType != null"> + and b.bill_type = #{query.billType} + </if> and b.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} </where> order by b.bill_type,b.payable_fees_time @@ -162,4 +165,25 @@ <select id="statisticsOverdue" resultType="java.math.BigDecimal"> SELECT ifnull(sum(outstanding_money),0) as amount FROM t_bill where pay_fees_status=4 </select> + <select id="batchBillCount" resultType="java.lang.Integer"> + SELECT + count(b.id) + FROM + t_bill b + LEFT JOIN t_contract c ON c.contract_number = b.contract_number and c.disabled=0 + LEFT JOIN t_house h ON h.id = c.house_id and h.disabled=0 + LEFT JOIN t_tenant t ON t.id = c.tenant_id and t.disabled=0 + <where> + <if test="userId != null and userId !=''"> + AND t.id = #{userId} + </if> + <if test="billIds != null and billIds.size() > 0"> + AND b.id NOT IN + <foreach collection="billIds" item="item" index="index" open="(" separator="," close=")"> + #{item} + </foreach> + </if> + AND b.bill_type = 3 + </where> + </select> </mapper> diff --git a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml index d1b8b4b..f0f1693 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TCheckAcceptRecordMapper.xml @@ -90,8 +90,11 @@ left join t_house h on t.house_id = h.id <where> - <if test="query.status != null"> - AND t.status = #{query.status} + <if test="query.status != null and query.status != '' and query.status == 1"> + AND t.status = 0 + </if> + <if test="query.status != null and query.status != '' and query.status == 2"> + AND t.status = 1 </if> <if test="query.houseNameOrAddress != null and query.houseNameOrAddress != ''"> AND (h.house_name LIKE concat('%', #{query.houseNameOrAddress}, '%') or h.house_address LIKE concat('%', #{query.houseNameOrAddress}, '%')) diff --git a/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml index 217157a..ba2c3f1 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TFaultRepairMessageMapper.xml @@ -61,6 +61,7 @@ t.attachment, t.attachment_name, t.status, + t.code, t.create_time, t.update_time, t.create_by, @@ -103,6 +104,7 @@ t.create_by, t.update_by, t.disabled, + t.code, i.item_name AS itemName, it.type_name AS itemTypeName, tnt.resident_name AS residentName @@ -158,6 +160,7 @@ t.create_by, t.update_by, t.disabled, + t.code, i.item_name AS itemName, it.type_name AS itemTypeName, tnt.resident_name AS residentName diff --git a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml index 0eefc41..d5450f9 100644 --- a/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/THouseMapper.xml @@ -29,8 +29,16 @@ id, house_picture, house_name, house_address, house_area, house_type, business_attributes, product_type, property_right_person, property_right_number, property_right_start_time, property_right_duration, lease_status, create_time, update_time, create_by, update_by, disabled </sql> <select id="houseList" resultType="com.ruoyi.system.model.THouse"> - select t1.* from - t_house t1 + select t1.*,t2.start_time as startTime + from t_house t1 + left join t_contract t2 + on (t2.house_id = t1.id + and t2.status != 1 + and t2.status != 2 + and t2.status != 3 + and t2.status != 5 + and t2.status != 8 + and NOW() between t2.start_time and t2.end_time) <where> <if test="req.houseName != null and req.houseName != ''"> and t1.house_name like concat('%', #{req.houseName}, '%') @@ -38,8 +46,14 @@ <if test="req.propertyRightPerson != null and req.propertyRightPerson != ''"> and t1.property_right_person like concat('%', #{req.propertyRightPerson}, '%') </if> - <if test="req.leaseStatus != null"> + <if test="req.leaseStatus == 3"> and t1.lease_status = #{req.leaseStatus} + </if> + <if test="req.leaseStatus == 2"> + and (t2.start_time is not null) + </if> + <if test="req.leaseStatus == 1"> + and (t2.start_time is null) and t1.lease_status = 1 </if> AND t1.disabled = ${@com.ruoyi.common.enums.DisabledEnum@NO.getCode()} </where> @@ -56,6 +70,7 @@ t3.room_number as roomNumber, t3.house_area as houseArea, t2.phone as loginAccount, + t2.tenant_type as tenantType, t2.id as tenantId, t2.id_card as idCard, t2.bank_number as bankNumber, -- Gitblit v1.7.1