Merge remote-tracking branch 'origin/master' into xizang-changyun
| | |
| | | @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")){ |
| | | //发起合同新增审批 |
| | |
| | | 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); |
| | | } |
| | |
| | | @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())); |
| | |
| | | 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(); |
| | | } |
| | |
| | | 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); |
| | |
| | | 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); |
| | |
| | | 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") |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | /** |
| | | * 获取部门管理管理列表 |
| | | */ |
| | | @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))); |
| | | } |
| | | |
| | | /** |
| | | * 添加部门管理管理 |
| | |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | @ApiOperation(value = "修改故障描述") |
| | | @PostMapping(value = "/update") |
| | | public R<Boolean> update(@Validated @RequestBody TFaultDescribeDic dto) { |
| | | dto.setUpdateTime(LocalDateTime.now()); |
| | | return R.ok(faultDescribeDicService.updateById(dto)); |
| | | } |
| | | |
| | |
| | | public R<Boolean> deleteByIds(@RequestBody List<String> ids) { |
| | | return R.ok(faultDescribeDicService.removeByIds(ids)); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | |
| | | @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() + "'失败,登录账号已存在"); |
| | |
| | | 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(); |
| | | // } |
| | | // } |
| | | // |
| | | // |
| | | //} |
| | |
| | | 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; |
| | |
| | | |
| | | 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 |
| | |
| | | /** |
| | | * 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 { |
| | | // 创建一个临时文件 |
| | |
| | | } |
| | | |
| | | 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; |
New file |
| | |
| | | //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); |
| | | // } |
| | | //} |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | 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 |
| | |
| | | } |
| | | |
| | | |
| | | 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); |
| | | |
| | | // 检查文件是否存在 |
| | |
| | | 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()); |
| | | // } |
| | | // } |
| | | |
| | | |
| | | |
| | | |
| | |
| | | # 开发环境配置 |
| | | server: |
| | | # 服务器的HTTP端口,默认为8080 |
| | | port: 8080 |
| | | port: 8081 |
| | | servlet: |
| | | # 应用的访问路径 |
| | | context-path: / |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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"); |
| | | } |
| | | /** |
| | | * 获取轮播图管理列表 |
| | | */ |
| | |
| | | return R.ok(myToDoVO); |
| | | } |
| | | |
| | | |
| | | |
| | | @ApiOperation(value = "租户-当前在租房源") |
| | | @PostMapping(value = "/tenant/myHouse") |
| | | public R<List<MyHouseVO>> myHouse() { |
| | |
| | | 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())); |
| | |
| | | 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())); |
| | |
| | | @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); |
| | |
| | | @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); |
| | | // 查询合同信息 |
| | |
| | | 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(); |
| | | } |
| | |
| | | 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 = "管理员-我的审批分页列表") |
| | |
| | | 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.*; |
| | |
| | | TInvoiceToBillService invoiceToBillService; |
| | | @Autowired |
| | | TokenService tokenService; |
| | | @Autowired |
| | | TTenantService tenantService; |
| | | |
| | | @ApiOperation(value = "缴费账单查询分页列表") |
| | | @PostMapping("list") |
| | |
| | | LocalDateTime localDateTime2 = LocalDateTime.now().withYear(2025).withMonth(11).withDayOfMonth(28); |
| | | long allDays = ChronoUnit.DAYS.between(localDateTime1, localDateTime2); |
| | | System.err.println(allDays); |
| | | |
| | | } |
| | | |
| | | @ApiOperation(value = "缴费账单查询列表") |
| | |
| | | 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 = "查看缴费账单详情") |
| | |
| | | @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); |
| | | |
| | |
| | | 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.*; |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | this.tokenService = tokenService; |
| | | this.contractService = contractService; |
| | | this.houseService = houseService; |
| | | this.smsUtil = smsUtil; |
| | | this.sysUserService = sysUserService; |
| | | } |
| | | |
| | | /** |
| | |
| | | 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); |
| | | } |
| | |
| | | .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(); |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | { |
| | | 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; |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | */ |
| | | 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"; |
| | | /** |
| | |
| | | import java.math.BigDecimal; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | import java.util.concurrent.atomic.AtomicInteger; |
| | | |
| | | /** |
| | | * @Description |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | |
| | | 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; |
| | |
| | | |
| | | @Autowired |
| | | private ISysUserService userService; |
| | | @Autowired |
| | | private TTenantService tenantService; |
| | | |
| | | @Autowired |
| | | private ISysConfigService configService; |
| | |
| | | */ |
| | | public LoginUser loginCode(String username,String code) |
| | | { |
| | | |
| | | |
| | | // 登录前置校验 |
| | | if (StringUtils.isEmpty(username)){ |
| | | AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); |
| | |
| | | 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; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 校验验证码 |
New file |
| | |
| | | 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; |
| | | |
| | | |
| | | } |
| | |
| | | BigDecimal statisticsPayed(); |
| | | |
| | | BigDecimal statisticsOverdue(); |
| | | |
| | | Integer batchBillCount(@Param("userId")String userId, @Param("billIds")List<String> billIds); |
| | | } |
| | |
| | | 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; |
| | |
| | | @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; |
| | | |
| | |
| | | * 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 = "内存大小多个文件逗号拼接") |
| | |
| | | private String houseAddress; |
| | | @ApiModelProperty(value = "审批流实例id") |
| | | @TableField(exist = false) |
| | | private Long instanceId; |
| | | private String instanceId; |
| | | |
| | | } |
| | |
| | | */ |
| | | @ApiModelProperty("租户ID") |
| | | private String userId; |
| | | /** |
| | | * 账单类型 |
| | | */ |
| | | @ApiModelProperty("账单类型 1=租金 2=押金 3=生活费用 4=房屋验收") |
| | | private Integer billType; |
| | | |
| | | |
| | | |
| | |
| | | Boolean cashPay(CachPayDto offlinePayDto); |
| | | |
| | | BillStatisticsDto statistics(); |
| | | |
| | | Integer batchBillCount(String userId, List<String> billIds); |
| | | } |
| | |
| | | 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; |
| | |
| | | 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(); |
| | |
| | | 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); |
| | | |
| | | |
| | | //对比发起人和节点审批人 |
| | |
| | | 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(); |
| | |
| | | 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); |
| | | |
| | | |
| | | //对比发起人和节点审批人 |
| | |
| | | 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; |
| | | } |
| | | //最后一个节点 |
| | |
| | | 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(); |
| | |
| | | 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; |
| | | } |
| | | //最后一个节点 |
| | |
| | | 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: |
| | |
| | | |
| | | // 查询历史任务 |
| | | 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) |
| | |
| | | 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)) { |
| | |
| | | return dto; |
| | | } |
| | | |
| | | @Override |
| | | public Integer batchBillCount(String userId, List<String> billIds) { |
| | | return this.baseMapper.batchBillCount(userId,billIds); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | 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; |
| | | |
| | |
| | | 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); |
| | |
| | | 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)); |
| | | }); |
| | |
| | | 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; |
| | |
| | | .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); |
| | |
| | | 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()); |
| | |
| | | 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) { |
| | |
| | | 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); |
| | | |
| | | // 进入签订审批流程 |
| | |
| | | //开启工作流程 |
| | | 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(); |
| | | } |
| | |
| | | .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; |
| | |
| | | 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; |
| | |
| | | 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(); |
| | | } |
New file |
| | |
| | | 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); |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | private Date createTime; |
| | | |
| | | private String status; |
| | | private Integer taskState; |
| | | |
| | | private String taskId; |
| | | |
| | |
| | | @ApiModelProperty(value = "合计年租金") |
| | | private BigDecimal totalYear; |
| | | |
| | | @ApiModelProperty(value = "合同时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime contractTime; |
| | | |
| | | } |
| | |
| | | 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> |
| | |
| | | <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 |
| | |
| | | <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> |
| | |
| | | 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}, '%')) |
| | |
| | | t.attachment, |
| | | t.attachment_name, |
| | | t.status, |
| | | t.code, |
| | | t.create_time, |
| | | t.update_time, |
| | | t.create_by, |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | 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}, '%') |
| | |
| | | <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> |
| | |
| | | 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, |